From e6748afd82356a2128c1bbd4b5510fcd16b1575e Mon Sep 17 00:00:00 2001 From: Markus Scherer Date: Fri, 14 Jul 2017 22:38:40 +0000 Subject: [PATCH] ICU-13197 improved normalization data structure and code; .nrm formatVersion 3; merged from branches/markus/normv3 except for cherry-picks from trunk to there X-SVN-Rev: 40265 --- icu4c/source/common/filterednormalizer2.cpp | 48 + icu4c/source/common/loadednormalizer2impl.cpp | 4 +- icu4c/source/common/norm2_nfc_data.h | 1736 ++++++++-------- icu4c/source/common/norm2allmodes.h | 15 +- icu4c/source/common/normalizer2.cpp | 11 +- icu4c/source/common/normalizer2impl.cpp | 1773 +++++++++-------- icu4c/source/common/normalizer2impl.h | 299 ++- icu4c/source/common/ucasemap.cpp | 2 +- icu4c/source/common/unicode/normalizer2.h | 62 +- icu4c/source/common/unicode/stringoptions.h | 1 + icu4c/source/common/ustr_imp.h | 5 + icu4c/source/common/ustrcase.cpp | 2 +- icu4c/source/common/utrie2.cpp | 4 +- icu4c/source/data/in/nfc.nrm | Bin 35260 -> 35384 bytes icu4c/source/data/in/nfkc.nrm | Bin 54160 -> 54300 bytes icu4c/source/data/in/nfkc_cf.nrm | Bin 51864 -> 51928 bytes icu4c/source/data/in/uts46.nrm | Bin 61060 -> 61068 bytes icu4c/source/test/cintltst/cnormtst.c | 7 +- icu4c/source/test/intltest/normconf.cpp | 5 +- icu4c/source/test/intltest/tstnorm.cpp | 147 +- icu4c/source/test/intltest/tstnorm.h | 4 + icu4c/source/tools/gennorm2/extradata.cpp | 80 +- icu4c/source/tools/gennorm2/extradata.h | 11 +- icu4c/source/tools/gennorm2/n2builder.cpp | 338 +++- icu4c/source/tools/gennorm2/n2builder.h | 13 +- icu4c/source/tools/gennorm2/norms.cpp | 12 +- icu4c/source/tools/gennorm2/norms.h | 17 +- .../src/com/ibm/icu/impl/Norm2AllModes.java | 8 +- .../src/com/ibm/icu/impl/Normalizer2Impl.java | 1202 +++++------ .../src/com/ibm/icu/text/Normalizer2.java | 6 +- icu4j/main/shared/data/icudata.jar | 4 +- icu4j/main/shared/data/testdata.jar | 4 +- .../icu/dev/test/normalizer/BasicTest.java | 73 +- .../dev/test/normalizer/ConformanceTest.java | 171 +- 34 files changed, 3372 insertions(+), 2692 deletions(-) diff --git a/icu4c/source/common/filterednormalizer2.cpp b/icu4c/source/common/filterednormalizer2.cpp index 28e5f6cbdde..eef199797c1 100644 --- a/icu4c/source/common/filterednormalizer2.cpp +++ b/icu4c/source/common/filterednormalizer2.cpp @@ -20,11 +20,13 @@ #if !UCONFIG_NO_NORMALIZATION +#include "unicode/edits.h" #include "unicode/normalizer2.h" #include "unicode/uniset.h" #include "unicode/unistr.h" #include "unicode/unorm.h" #include "cpputils.h" +#include "ustr_imp.h" // U_EDITS_NO_RESET U_NAMESPACE_BEGIN @@ -85,6 +87,52 @@ FilteredNormalizer2::normalize(const UnicodeString &src, return dest; } +void +FilteredNormalizer2::normalizeUTF8(uint32_t options, StringPiece src, ByteSink &sink, + Edits *edits, UErrorCode &errorCode) const { + if (U_FAILURE(errorCode)) { + return; + } + if (edits != nullptr && (options & U_EDITS_NO_RESET) == 0) { + edits->reset(); + } + options |= U_EDITS_NO_RESET; // Do not reset for each span. + normalizeUTF8(options, src.data(), src.length(), sink, edits, USET_SPAN_SIMPLE, errorCode); +} + +void +FilteredNormalizer2::normalizeUTF8(uint32_t options, const char *src, int32_t length, + ByteSink &sink, Edits *edits, + USetSpanCondition spanCondition, + UErrorCode &errorCode) const { + while (length > 0) { + int32_t spanLength = set.spanUTF8(src, length, spanCondition); + if (spanCondition == USET_SPAN_NOT_CONTAINED) { + if (spanLength != 0) { + if (edits != nullptr) { + edits->addUnchanged(spanLength); + } + if ((options & U_OMIT_UNCHANGED_TEXT) == 0) { + sink.Append(src, spanLength); + } + } + spanCondition = USET_SPAN_SIMPLE; + } else { + if (spanLength != 0) { + // Not norm2.normalizeSecondAndAppend() because we do not want + // to modify the non-filter part of dest. + norm2.normalizeUTF8(options, StringPiece(src, spanLength), sink, edits, errorCode); + if (U_FAILURE(errorCode)) { + break; + } + } + spanCondition = USET_SPAN_NOT_CONTAINED; + } + src += spanLength; + length -= spanLength; + } +} + UnicodeString & FilteredNormalizer2::normalizeSecondAndAppend(UnicodeString &first, const UnicodeString &second, diff --git a/icu4c/source/common/loadednormalizer2impl.cpp b/icu4c/source/common/loadednormalizer2impl.cpp index 0a4bef4adf7..288a7d69536 100644 --- a/icu4c/source/common/loadednormalizer2impl.cpp +++ b/icu4c/source/common/loadednormalizer2impl.cpp @@ -62,7 +62,7 @@ LoadedNormalizer2Impl::isAcceptable(void * /*context*/, pInfo->dataFormat[1]==0x72 && pInfo->dataFormat[2]==0x6d && pInfo->dataFormat[3]==0x32 && - pInfo->formatVersion[0]==2 + pInfo->formatVersion[0]==3 ) { // Normalizer2Impl *me=(Normalizer2Impl *)context; // uprv_memcpy(me->dataVersion, pInfo->dataVersion, 4); @@ -84,7 +84,7 @@ LoadedNormalizer2Impl::load(const char *packageName, const char *name, UErrorCod const uint8_t *inBytes=(const uint8_t *)udata_getMemory(memory); const int32_t *inIndexes=(const int32_t *)inBytes; int32_t indexesLength=inIndexes[IX_NORM_TRIE_OFFSET]/4; - if(indexesLength<=IX_MIN_YES_NO_MAPPINGS_ONLY) { + if(indexesLength<=IX_MIN_LCCC_CP) { errorCode=U_INVALID_FORMAT_ERROR; // Not enough indexes. return; } diff --git a/icu4c/source/common/norm2_nfc_data.h b/icu4c/source/common/norm2_nfc_data.h index 55a20617f7e..a8e33878dfb 100644 --- a/icu4c/source/common/norm2_nfc_data.h +++ b/icu4c/source/common/norm2_nfc_data.h @@ -11,14 +11,15 @@ #ifdef INCLUDED_FROM_NORMALIZER2_CPP -static const UVersionInfo norm2_nfc_data_formatVersion={2,0,0,0}; +static const UVersionInfo norm2_nfc_data_formatVersion={3,0,0,0}; static const UVersionInfo norm2_nfc_data_dataVersion={0xa,0,0,0}; static const int32_t norm2_nfc_data_indexes[Normalizer2Impl::IX_COUNT]={ -0x40,0x4c48,0x889c,0x899c,0x899c,0x899c,0x899c,0x899c,0xc0,0x300,0x56e,0x14e7,0x1e2a,0xfe00,0x941,0 +0x50,0x4cc0,0x8918,0x8a18,0x8a18,0x8a18,0x8a18,0x8a18,0xc0,0x300,0xadc,0x29d0,0x3c56,0xfc00,0x1282,0x3b8c, +0x3c24,0x3c56,0x300,0 }; -static const uint16_t norm2_nfc_data_trieIndex[9724]={ +static const uint16_t norm2_nfc_data_trieIndex[9776]={ 0x2a8,0x2b0,0x2b8,0x2c0,0x2ce,0x2d6,0x2de,0x2e6,0x2ee,0x2f6,0x2fe,0x306,0x30e,0x316,0x31c,0x324, 0x32c,0x334,0x2c7,0x2cf,0x339,0x341,0x2c7,0x2cf,0x349,0x351,0x359,0x361,0x369,0x371,0x379,0x381, 0x389,0x391,0x399,0x3a1,0x3a9,0x3b1,0x3b9,0x3c1,0x2c7,0x2cf,0x2c7,0x2cf,0x3c8,0x3d0,0x3d8,0x3e0, @@ -105,29 +106,29 @@ static const uint16_t norm2_nfc_data_trieIndex[9724]={ 0x2c7,0x2c7,0x2c7,0x6e5,0x6ed,0x2c7,0x2c7,0x6f5,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7, 0x6fc,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x703,0x70b,0x2c7,0x711,0x715,0x2c7,0x2c7,0x58b,0x71d,0x2c7, 0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x721,0x729,0x72c,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x48b, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959, -0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x959,0x960,0x2c7,0x2c7, -0x968,0x96f,0x2a8,0x976,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8, +0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a, +0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c, +0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e, +0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959, +0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b, +0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d, +0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d, +0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a, +0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c, +0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e, +0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959, +0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b, +0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d, +0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d, +0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a, +0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c, +0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e, +0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959, +0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b, +0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d, +0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d, +0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x96d,0x959,0x95a,0x95b,0x95c,0x95d,0x95e,0x965,0x2c7,0x2c7, +0x975,0x97c,0x2a8,0x983,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8, 0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8,0x2a8, 0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7, 0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7, @@ -189,447 +190,450 @@ static const uint16_t norm2_nfc_data_trieIndex[9724]={ 0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7, 0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7, 0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2a7, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,2,4,6,0, -0,8,0x28,0x2e,0x38,0x44,0x66,0x68,0x76,0x84,0xa2,0xa4,0xae,0xba,0xc0,0xd2, -0xf2,0,0xf6,0x106,0x114,0x122,0x148,0x14c,0x158,0x15c,0x16e,0,0,0,0,0, -0,0x17a,0x19a,0x1a0,0x1aa,0x1b6,0x1d8,0x1da,0x1e8,0x1f8,0x214,0x218,0x222,0x22e,0x234,0x246, -0x266,0,0x26a,0x27a,0x288,0x298,0x2be,0x2c2,0x2d0,0x2d4,0x2e8,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0x2f4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0x941,0x944,0x56f,0x947,0x57a,0x57f,0x2fa,0x584, -0x94a,0x94d,0x589,0x950,0x953,0x956,0x959,0x594,0,0x95c,0x95f,0x962,0x599,0x5a4,0x5ad,0, -0x2fe,0x965,0x968,0x96b,0x5b2,0x96e,0,0,0x971,0x974,0x5bd,0x977,0x5c8,0x5cd,0x300,0x5d2, -0x97a,0x97d,0x5d7,0x980,0x983,0x986,0x989,0x5e2,0,0x98c,0x98f,0x992,0x5e7,0x5f2,0x5fb,0, -0x304,0x995,0x998,0x99b,0x600,0x99e,0,0x9a1,0x9a4,0x9a7,0x60b,0x616,0x9aa,0x9ad,0x9b0,0x9b3, -0x9b6,0x9b9,0x9bc,0x9bf,0x9c2,0x9c5,0x9c8,0x9cb,0,0,0x621,0x628,0x9ce,0x9d1,0x9d4,0x9d7, -0x9da,0x9dd,0x9e0,0x9e3,0x9e6,0x9e9,0x9ec,0x9ef,0x9f2,0x9f5,0x9f8,0x9fb,0x9fe,0xa01,0,0, -0xa04,0xa07,0xa0a,0xa0d,0xa10,0xa13,0xa16,0xa19,0xa1c,0,0,0,0xa1f,0xa22,0xa25,0xa28, -0,0xa2b,0xa2e,0xa31,0xa34,0xa37,0xa3a,0,0,0,0,0xa3d,0xa40,0xa43,0xa46,0xa49, -0xa4c,0,0,0,0x62f,0x636,0xa4f,0xa52,0xa55,0xa58,0,0,0xa5b,0xa5e,0xa61,0xa64, -0xa67,0xa6a,0x63d,0x642,0xa6d,0xa70,0xa73,0xa76,0x647,0x64c,0xa79,0xa7c,0xa7f,0xa82,0,0, -0x651,0x656,0x65b,0x660,0xa85,0xa88,0xa8b,0xa8e,0xa91,0xa94,0xa97,0xa9a,0xa9d,0xaa0,0xaa3,0xaa6, -0xaa9,0xaac,0xaaf,0xab2,0xab5,0xab8,0xabb,0x306,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0x665,0x672,0,0,0,0,0,0, -0,0,0,0,0,0,0,0x67f,0x68c,0,0,0,0,0,0,0x308, -0,0,0,0,0,0,0,0,0,0,0,0,0,0xabe,0xac1,0xac4, -0xac7,0xaca,0xacd,0xad0,0xad3,0xad7,0xadc,0xae1,0xae6,0xaeb,0xaf0,0xaf5,0xafa,0,0xaff,0xb04, -0xb09,0xb0e,0xb12,0xb15,0,0,0xb18,0xb1b,0xb1e,0xb21,0x699,0x69e,0xb25,0xb2a,0xb2e,0xb31, -0xb34,0,0,0,0xb37,0xb3a,0,0,0xb3d,0xb40,0xb44,0xb49,0xb4d,0xb50,0xb53,0xb56, -0xb59,0xb5c,0xb5f,0xb62,0xb65,0xb68,0xb6b,0xb6e,0xb71,0xb74,0xb77,0xb7a,0xb7d,0xb80,0xb83,0xb86, -0xb89,0xb8c,0xb8f,0xb92,0xb95,0xb98,0xb9b,0xb9e,0xba1,0xba4,0xba7,0xbaa,0,0,0xbad,0xbb0, -0,0,0,0,0,0,0x6a3,0x6a8,0x6ad,0x6b2,0xbb4,0xbb9,0xbbe,0xbc3,0x6b7,0x6bc, -0xbc8,0xbcd,0xbd1,0xbd4,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0x30a,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0xfee6,0xfee6,0xfee6,0xfee6,0xfee6,0xffe6,0xfee6,0xfee6,0xfee6,0xfee6,0xfee6,0xfee6, -0xfee6,0xffe6,0xffe6,0xfee6,0xffe6,0xfee6,0xffe6,0xfee6,0xfee6,0xffe8,0xffdc,0xffdc,0xffdc,0xffdc,0xffe8,0xfed8, -0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffca,0xffca,0xfedc,0xfedc,0xfedc,0xfedc,0xfeca,0xfeca,0xffdc,0xffdc,0xffdc, -0xffdc,0xfedc,0xfedc,0xffdc,0xfedc,0xfedc,0xffdc,0xffdc,0xff01,0xff01,0xff01,0xff01,0xfe01,0xffdc,0xffdc,0xffdc, -0xffdc,0xffe6,0xffe6,0xffe6,0x14e8,0x14eb,0xfee6,0x14ee,0x14f1,0xfef0,0xffe6,0xffdc,0xffdc,0xffdc,0xffe6,0xffe6, -0xffe6,0xffdc,0xffdc,0,0xffe6,0xffe6,0xffe6,0xffdc,0xffdc,0xffdc,0xffdc,0xffe6,0xffe8,0xffdc,0xffdc,0xffe6, -0xffe9,0xffea,0xffea,0xffe9,0xffea,0xffea,0xffe9,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6, -0xffe6,0xffe6,0xffe6,0xffe6,0,0,0,0,0x14f4,0,0,0,0,0,0,0, -0,0,0x14f6,0,0,0,0,0,0,0xbd7,0xbda,0x14f8,0xbdd,0xbe0,0xbe3,0, -0xbe6,0,0xbe9,0xbec,0xbf0,0x30c,0,0,0,0x31a,0,0x322,0,0x32c,0,0, -0,0,0,0x33a,0,0x342,0,0,0,0x344,0,0,0,0x350,0xbf4,0xbf7, -0x6c1,0xbfa,0x6c6,0xbfd,0xc01,0x35a,0,0,0,0x36a,0,0x372,0,0x37e,0,0, -0,0,0,0x38e,0,0x396,0,0,0,0x39a,0,0,0,0x3aa,0x6cb,0x6d4, -0xc05,0xc08,0x6dd,0,0,0,0x3b6,0xc0b,0xc0e,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0xc11,0xc14,0,0xc17,0,0,0x3ba,0xc1a,0,0,0,0, -0xc1d,0xc20,0xc23,0,0x3bc,0,0,0x3c0,0,0x3c2,0x3c8,0x3cc,0x3ce,0xc26,0x3d6,0, -0,0,0x3d8,0,0,0,0,0x3da,0,0,0,0x3e2,0,0,0,0x3e4, -0,0x3e6,0,0,0x3e8,0,0,0x3ec,0,0x3ee,0x3f4,0x3f8,0x3fa,0xc29,0x402,0, -0,0,0x404,0,0,0,0,0x406,0,0,0,0x40e,0,0,0,0x410, -0,0x412,0,0,0xc2c,0xc2f,0,0xc32,0,0,0x414,0xc35,0,0,0,0, -0xc38,0xc3b,0xc3e,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0x416,0x418,0xc41,0xc44,0,0,0,0, -0,0,0,0,0,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0xc47,0xc4a,0,0,0,0,0,0,0,0,0, -0,0,0,0,0xc4d,0xc50,0xc53,0xc56,0,0,0xc59,0xc5c,0x41a,0x41c,0xc5f,0xc62, -0xc65,0xc68,0xc6b,0xc6e,0,0,0xc71,0xc74,0xc77,0xc7a,0xc7d,0xc80,0x41e,0x420,0xc83,0xc86, -0xc89,0xc8c,0xc8f,0xc92,0xc95,0xc98,0xc9b,0xc9e,0xca1,0xca4,0,0,0xca7,0xcaa,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0xffdc,0xffe6,0xffe6,0xffe6,0xffe6,0xffdc,0xffe6,0xffe6,0xffe6,0xffde,0xffdc,0xffe6,0xffe6,0xffe6,0xffe6, -0xffe6,0xffe6,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffe6,0xffe6,0xffdc,0xffe6,0xffe6,0xffde,0xffe4,0xffe6, -0xff0a,0xff0b,0xff0c,0xff0d,0xff0e,0xff0f,0xff10,0xff11,0xff12,0xff13,0xff13,0xff14,0xff15,0xff16,0,0xff17, -0,0xff18,0xff19,0,0xffe6,0xffdc,0,0xff12,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xff1e,0xff1f,0xff20,0,0,0,0,0, -0,0,0xcad,0xcb0,0xcb3,0xcb6,0xcb9,0x422,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0x428,0,0x42a,0xff1b,0xff1c,0xff1d,0xff1e,0xff1f,0xff20,0xff21,0xff22,0xfee6,0xfee6,0xfedc,0xffdc,0xffe6, -0xffe6,0xffe6,0xffe6,0xffe6,0xffdc,0xffe6,0xffe6,0xffdc,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0xff23,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0xcbc,0x42c,0xcbf,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0x42e,0xcc2,0,0x430,0xffe6,0xffe6, -0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffdc,0xffe6,0,0,0xffe6, -0xffe6,0,0xffdc,0xffe6,0xffe6,0xffdc,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0xff24,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0xffe6,0xffdc,0xffe6,0xffe6,0xffdc,0xffe6,0xffe6,0xffdc, -0xffdc,0xffdc,0xffe6,0xffdc,0xffdc,0xffe6,0xffdc,0xffe6,0xffe6,0xffe6,0xffdc,0xffe6,0xffdc,0xffe6,0xffdc,0xffe6, -0xffdc,0xffe6,0xffe6,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6, -0xffe6,0xffe6,0xffdc,0xffe6,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0,0xffe6, -0xffe6,0xffe6,0xffe6,0xffe6,0,0xffe6,0xffe6,0xffe6,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0xffdc,0xffdc,0xffdc,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,0xffdc, -0xffe6,0xffe6,0xffdc,0xffe6,0xffe6,0xffdc,0xffe6,0xffe6,0xffe6,0xffdc,0xffdc,0xffdc,0xff1b,0xff1c,0xff1d,0xffe6, -0xffe6,0xffe6,0xffdc,0xffe6,0xffe6,0xffdc,0xffdc,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,0,0,0, -0,0,0,0,0x432,0xcc5,0,0,0,0,0,0,0x434,0xcc8,0,0x436, -0xccb,0,0,0,0,0,0,0,0xfe07,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0xff09,0,0,0,0xffe6,0xffdc,0xffe6, -0xffe6,0,0,0,0x14fa,0x14fd,0x1500,0x1503,0x1506,0x1509,0x150c,0x150f,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0xff07,0,0xfe00,0,0,0,0,0, -0,0,0,0x438,0,0,0,0xcce,0xcd1,0xff09,0,0,0,0,0,0, -0,0,0,0xfe00,0,0,0,0,0x1512,0x1515,0,0x1518,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x151b, -0,0,0x151e,0,0,0,0,0,0xff07,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0xff09,0,0,0,0,0,0, -0,0,0,0,0,0x1521,0x1524,0x1527,0,0,0x152a,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0xff07,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0xff09,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x43c, -0xcd4,0,0,0xcd7,0xcda,0xff09,0,0,0,0,0,0,0,0,0xfe00,0xfe00, -0,0,0,0,0x152d,0x1530,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0x442,0,0xcdd,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xfe00,0, -0,0,0,0,0,0,0x444,0x448,0,0,0xce0,0xce3,0xce6,0xff09,0,0, -0,0,0,0,0,0,0,0xfe00,0,0,0,0,0,0,0,0, -0,0,0x44a,0,0xce9,0,0,0,0,0xff09,0,0,0,0,0,0, -0,0xff54,0xfe5b,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0xff07,0,0,0x44c,0xcec,0,0xfe00,0,0,0,0x44e,0xcef,0xcf2,0,0x6e2,0xcf6, -0,0xff09,0,0,0,0,0,0,0,0xfe00,0xfe00,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0xff09,0xff09,0,0xfe00,0,0,0,0,0, -0,0,0x454,0x458,0,0,0xcfa,0xcfd,0xd00,0xff09,0,0,0,0,0,0, -0,0,0,0xfe00,0,0,0,0,0,0,0,0,0,0,0xfe09,0, -0,0,0,0xfe00,0,0,0,0,0,0,0,0,0,0x45a,0xd03,0, -0x6e7,0xd07,0xd0b,0xfe00,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0xff67,0xff67,0xff09,0, -0,0,0,0,0,0,0,0,0xff6b,0xff6b,0xff6b,0xff6b,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0xff76,0xff76,0,0,0,0,0,0,0,0,0,0, -0xff7a,0xff7a,0xff7a,0xff7a,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0xffdc,0xffdc,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0xffdc,0,0xffdc,0,0xffd8,0,0,0,0,0,0, -0,0,0,0x1533,0,0,0,0,0,0,0,0,0,0x1536,0,0, -0,0,0x1539,0,0,0,0,0x153c,0,0,0,0,0x153f,0,0,0, -0,0,0,0,0,0,0,0,0,0x1542,0,0,0,0,0,0, -0,0xff81,0xff82,0x1546,0xff84,0x154a,0x154d,0,0x1550,0,0xff82,0xff82,0xff82,0xff82,0,0, -0xff82,0x1554,0xffe6,0xffe6,0xff09,0,0xffe6,0xffe6,0,0,0,0,0,0,0,0, -0,0,0,0x1557,0,0,0,0,0,0,0,0,0,0x155a,0,0, -0,0,0x155d,0,0,0,0,0x1560,0,0,0,0,0x1563,0,0,0, -0,0,0,0,0,0,0,0,0,0x1566,0,0,0,0,0,0, -0,0,0xffdc,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0x460,0xd0e,0, -0,0,0,0,0,0,0xfe00,0,0,0,0,0,0,0,0,0xff07, -0,0xff09,0xff09,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0xffdc,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0xffe6,0xffe6,0xffe6,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0xff09,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xff09,0, -0,0,0,0,0,0,0,0,0,0xffe6,0,0,0,0,0,0, -0,0,0,0,0,0xffe4,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0xffde,0xffe6,0xffdc,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0xffe6,0xffdc,0,0,0, -0,0,0,0,0xff09,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6, -0xffe6,0,0,0xffdc,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffe6, -0xffe6,0xffdc,0,0,0,0,0,0,0,0x462,0xd11,0x464,0xd14,0x466,0xd17,0x468, -0xd1a,0x46a,0xd1d,0,0,0x46c,0xd20,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0xff07,0xfe00,0,0, -0,0,0x46e,0xd23,0x470,0xd26,0x472,0x474,0xd29,0xd2c,0x476,0xd2f,0xff09,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0xffe6,0xffdc,0xffe6,0xffe6,0xffe6, -0xffe6,0xffe6,0xffe6,0xffe6,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0xff09,0xff09,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0xff07,0,0,0,0,0, -0,0,0,0,0,0,0xff09,0xff09,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xff07, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0xffe6,0xffe6,0xffe6,0,0xff01,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffe6,0xffe6,0xffdc,0xffdc,0xffdc,0xffdc, -0xffe6,0,0xff01,0xff01,0xff01,0xff01,0xff01,0xff01,0xff01,0,0,0,0,0xffdc,0,0, -0,0,0,0,0xffe6,0,0,0,0xffe6,0xffe6,0,0,0,0,0,0, -0xffe6,0xffe6,0xffdc,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffdc,0xffe6,0xffe6,0xffea,0xffd6,0xffdc, -0xffca,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6, -0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe8,0xffe4,0xffe4,0xffdc,0,0xffe6, -0xffe9,0xffdc,0xffe6,0xffdc,0xd32,0xd35,0xd38,0xd3b,0xd3e,0xd41,0xd44,0xd47,0xd4b,0xd50,0xd54,0xd57, -0xd5a,0xd5d,0xd60,0xd63,0xd66,0xd69,0xd6c,0xd6f,0xd73,0xd78,0xd7d,0xd82,0xd86,0xd89,0xd8c,0xd8f, -0xd93,0xd98,0xd9c,0xd9f,0xda2,0xda5,0xda8,0xdab,0xdae,0xdb1,0xdb4,0xdb7,0xdba,0xdbd,0xdc0,0xdc3, -0xdc6,0xdc9,0xdcd,0xdd2,0xdd6,0xdd9,0xddc,0xddf,0xde2,0xde5,0x6ec,0x6f1,0xde9,0xdee,0xdf2,0xdf5, -0xdf8,0xdfb,0xdfe,0xe01,0xe04,0xe07,0xe0a,0xe0d,0xe10,0xe13,0xe16,0xe19,0xe1c,0xe1f,0xe22,0xe25, -0xe29,0xe2e,0xe33,0xe38,0xe3d,0xe42,0xe47,0xe4c,0xe50,0xe53,0xe56,0xe59,0xe5c,0xe5f,0x6f6,0x6fb, -0xe63,0xe68,0xe6c,0xe6f,0xe72,0xe75,0x700,0x705,0xe79,0xe7e,0xe83,0xe88,0xe8d,0xe92,0xe96,0xe99, -0xe9c,0xe9f,0xea2,0xea5,0xea8,0xeab,0xeae,0xeb1,0xeb4,0xeb7,0xeba,0xebd,0xec1,0xec6,0xecb,0xed0, -0xed4,0xed7,0xeda,0xedd,0xee0,0xee3,0xee6,0xee9,0xeec,0xeef,0xef2,0xef5,0xef8,0xefb,0xefe,0xf01, -0xf04,0xf07,0xf0a,0xf0d,0xf10,0xf13,0xf16,0xf19,0xf1c,0xf1f,0xf22,0xf25,0xf28,0xf2b,0,0xf2e, -0,0,0,0,0x70a,0x711,0xf31,0xf34,0xf38,0xf3d,0xf42,0xf47,0xf4c,0xf51,0xf56,0xf5b, -0xf60,0xf65,0xf6a,0xf6f,0xf74,0xf79,0xf7e,0xf83,0xf88,0xf8d,0xf92,0xf97,0x718,0x71d,0xf9b,0xf9e, -0xfa1,0xfa4,0xfa8,0xfad,0xfb2,0xfb7,0xfbc,0xfc1,0xfc6,0xfcb,0xfd0,0xfd5,0xfd9,0xfdc,0xfdf,0xfe2, -0x722,0x727,0xfe5,0xfe8,0xfec,0xff1,0xff6,0xffb,0x1000,0x1005,0x100a,0x100f,0x1014,0x1019,0x101e,0x1023, -0x1028,0x102d,0x1032,0x1037,0x103c,0x1041,0x1046,0x104b,0x104f,0x1052,0x1055,0x1058,0x105c,0x1061,0x1066,0x106b, -0x1070,0x1075,0x107a,0x107f,0x1084,0x1089,0x108d,0x1090,0x1093,0x1096,0x1099,0x109c,0x109f,0x10a2,0,0, -0,0,0,0,0x72c,0x737,0x743,0x74a,0x751,0x758,0x75f,0x766,0x76c,0x777,0x783,0x78a, -0x791,0x798,0x79f,0x7a6,0x7ac,0x7b3,0x10a6,0x10ab,0x10b0,0x10b5,0,0,0x7ba,0x7c1,0x10ba,0x10bf, -0x10c4,0x10c9,0,0,0x7c8,0x7d3,0x7df,0x7e6,0x7ed,0x7f4,0x7fb,0x802,0x808,0x813,0x81f,0x826, -0x82d,0x834,0x83b,0x842,0x848,0x851,0x10ce,0x10d3,0x10d8,0x10dd,0x10e2,0x10e7,0x85a,0x863,0x10ec,0x10f1, -0x10f6,0x10fb,0x1100,0x1105,0x86c,0x873,0x110a,0x110f,0x1114,0x1119,0,0,0x87a,0x881,0x111e,0x1123, -0x1128,0x112d,0,0,0x888,0x891,0x1132,0x1137,0x113c,0x1141,0x1146,0x114b,0,0x89a,0,0x1150, -0,0x1155,0,0x115a,0x8a3,0x8ae,0x8ba,0x8c1,0x8c8,0x8cf,0x8d6,0x8dd,0x8e3,0x8ee,0x8fa,0x901, -0x908,0x90f,0x916,0x91d,0x923,0x156a,0x115e,0x156e,0x928,0x1572,0x1161,0x1576,0x1164,0x157a,0x1167,0x157e, -0x92d,0x1582,0,0,0x116b,0x1170,0x1177,0x117f,0x1187,0x118f,0x1197,0x119f,0x11a5,0x11aa,0x11b1,0x11b9, -0x11c1,0x11c9,0x11d1,0x11d9,0x11df,0x11e4,0x11eb,0x11f3,0x11fb,0x1203,0x120b,0x1213,0x1219,0x121e,0x1225,0x122d, -0x1235,0x123d,0x1245,0x124d,0x1253,0x1258,0x125f,0x1267,0x126f,0x1277,0x127f,0x1287,0x128d,0x1292,0x1299,0x12a1, -0x12a9,0x12b1,0x12b9,0x12c1,0x12c6,0x12c9,0x12cd,0x12d1,0x12d5,0,0x932,0x12da,0x12de,0x12e1,0x12e4,0x1586, -0x12e7,0,0x1589,0x478,0,0x12ea,0x12ee,0x12f2,0x12f6,0,0x937,0x12fb,0x12ff,0x158c,0x1302,0x1590, -0x1305,0x1308,0x130b,0x130e,0x1311,0x1314,0x1318,0x1595,0,0,0x131c,0x1320,0x1324,0x1327,0x132a,0x159a, -0,0x132d,0x1330,0x1333,0x1336,0x1339,0x133d,0x159f,0x1341,0x1344,0x1347,0x134b,0x134f,0x1352,0x1355,0x15a4, -0x1358,0x135b,0x15a8,0x15ab,0,0,0x135f,0x1363,0x1367,0,0x93c,0x136c,0x1370,0x15ae,0x1373,0x15b2, -0x1376,0x15b5,0x47e,0,0xfdc1,0xfdc1,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0xffe6,0xffe6,0xff01,0xff01,0xffe6,0xffe6,0xffe6,0xffe6,0xff01,0xff01,0xff01,0xffe6, -0xffe6,0,0,0,0,0xffe6,0,0,0,0xff01,0xff01,0xffe6,0xffdc,0xffe6,0xff01,0xff01, -0xffdc,0xffdc,0xffdc,0xffdc,0xffe6,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0x15b7,0,0,0,0x15b9,0x15bc,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0x484,0,0x486,0,0x488,0,0,0,0,0,0x1379,0x137c,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0x137f,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0x1382,0x1385,0x1388, -0x48a,0,0x48c,0,0x48e,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0x490,0x138b,0,0,0,0x492,0x138e,0,0x494,0x1391,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0x496,0x1394,0x498,0x1397,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0x49a,0,0,0, -0,0x139a,0,0x49c,0x139d,0x49e,0,0x13a0,0x4a0,0x13a3,0,0,0,0x4a2,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0x13a6,0x4a4,0x13a9,0,0x4a6,0x4a8,0,0,0,0,0,0,0,0x13ac,0x13af,0x13b2, -0x13b5,0x13b8,0x4aa,0x4ac,0x13bb,0x13be,0x4ae,0x4b0,0x13c1,0x13c4,0x4b2,0x4b4,0x4b6,0x4b8,0,0, -0x13c7,0x13ca,0x4ba,0x4bc,0x13cd,0x13d0,0x4be,0x4c0,0x13d3,0x13d6,0,0,0,0,0,0, -0,0x4c2,0x4c4,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0x4c6,0,0,0,0,0,0x4c8,0x4ca,0,0x4cc,0x13d9,0x13dc,0x13df,0x13e2, -0,0,0x4ce,0x4d0,0x4d2,0x4d4,0,0,0,0,0,0,0,0,0,0, -0x13e5,0x13e8,0x13eb,0x13ee,0,0,0,0,0,0,0x13f1,0x13f4,0x13f7,0x13fa,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0x15bf,0x15c1,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0x15c3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0xffe6,0xffe6,0xffe6,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0xff09,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6, -0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6, -0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,0,0,0,0,0,0,0, -0,0,0xffda,0xffe4,0xffe8,0xffde,0xffe0,0xffe0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0x4d6,0,0,0,0,0x4d8, -0x13fd,0x4da,0x1400,0x4dc,0x1403,0x4de,0x1406,0x4e0,0x1409,0x4e2,0x140c,0x4e4,0x140f,0x4e6,0x1412,0x4e8, -0x1415,0x4ea,0x1418,0x4ec,0x141b,0x4ee,0x141e,0,0x4f0,0x1421,0x4f2,0x1424,0x4f4,0x1427,0,0, -0,0,0,0x4f6,0x142a,0x142d,0x4fa,0x1430,0x1433,0x4fe,0x1436,0x1439,0x502,0x143c,0x143f,0x506, -0x1442,0x1445,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0x1448,0,0,0,0,0xfe08,0xfe08,0, -0,0x50a,0x144b,0,0,0,0,0,0,0,0x50c,0,0,0,0,0x50e, -0x144e,0x510,0x1451,0x512,0x1454,0x514,0x1457,0x516,0x145a,0x518,0x145d,0x51a,0x1460,0x51c,0x1463,0x51e, -0x1466,0x520,0x1469,0x522,0x146c,0x524,0x146f,0,0x526,0x1472,0x528,0x1475,0x52a,0x1478,0,0, -0,0,0,0x52c,0x147b,0x147e,0x530,0x1481,0x1484,0x534,0x1487,0x148a,0x538,0x148d,0x1490,0x53c, -0x1493,0x1496,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0x540,0x542,0x544,0x546,0,0x1499,0,0,0x149c,0x149f,0x14a2,0x14a5,0, -0,0x548,0x14a8,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0xffe6,0,0,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6, -0xffe6,0xffe6,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0xffe6,0xffe6,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0xffe6,0xffe6,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0xff09,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0xff09,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0xffe6,0xffe6,0xffe6,0xffe6, -0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xffdc, -0xffdc,0xffdc,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0xff09,0,0,0,0,0,0,0,0, -0,0,0,0,0xff09,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0xffe6,0,0xffe6,0xffe6,0xffdc,0,0,0xffe6,0xffe6,0,0,0, -0,0,0xffe6,0xffe6,0,0xffe6,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0xff09,0,0,0,0,0,0,0,0,0, -0x15c6,0x15c8,0x15ca,0x15cc,0x15ce,0x15d0,0x15d2,0x15d4,0x15d4,0x15d6,0x15d8,0x15da,0x15dc,0x15de,0x15e0,0x15e2, -0x15e4,0x15e6,0x15e8,0x15ea,0x15ec,0x15ee,0x15f0,0x15f2,0x15f4,0x15f6,0x15f8,0x15fa,0x15fc,0x15fe,0x1600,0x1602, -0x1604,0x1606,0x1608,0x160a,0x160c,0x160e,0x1610,0x1612,0x1614,0x1616,0x1618,0x161a,0x161c,0x161e,0x1620,0x1622, -0x1624,0x1626,0x1628,0x162a,0x162c,0x162e,0x1630,0x1632,0x1634,0x1636,0x1638,0x163a,0x163c,0x163e,0x1640,0x1642, -0x1644,0x1646,0x1648,0x164a,0x164c,0x164e,0x1650,0x1652,0x1654,0x1656,0x1658,0x165a,0x165c,0x165e,0x1660,0x1662, -0x1664,0x1666,0x1668,0x166a,0x166c,0x166e,0x1670,0x1672,0x1674,0x1676,0x1678,0x167a,0x15ec,0x167c,0x167e,0x1680, -0x1682,0x1684,0x1686,0x1688,0x168a,0x168c,0x168e,0x1690,0x1692,0x1694,0x1696,0x1698,0x169a,0x169c,0x169e,0x16a0, -0x16a2,0x16a4,0x16a6,0x16a8,0x16aa,0x16ac,0x16ae,0x16b0,0x16b2,0x16b4,0x16b6,0x16b8,0x16ba,0x16bc,0x16be,0x16c0, -0x16c2,0x16c4,0x16c6,0x16c8,0x16ca,0x16cc,0x16ce,0x16d0,0x16d2,0x16d4,0x16d6,0x16d8,0x16da,0x16dc,0x16de,0x16e0, -0x16e2,0x16e4,0x16e6,0x16e8,0x16ea,0x16ec,0x16ee,0x16f0,0x16f2,0x16f4,0x16f6,0x16f8,0x16fa,0x16fc,0x16fe,0x1700, -0x1702,0x16a0,0x1704,0x1706,0x1708,0x170a,0x170c,0x170e,0x1710,0x1712,0x1680,0x1714,0x1716,0x1718,0x171a,0x171c, -0x171e,0x1720,0x1722,0x1724,0x1726,0x1728,0x172a,0x172c,0x172e,0x1730,0x1732,0x1734,0x1736,0x1738,0x173a,0x15ec, -0x173c,0x173e,0x1740,0x1742,0x1744,0x1746,0x1748,0x174a,0x174c,0x174e,0x1750,0x1752,0x1754,0x1756,0x1758,0x175a, -0x175c,0x175e,0x1760,0x1762,0x1764,0x1766,0x1768,0x176a,0x176c,0x176e,0x1770,0x1684,0x1772,0x1774,0x1776,0x1778, -0x177a,0x177c,0x177e,0x1780,0x1782,0x1784,0x1786,0x1788,0x178a,0x178c,0x178e,0x1790,0x1792,0x1794,0x1796,0x1798, -0x179a,0x179c,0x179e,0x17a0,0x17a2,0x17a4,0x17a6,0x17a8,0x17aa,0x17ac,0x17ae,0x17b0,0x17b2,0x17b4,0x17b6,0x17b8, -0x17ba,0x17bc,0x17be,0x17c0,0x17c2,0x17c4,0x17c6,0x17c8,0x17ca,0x17cc,0x17ce,0x17d0,0x17d2,0x17d4,0,0, -0x17d6,0,0x17d8,0,0,0x17da,0x17dc,0x17de,0x17e0,0x17e2,0x17e4,0x17e6,0x17e8,0x17ea,0x17ec,0, -0x17ee,0,0x17f0,0,0,0x17f2,0x17f4,0,0,0,0x17f6,0x17f8,0x17fa,0x17fc,0x17fe,0x1800, -0x1802,0x1804,0x1806,0x1808,0x180a,0x180c,0x180e,0x1810,0x1812,0x1814,0x1816,0x1818,0x181a,0x181c,0x181e,0x1820, -0x1822,0x1824,0x1826,0x1828,0x182a,0x182c,0x182e,0x1830,0x1832,0x1834,0x1836,0x1838,0x183a,0x183c,0x183e,0x1840, -0x1842,0x1844,0x1846,0x1848,0x184a,0x184c,0x184e,0x16ee,0x1850,0x1852,0x1854,0x1856,0x1858,0x185a,0x185a,0x185c, -0x185e,0x1860,0x1862,0x1864,0x1866,0x1868,0x186a,0x17f2,0x186c,0x186e,0x1870,0x1872,0x1874,0x1877,0,0, -0x1879,0x187b,0x187d,0x187f,0x1881,0x1883,0x1885,0x1887,0x180e,0x1889,0x188b,0x188d,0x17d6,0x188f,0x1891,0x1893, -0x1895,0x1897,0x1899,0x189b,0x189d,0x189f,0x18a1,0x18a3,0x18a5,0x1820,0x18a7,0x1822,0x18a9,0x18ab,0x18ad,0x18af, -0x18b1,0x17d8,0x1616,0x18b3,0x18b5,0x18b7,0x16a2,0x1750,0x18b9,0x18bb,0x1830,0x18bd,0x1832,0x18bf,0x18c1,0x18c3, -0x17dc,0x18c5,0x18c7,0x18c9,0x18cb,0x18cd,0x17de,0x18cf,0x18d1,0x18d3,0x18d5,0x18d7,0x18d9,0x184e,0x18db,0x18dd, -0x16ee,0x18df,0x1856,0x18e1,0x18e3,0x18e5,0x18e7,0x18e9,0x1860,0x18eb,0x17f0,0x18ed,0x1862,0x167c,0x18ef,0x1864, -0x18f1,0x1868,0x18f3,0x18f5,0x18f7,0x18f9,0x18fb,0x186c,0x17e8,0x18fd,0x186e,0x18ff,0x1870,0x1901,0x15d4,0x1903, -0x1906,0x1909,0x190c,0x190e,0x1910,0x1912,0x1915,0x1918,0x191b,0x191d,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0x191f,0xff1a,0x1922,0,0,0,0, -0,0,0,0,0,0,0x1925,0x1928,0x192c,0x1931,0x1935,0x1938,0x193b,0x193e,0x1941,0x1944, -0x1947,0x194a,0x194d,0,0x1950,0x1953,0x1956,0x1959,0x195c,0,0x195f,0,0x1962,0x1965,0,0x1968, -0x196b,0,0x196e,0x1971,0x1974,0x1977,0x197a,0x197d,0x1980,0x1983,0x1986,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0xffe6,0xffe6,0xffe6,0xffe6, -0xffe6,0xffe6,0xffe6,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffe6,0xffe6,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0xffdc,0,0,0xffdc,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xffe6,0xffe6, -0xffe6,0xffe6,0xffe6,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0xffdc,0,0xffe6,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0xffe6,0xff01,0xffdc,0, -0,0,0,0xff09,0,0,0,0,0,0xffe6,0xffdc,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0x54a,0x14ab,0x54d,0x14b0,0,0,0,0,0,0,0, -0,0x550,0,0,0,0,0,0x14b5,0,0,0,0,0,0,0,0, -0,0,0,0,0,0xff09,0xfe07,0,0,0,0,0,0xffe6,0xffe6,0xffe6,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xfe00, -0,0,0,0,0,0,0x14ba,0x14bf,0,0x553,0x556,0xff09,0xff09,0,0,0, -0,0,0,0,0,0,0,0,0xff09,0,0,0,0,0,0,0, -0,0,0xff07,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0xff09,0xff07,0,0,0,0,0, -0,0,0,0,0,0xff07,0xff09,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x559, -0,0,0,0x14c4,0x14c9,0xff09,0,0,0,0,0,0,0,0,0,0xfe00, -0,0,0,0,0,0,0,0,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6, -0xffe6,0,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,0,0,0,0,0,0, -0,0,0,0,0,0,0xff09,0,0,0,0xff07,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0xfe00,0,0,0,0,0,0,0,0,0x55f,0xfe00,0x14ce, -0x14d3,0xfe00,0x14d8,0,0,0,0xff09,0xff07,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0xfe00,0,0,0,0,0,0,0,0, -0x568,0x56b,0x14dd,0x14e2,0,0,0,0xff09,0xff07,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0xff09,0xff07,0,0,0,0, -0,0,0,0,0,0,0,0xff09,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0xff09,0,0,0,0,0,0,0,0,0xff07,0,0xff09,0xff09,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0xff01,0xff01,0xff01,0xff01,0xff01,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0xff01,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0x1989,0x198e,0x1998,0x19a4,0x19b0,0x19bc,0x19c8,0xffd8,0xffd8,0xff01, -0xff01,0xff01,0,0,0,0xffe2,0xffd8,0xffd8,0xffd8,0xffd8,0xffd8,0,0,0,0,0, -0,0,0,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0,0,0xffe6,0xffe6,0xffe6, -0xffe6,0xffe6,0xffdc,0xffdc,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0,0, -0,0,0,0,0,0,0,0,0,0,0,0x19cf,0x19d4,0x19de,0x19ea,0x19f6, -0x1a02,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0xffe6,0xffe6,0xffe6,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6, -0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6, -0xffe6,0xffe6,0,0xffe6,0xffe6,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0,0,0,0,0,0,0,0,0, -0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xff07,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0x1a09,0x1a0b,0x1a0d,0x1a0f, -0x1a12,0x1802,0x1a14,0x1a16,0x1a18,0x1a1a,0x1804,0x1a1c,0x1a1e,0x1a20,0x1806,0x1a23,0x1a25,0x1a27,0x1a29,0x1a2c, -0x1a2e,0x1a30,0x1a32,0x1a35,0x1a37,0x1a39,0x1a3b,0x187b,0x1a3d,0x1a40,0x1a42,0x1a44,0x1a46,0x1a48,0x1a4a,0x1a4c, -0x1a4e,0x1885,0x1808,0x180a,0x1887,0x1a50,0x1a52,0x1688,0x1a54,0x180c,0x1a56,0x1a58,0x1a5a,0x1a5c,0x1a5c,0x1a5c, -0x1a5e,0x1a61,0x1a63,0x1a65,0x1a67,0x1a6a,0x1a6c,0x1a6e,0x1a70,0x1a72,0x1a74,0x1a76,0x1a78,0x1a7a,0x1a7c,0x1a7e, -0x1a80,0x1a82,0x1a82,0x188b,0x1a84,0x1a86,0x1a88,0x1a8a,0x1810,0x1a8c,0x1a8e,0x1a90,0x17ba,0x1a92,0x1a94,0x1a96, -0x1a98,0x1a9a,0x1a9c,0x1a9e,0x1aa0,0x1aa2,0x1aa5,0x1aa7,0x1aa9,0x1aab,0x1aad,0x1aaf,0x1ab1,0x1ab4,0x1ab7,0x1ab9, -0x1abb,0x1abd,0x1abf,0x1ac1,0x1ac3,0x1ac5,0x1ac7,0x1ac7,0x1ac9,0x1acc,0x1ace,0x1680,0x1ad0,0x1ad2,0x1ad5,0x1ad7, -0x1ad9,0x1adb,0x1add,0x1adf,0x181a,0x1ae1,0x1ae3,0x1ae5,0x1ae8,0x1aea,0x1aed,0x1aef,0x1af1,0x1af3,0x1af5,0x1af7, -0x1af9,0x1afb,0x1afd,0x1aff,0x1b01,0x1b03,0x1b06,0x1b08,0x1b0a,0x1b0c,0x1614,0x1b0e,0x1b11,0x1b13,0x1b13,0x1b16, -0x1b18,0x1b18,0x1b1a,0x1b1c,0x1b1f,0x1b22,0x1b24,0x1b26,0x1b28,0x1b2a,0x1b2c,0x1b2e,0x1b30,0x1b32,0x1b34,0x181c, -0x1b36,0x1b39,0x1b3b,0x1b3d,0x18a3,0x1b3d,0x1b3f,0x1820,0x1b41,0x1b43,0x1b45,0x1b47,0x1822,0x15de,0x1b49,0x1b4b, -0x1b4d,0x1b4f,0x1b51,0x1b53,0x1b55,0x1b58,0x1b5a,0x1b5c,0x1b5e,0x1b60,0x1b62,0x1b65,0x1b67,0x1b69,0x1b6b,0x1b6d, -0x1b6f,0x1b71,0x1b73,0x1b75,0x1824,0x1b77,0x1b79,0x1b7c,0x1b7e,0x1b80,0x1b82,0x1828,0x1b84,0x1b86,0x1b88,0x1b8a, -0x1b8c,0x1b8e,0x1b90,0x1b92,0x1616,0x18b3,0x1b94,0x1b96,0x1b98,0x1b9a,0x1b9d,0x1b9f,0x1ba1,0x1ba3,0x182a,0x1ba5, -0x1ba8,0x1baa,0x1bac,0x190c,0x1bae,0x1bb0,0x1bb2,0x1bb4,0x1bb6,0x1bb9,0x1bbb,0x1bbd,0x1bbf,0x1bc2,0x1bc4,0x1bc6, -0x1bc8,0x16a2,0x1bca,0x1bcc,0x1bcf,0x1bd2,0x1bd5,0x1bd7,0x1bda,0x1bdc,0x1bde,0x1be0,0x1be2,0x182c,0x1750,0x1be4, -0x1be6,0x1be8,0x1bea,0x1bed,0x1bef,0x1bf1,0x1bf3,0x18bb,0x1bf5,0x1bf7,0x1bfa,0x1bfc,0x1bfe,0x1c01,0x1c04,0x1c06, -0x18bd,0x1c08,0x1c0a,0x1c0c,0x1c0e,0x1c10,0x1c12,0x1c14,0x1c17,0x1c19,0x1c1c,0x1c1e,0x1c21,0x18c1,0x1c23,0x1c25, -0x1c28,0x1c2a,0x1c2c,0x1c2f,0x1c32,0x1c34,0x1c36,0x1c38,0x1c3a,0x1c3a,0x1c3c,0x1c3e,0x18c5,0x1c40,0x1c42,0x1c44, -0x1c46,0x1c48,0x1c4b,0x1c4d,0x1686,0x1c50,0x1c53,0x1c55,0x1c58,0x1c5b,0x1c5e,0x1c60,0x18d1,0x1c62,0x1c65,0x1c68, -0x1c6b,0x1c6e,0x1c70,0x1c70,0x18d3,0x1910,0x1c72,0x1c74,0x1c76,0x1c78,0x1c7b,0x163a,0x18d7,0x1c7d,0x1c7f,0x1842, -0x1c82,0x1c85,0x17e6,0x1c88,0x1c8a,0x184a,0x1c8c,0x1c8e,0x1c90,0x1c93,0x1c93,0x1c96,0x1c98,0x1c9a,0x1c9d,0x1c9f, -0x1ca1,0x1ca3,0x1ca6,0x1ca8,0x1caa,0x1cac,0x1cae,0x1cb0,0x1cb3,0x1cb5,0x1cb7,0x1cb9,0x1cbb,0x1cbd,0x1cbf,0x1cc2, -0x1cc5,0x1cc7,0x1cca,0x1ccc,0x1ccf,0x1cd1,0x1856,0x1cd3,0x1cd6,0x1cd9,0x1cdb,0x1cde,0x1ce0,0x1ce3,0x1ce5,0x1ce7, -0x1ce9,0x1ceb,0x1ced,0x1cef,0x1cf2,0x1cf5,0x1cf8,0x1b16,0x1cfb,0x1cfd,0x1cff,0x1d01,0x1d03,0x1d05,0x1d07,0x1d09, -0x1d0b,0x1d0d,0x1d0f,0x1d11,0x16aa,0x1d14,0x1d16,0x1d18,0x1d1a,0x1d1c,0x1d1e,0x185c,0x1d20,0x1d22,0x1d24,0x1d26, -0x1d28,0x1d2b,0x1d2e,0x1d31,0x1d33,0x1d35,0x1d37,0x1d39,0x1d3c,0x1d3e,0x1d41,0x1d43,0x1d45,0x1d48,0x1d4b,0x1d4d, -0x1630,0x1d4f,0x1d51,0x1d53,0x1d55,0x1d57,0x1d59,0x18e5,0x1d5b,0x1d5d,0x1d5f,0x1d61,0x1d63,0x1d65,0x1d67,0x1d69, -0x1d6b,0x1d6d,0x1d70,0x1d72,0x1d74,0x1d76,0x1d78,0x1d7a,0x1d7d,0x1d80,0x1d82,0x1d84,0x18ef,0x18f1,0x1d86,0x1d88, -0x1d8b,0x1d8d,0x1d8f,0x1d91,0x1d93,0x1d96,0x1d99,0x1d9b,0x1d9d,0x1d9f,0x1da2,0x18f3,0x1da4,0x1da7,0x1daa,0x1dac, -0x1dae,0x1db0,0x1db3,0x1db5,0x1db7,0x1db9,0x1dbb,0x1dbd,0x1dbf,0x1dc1,0x1dc4,0x1dc6,0x1dc8,0x1dca,0x1dcd,0x1dcf, -0x1dd1,0x1dd3,0x1dd5,0x1dd8,0x1ddb,0x1ddd,0x1ddf,0x1de1,0x1de4,0x1de6,0x18ff,0x18ff,0x1de9,0x1deb,0x1dee,0x1df0, -0x1df2,0x1df4,0x1df6,0x1df8,0x1dfa,0x1dfc,0x1901,0x1dff,0x1e01,0x1e03,0x1e05,0x1e07,0x1e09,0x1e0c,0x1e0e,0x1e11, -0x1e14,0x1e17,0x1e19,0x1e1b,0x1e1d,0x1e1f,0x1e21,0x1e23,0x1e25,0x1e27,0,0,1,1,1,1, -1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0xff00,0xff00,0xff00, -0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, -0xff00,0xff00,0,0,0,0,0,0,0,0,0,0,0xff00,0xff00,0xff00,0xff00, -0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, -0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e, -0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e, -0x56e,0x56e,0x56e,0x56e,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0x1e29,0,0x1e29,0,0x1e29,0x1e29,0x1e29,0x1e29,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0x1e29,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0x1e29,0,0,0,0, -0x1e29,0,0,0,0x1e29,0,0x1e29,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0x1e27,0,0,0,0,0 +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,4,8,0xc,1, +1,0x10,0x50,0x5c,0x70,0x88,0xcc,0xd0,0xec,0x108,0x144,0x148,0x15c,0x174,0x180,0x1a4, +0x1e4,1,0x1ec,0x20c,0x228,0x244,0x290,0x298,0x2b0,0x2b8,0x2dc,1,1,1,1,1, +1,0x2f4,0x334,0x340,0x354,0x36c,0x3b0,0x3b4,0x3d0,0x3f0,0x428,0x430,0x444,0x45c,0x468,0x48c, +0x4cc,1,0x4d4,0x4f4,0x510,0x530,0x57c,0x584,0x5a0,0x5a8,0x5d0,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +0x5e8,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,0x1284,0x128a,0xade,0x1290,0xaf4,0xafe,0x5f4,0xb08, +0x1296,0x129c,0xb12,0x12a2,0x12a8,0x12ae,0x12b4,0xb28,1,0x12ba,0x12c0,0x12c6,0xb32,0xb48,0xb5a,1, +0x5fc,0x12cc,0x12d2,0x12d8,0xb64,0x12de,1,1,0x12e4,0x12ea,0xb7a,0x12f0,0xb90,0xb9a,0x600,0xba4, +0x12f6,0x12fc,0xbae,0x1302,0x1308,0x130e,0x1314,0xbc4,1,0x131a,0x1320,0x1326,0xbce,0xbe4,0xbf6,1, +0x608,0x132c,0x1332,0x1338,0xc00,0x133e,1,0x1344,0x134a,0x1350,0xc16,0xc2c,0x1357,0x135d,0x1362,0x1368, +0x136e,0x1374,0x137a,0x1380,0x1386,0x138c,0x1392,0x1398,1,1,0xc42,0xc50,0x139e,0x13a4,0x13aa,0x13b0, +0x13b7,0x13bd,0x13c2,0x13c8,0x13ce,0x13d4,0x13da,0x13e0,0x13e6,0x13ec,0x13f3,0x13f9,0x13fe,0x1404,1,1, +0x140a,0x1410,0x1416,0x141c,0x1422,0x1428,0x142f,0x1435,0x143a,1,1,1,0x1441,0x1447,0x144d,0x1453, +1,0x1458,0x145e,0x1465,0x146b,0x1470,0x1476,1,1,1,1,0x147c,0x1482,0x1489,0x148f,0x1494, +0x149a,1,1,1,0xc5e,0xc6c,0x14a0,0x14a6,0x14ac,0x14b2,1,1,0x14b8,0x14be,0x14c5,0x14cb, +0x14d0,0x14d6,0xc7a,0xc84,0x14dc,0x14e2,0x14e9,0x14ef,0xc8e,0xc98,0x14f5,0x14fb,0x1500,0x1506,1,1, +0xca2,0xcac,0xcb6,0xcc0,0x150c,0x1512,0x1518,0x151e,0x1524,0x152a,0x1531,0x1537,0x153c,0x1542,0x1548,0x154e, +0x1554,0x155a,0x1560,0x1566,0x156c,0x1572,0x1578,0x60c,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,0xcca,0xce4,1,1,1,1,1,1, +1,1,1,1,1,1,1,0xcfe,0xd18,1,1,1,1,1,1,0x610, +1,1,1,1,1,1,1,1,1,1,1,1,1,0x157e,0x1584,0x158a, +0x1590,0x1596,0x159c,0x15a2,0x15a8,0x15b0,0x15ba,0x15c4,0x15ce,0x15d8,0x15e2,0x15ec,0x15f6,1,0x1600,0x160a, +0x1614,0x161e,0x1627,0x162d,1,1,0x1632,0x1638,0x163e,0x1644,0xd32,0xd3c,0x164d,0x1657,0x165f,0x1665, +0x166b,1,1,1,0x1670,0x1676,1,1,0x167c,0x1682,0x168a,0x1694,0x169d,0x16a3,0x16a9,0x16af, +0x16b4,0x16ba,0x16c0,0x16c6,0x16cc,0x16d2,0x16d8,0x16de,0x16e4,0x16ea,0x16f0,0x16f6,0x16fc,0x1702,0x1708,0x170e, +0x1714,0x171a,0x1720,0x1726,0x172c,0x1732,0x1738,0x173e,0x1744,0x174a,0x1750,0x1756,1,1,0x175c,0x1762, +1,1,1,1,1,1,0xd46,0xd50,0xd5a,0xd64,0x176a,0x1774,0x177e,0x1788,0xd6e,0xd78, +0x1792,0x179c,0x17a4,0x17aa,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,0x614,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,0xfdcc,0xfdcc,0xfdcc,0xfdcc,0xfdcc,0xffcc,0xfdcc,0xfdcc,0xfdcc,0xfdcc,0xfdcc,0xfdcc, +0xfdcc,0xffcc,0xffcc,0xfdcc,0xffcc,0xfdcc,0xffcc,0xfdcc,0xfdcc,0xffd0,0xffb8,0xffb8,0xffb8,0xffb8,0xffd0,0xfdb0, +0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xff94,0xff94,0xfdb8,0xfdb8,0xfdb8,0xfdb8,0xfd94,0xfd94,0xffb8,0xffb8,0xffb8, +0xffb8,0xfdb8,0xfdb8,0xffb8,0xfdb8,0xfdb8,0xffb8,0xffb8,0xfe02,0xfe02,0xfe02,0xfe02,0xfc02,0xffb8,0xffb8,0xffb8, +0xffb8,0xffcc,0xffcc,0xffcc,0x3c26,0x3c2c,0xfdcc,0x3c32,0x3c38,0xfde0,0xffcc,0xffb8,0xffb8,0xffb8,0xffcc,0xffcc, +0xffcc,0xffb8,0xffb8,1,0xffcc,0xffcc,0xffcc,0xffb8,0xffb8,0xffb8,0xffb8,0xffcc,0xffd0,0xffb8,0xffb8,0xffcc, +0xffd2,0xffd4,0xffd4,0xffd2,0xffd4,0xffd4,0xffd2,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc, +0xffcc,0xffcc,0xffcc,0xffcc,1,1,1,1,0x29d1,1,1,1,1,1,1,1, +1,1,0x29d5,1,1,1,1,1,1,0x17b1,0x17b7,0x29d9,0x17bd,0x17c3,0x17c9,1, +0x17cf,1,0x17d5,0x17db,0x17e3,0x618,1,1,1,0x634,1,0x644,1,0x658,1,1, +1,1,1,0x674,1,0x684,1,1,1,0x688,1,1,1,0x6a0,0x17eb,0x17f1, +0xd82,0x17f7,0xd8c,0x17fd,0x1805,0x6b4,1,1,1,0x6d4,1,0x6e4,1,0x6fc,1,1, +1,1,1,0x71c,1,0x72c,1,1,1,0x734,1,1,1,0x754,0xd96,0xda8, +0x180d,0x1813,0xdba,1,1,1,0x76c,0x1819,0x181f,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,0x1825,0x182b,1,0x1831,1,1,0x774,0x1837,1,1,1,1, +0x183d,0x1843,0x1849,1,0x778,1,1,0x780,1,0x784,0x790,0x798,0x79c,0x184f,0x7ac,1, +1,1,0x7b0,1,1,1,1,0x7b4,1,1,1,0x7c4,1,1,1,0x7c8, +1,0x7cc,1,1,0x7d0,1,1,0x7d8,1,0x7dc,0x7e8,0x7f0,0x7f4,0x1855,0x804,1, +1,1,0x808,1,1,1,1,0x80c,1,1,1,0x81c,1,1,1,0x820, +1,0x824,1,1,0x185b,0x1861,1,0x1867,1,1,0x828,0x186d,1,1,1,1, +0x1873,0x1879,0x187f,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,0x82c,0x830,0x1885,0x188b,1,1,1,1, +1,1,1,1,1,1,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,0x1891,0x1897,1,1,1,1,1,1,1,1,1, +1,1,1,1,0x189d,0x18a3,0x18a9,0x18af,1,1,0x18b5,0x18bb,0x834,0x838,0x18c1,0x18c7, +0x18cd,0x18d3,0x18d9,0x18df,1,1,0x18e5,0x18eb,0x18f1,0x18f7,0x18fd,0x1903,0x83c,0x840,0x1909,0x190f, +0x1915,0x191b,0x1921,0x1927,0x192d,0x1933,0x1939,0x193f,0x1945,0x194b,1,1,0x1951,0x1957,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,0xffb8,0xffcc,0xffcc,0xffcc,0xffcc,0xffb8,0xffcc,0xffcc,0xffcc,0xffbc,0xffb8,0xffcc,0xffcc,0xffcc,0xffcc, +0xffcc,0xffcc,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xffcc,0xffcc,0xffb8,0xffcc,0xffcc,0xffbc,0xffc8,0xffcc, +0xfe14,0xfe16,0xfe18,0xfe1a,0xfe1c,0xfe1e,0xfe20,0xfe22,0xfe24,0xfe26,0xfe26,0xfe28,0xfe2a,0xfe2c,1,0xfe2e, +1,0xfe30,0xfe32,1,0xffcc,0xffb8,1,0xfe24,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xfe3c,0xfe3e,0xfe40,1,1,1,1,1, +1,1,0x195c,0x1962,0x1969,0x196f,0x1975,0x844,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +0x850,1,0x854,0xfe36,0xfe38,0xfe3a,0xfe3c,0xfe3e,0xfe40,0xfe42,0xfe44,0xfdcc,0xfdcc,0xfdb8,0xffb8,0xffcc, +0xffcc,0xffcc,0xffcc,0xffcc,0xffb8,0xffcc,0xffcc,0xffb8,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,0xfe46,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,0x197b,0x858,0x1981,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,0x85c,0x1987,1,0x860,0xffcc,0xffcc, +0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffb8,0xffcc,1,1,0xffcc, +0xffcc,1,0xffb8,0xffcc,0xffcc,0xffb8,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,0xfe48,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,0xffcc,0xffb8,0xffcc,0xffcc,0xffb8,0xffcc,0xffcc,0xffb8, +0xffb8,0xffb8,0xffcc,0xffb8,0xffb8,0xffcc,0xffb8,0xffcc,0xffcc,0xffcc,0xffb8,0xffcc,0xffb8,0xffcc,0xffb8,0xffcc, +0xffb8,0xffcc,0xffcc,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc, +0xffcc,0xffcc,0xffb8,0xffcc,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,0xffcc,0xffcc,0xffcc,0xffcc,1,0xffcc, +0xffcc,0xffcc,0xffcc,0xffcc,1,0xffcc,0xffcc,0xffcc,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,0xffb8,0xffb8,0xffb8,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,0xffb8, +0xffcc,0xffcc,0xffb8,0xffcc,0xffcc,0xffb8,0xffcc,0xffcc,0xffcc,0xffb8,0xffb8,0xffb8,0xfe36,0xfe38,0xfe3a,0xffcc, +0xffcc,0xffcc,0xffb8,0xffcc,0xffcc,0xffb8,0xffb8,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,1,1,1, +1,1,1,1,0x864,0x198d,1,1,1,1,1,1,0x868,0x1993,1,0x86c, +0x1999,1,1,1,1,1,1,1,0xfc0e,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,0xfe12,1,1,1,0xffcc,0xffb8,0xffcc, +0xffcc,1,1,1,0x29dd,0x29e3,0x29e9,0x29ef,0x29f5,0x29fb,0x2a01,0x2a07,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,0xfe0e,1,0xfc00,1,1,1,1,1, +1,1,1,0x870,1,1,1,0x199f,0x19a5,0xfe12,1,1,1,1,1,1, +1,1,1,0xfc00,1,1,1,1,0x2a0d,0x2a13,1,0x2a19,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0x2a1f, +1,1,0x2a25,1,1,1,1,1,0xfe0e,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,0xfe12,1,1,1,1,1,1, +1,1,1,1,1,0x2a2b,0x2a31,0x2a37,1,1,0x2a3d,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,0xfe0e,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,0xfe12,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0x878, +0x19ab,1,1,0x19b1,0x19b7,0xfe12,1,1,1,1,1,1,1,1,0xfc00,0xfc00, +1,1,1,1,0x2a43,0x2a49,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,0x884,1,0x19bd,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,0xfc00,1, +1,1,1,1,1,1,0x888,0x890,1,1,0x19c3,0x19c9,0x19cf,0xfe12,1,1, +1,1,1,1,1,1,1,0xfc00,1,1,1,1,1,1,1,1, +1,1,0x894,1,0x19d5,1,1,1,1,0xfe12,1,1,1,1,1,1, +1,0xfea8,0xfcb6,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +0xfe0e,1,1,0x898,0x19db,1,0xfc00,1,1,1,0x89c,0x19e1,0x19e7,1,0xdc4,0x19ef, +1,0xfe12,1,1,1,1,1,1,1,0xfc00,0xfc00,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,0xfe12,0xfe12,1,0xfc00,1,1,1,1,1, +1,1,0x8a8,0x8b0,1,1,0x19f7,0x19fd,0x1a03,0xfe12,1,1,1,1,1,1, +1,1,1,0xfc00,1,1,1,1,1,1,1,1,1,1,0xfc12,1, +1,1,1,0xfc00,1,1,1,1,1,1,1,1,1,0x8b4,0x1a09,1, +0xdce,0x1a11,0x1a19,0xfc00,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,0xfece,0xfece,0xfe12,1, +1,1,1,1,1,1,1,1,0xfed6,0xfed6,0xfed6,0xfed6,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,0xfeec,0xfeec,1,1,1,1,1,1,1,1,1,1, +0xfef4,0xfef4,0xfef4,0xfef4,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,0xffb8,0xffb8,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,0xffb8,1,0xffb8,1,0xffb0,1,1,1,1,1,1, +1,1,1,0x2a4f,1,1,1,1,1,1,1,1,1,0x2a55,1,1, +1,1,0x2a5b,1,1,1,1,0x2a61,1,1,1,1,0x2a67,1,1,1, +1,1,1,1,1,1,1,1,1,0x2a6d,1,1,1,1,1,1, +1,0xff02,0xff04,0x3c40,0xff08,0x3c48,0x2a73,1,0x2a79,1,0xff04,0xff04,0xff04,0xff04,1,1, +0xff04,0x3c50,0xffcc,0xffcc,0xfe12,1,0xffcc,0xffcc,1,1,1,1,1,1,1,1, +1,1,1,0x2a7f,1,1,1,1,1,1,1,1,1,0x2a85,1,1, +1,1,0x2a8b,1,1,1,1,0x2a91,1,1,1,1,0x2a97,1,1,1, +1,1,1,1,1,1,1,1,1,0x2a9d,1,1,1,1,1,1, +1,1,0xffb8,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,0x8c0,0x1a1f,1, +1,1,1,1,1,1,0xfc00,1,1,1,1,1,1,1,1,0xfe0e, +1,0xfe12,0xfe12,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,0xffb8,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,0xffcc,0xffcc,0xffcc,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,0xfe12,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,0xfe12,1, +1,1,1,1,1,1,1,1,1,0xffcc,1,1,1,1,1,1, +1,1,1,1,1,0xffc8,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,0xffbc,0xffcc,0xffb8,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,0xffcc,0xffb8,1,1,1, +1,1,1,1,0xfe12,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc, +0xffcc,1,1,0xffb8,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xffcc, +0xffcc,0xffb8,1,1,1,1,1,1,1,0x8c4,0x1a25,0x8c8,0x1a2b,0x8cc,0x1a31,0x8d0, +0x1a37,0x8d4,0x1a3d,1,1,0x8d8,0x1a43,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,0xfe0e,0xfc00,1,1, +1,1,0x8dc,0x1a49,0x8e0,0x1a4f,0x8e4,0x8e8,0x1a55,0x1a5b,0x8ec,0x1a61,0xfe12,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,0xffcc,0xffb8,0xffcc,0xffcc,0xffcc, +0xffcc,0xffcc,0xffcc,0xffcc,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,0xfe12,0xfe12,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,0xfe0e,1,1,1,1,1, +1,1,1,1,1,1,0xfe12,0xfe12,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0xfe0e, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +0xffcc,0xffcc,0xffcc,1,0xfe02,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xffcc,0xffcc,0xffb8,0xffb8,0xffb8,0xffb8, +0xffcc,1,0xfe02,0xfe02,0xfe02,0xfe02,0xfe02,0xfe02,0xfe02,1,1,1,1,0xffb8,1,1, +1,1,1,1,0xffcc,1,1,1,0xffcc,0xffcc,1,1,1,1,1,1, +0xffcc,0xffcc,0xffb8,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffb8,0xffcc,0xffcc,0xffd4,0xffac,0xffb8, +0xff94,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc, +0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffd0,0xffc8,0xffc8,0xffb8,1,0xffcc, +0xffd2,0xffb8,0xffcc,0xffb8,0x1a66,0x1a6c,0x1a72,0x1a78,0x1a7f,0x1a85,0x1a8b,0x1a91,0x1a99,0x1aa3,0x1aaa,0x1ab0, +0x1ab6,0x1abc,0x1ac2,0x1ac8,0x1acf,0x1ad5,0x1ada,0x1ae0,0x1ae8,0x1af2,0x1afc,0x1b06,0x1b0e,0x1b14,0x1b1a,0x1b20, +0x1b29,0x1b33,0x1b3b,0x1b41,0x1b46,0x1b4c,0x1b52,0x1b58,0x1b5e,0x1b64,0x1b6a,0x1b70,0x1b77,0x1b7d,0x1b82,0x1b88, +0x1b8e,0x1b94,0x1b9c,0x1ba6,0x1bae,0x1bb4,0x1bba,0x1bc0,0x1bc6,0x1bcc,0xdd8,0xde2,0x1bd4,0x1bde,0x1be6,0x1bec, +0x1bf2,0x1bf8,0x1bfe,0x1c04,0x1c0a,0x1c10,0x1c17,0x1c1d,0x1c22,0x1c28,0x1c2e,0x1c34,0x1c3a,0x1c40,0x1c46,0x1c4c, +0x1c54,0x1c5e,0x1c68,0x1c72,0x1c7c,0x1c86,0x1c90,0x1c9a,0x1ca3,0x1ca9,0x1caf,0x1cb5,0x1cba,0x1cc0,0xdec,0xdf6, +0x1cc8,0x1cd2,0x1cda,0x1ce0,0x1ce6,0x1cec,0xe00,0xe0a,0x1cf4,0x1cfe,0x1d08,0x1d12,0x1d1c,0x1d26,0x1d2e,0x1d34, +0x1d3a,0x1d40,0x1d46,0x1d4c,0x1d52,0x1d58,0x1d5e,0x1d64,0x1d6a,0x1d70,0x1d76,0x1d7c,0x1d84,0x1d8e,0x1d98,0x1da2, +0x1daa,0x1db0,0x1db7,0x1dbd,0x1dc2,0x1dc8,0x1dce,0x1dd4,0x1dda,0x1de0,0x1de6,0x1dec,0x1df3,0x1df9,0x1dff,0x1e05, +0x1e0b,0x1e11,0x1e16,0x1e1c,0x1e22,0x1e28,0x1e2f,0x1e35,0x1e3b,0x1e41,0x1e46,0x1e4c,0x1e52,0x1e58,1,0x1e5f, +1,1,1,1,0xe14,0xe22,0x1e64,0x1e6a,0x1e72,0x1e7c,0x1e86,0x1e90,0x1e9a,0x1ea4,0x1eae,0x1eb8, +0x1ec2,0x1ecc,0x1ed6,0x1ee0,0x1eea,0x1ef4,0x1efe,0x1f08,0x1f12,0x1f1c,0x1f26,0x1f30,0xe30,0xe3a,0x1f38,0x1f3e, +0x1f44,0x1f4a,0x1f52,0x1f5c,0x1f66,0x1f70,0x1f7a,0x1f84,0x1f8e,0x1f98,0x1fa2,0x1fac,0x1fb4,0x1fba,0x1fc0,0x1fc6, +0xe44,0xe4e,0x1fcc,0x1fd2,0x1fda,0x1fe4,0x1fee,0x1ff8,0x2002,0x200c,0x2016,0x2020,0x202a,0x2034,0x203e,0x2048, +0x2052,0x205c,0x2066,0x2070,0x207a,0x2084,0x208e,0x2098,0x20a0,0x20a6,0x20ac,0x20b2,0x20ba,0x20c4,0x20ce,0x20d8, +0x20e2,0x20ec,0x20f6,0x2100,0x210a,0x2114,0x211c,0x2122,0x2129,0x212f,0x2134,0x213a,0x2140,0x2146,1,1, +1,1,1,1,0xe58,0xe6e,0xe86,0xe94,0xea2,0xeb0,0xebe,0xecc,0xed8,0xeee,0xf06,0xf14, +0xf22,0xf30,0xf3e,0xf4c,0xf58,0xf66,0x214f,0x2159,0x2163,0x216d,1,1,0xf74,0xf82,0x2177,0x2181, +0x218b,0x2195,1,1,0xf90,0xfa6,0xfbe,0xfcc,0xfda,0xfe8,0xff6,0x1004,0x1010,0x1026,0x103e,0x104c, +0x105a,0x1068,0x1076,0x1084,0x1090,0x10a2,0x219f,0x21a9,0x21b3,0x21bd,0x21c7,0x21d1,0x10b4,0x10c6,0x21db,0x21e5, +0x21ef,0x21f9,0x2203,0x220d,0x10d8,0x10e6,0x2217,0x2221,0x222b,0x2235,1,1,0x10f4,0x1102,0x223f,0x2249, +0x2253,0x225d,1,1,0x1110,0x1122,0x2267,0x2271,0x227b,0x2285,0x228f,0x2299,1,0x1134,1,0x22a3, +1,0x22ad,1,0x22b7,0x1146,0x115c,0x1174,0x1182,0x1190,0x119e,0x11ac,0x11ba,0x11c6,0x11dc,0x11f4,0x1202, +0x1210,0x121e,0x122c,0x123a,0x1246,0x3b8e,0x22bf,0x3b97,0x1250,0x3b9e,0x22c5,0x3ba7,0x22cb,0x3baf,0x22d1,0x3bb7, +0x125a,0x3bbe,1,1,0x22d8,0x22e2,0x22f1,0x2301,0x2311,0x2321,0x2331,0x2341,0x234c,0x2356,0x2365,0x2375, +0x2385,0x2395,0x23a5,0x23b5,0x23c0,0x23ca,0x23d9,0x23e9,0x23f9,0x2409,0x2419,0x2429,0x2434,0x243e,0x244d,0x245d, +0x246d,0x247d,0x248d,0x249d,0x24a8,0x24b2,0x24c1,0x24d1,0x24e1,0x24f1,0x2501,0x2511,0x251c,0x2526,0x2535,0x2545, +0x2555,0x2565,0x2575,0x2585,0x258f,0x2595,0x259d,0x25a4,0x25ad,1,0x1264,0x25b7,0x25bf,0x25c5,0x25cb,0x3bc7, +0x25d0,1,0x2aa2,0x8f0,1,0x25d7,0x25df,0x25e6,0x25ef,1,0x126e,0x25f9,0x2601,0x3bcf,0x2607,0x3bd7, +0x260c,0x2613,0x2619,0x261f,0x2625,0x262b,0x2633,0x3be1,1,1,0x263b,0x2643,0x264b,0x2651,0x2657,0x3beb, +1,0x265d,0x2663,0x2669,0x266f,0x2675,0x267d,0x3bf5,0x2685,0x268b,0x2691,0x2699,0x26a1,0x26a7,0x26ad,0x3bff, +0x26b3,0x26b9,0x3c07,0x2aa7,1,1,0x26c1,0x26c8,0x26d1,1,0x1278,0x26db,0x26e3,0x3c0f,0x26e9,0x3c17, +0x26ee,0x2aab,0x8fc,1,0xfa09,0xfa09,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,0xffcc,0xffcc,0xfe02,0xfe02,0xffcc,0xffcc,0xffcc,0xffcc,0xfe02,0xfe02,0xfe02,0xffcc, +0xffcc,1,1,1,1,0xffcc,1,1,1,0xfe02,0xfe02,0xffcc,0xffb8,0xffcc,0xfe02,0xfe02, +0xffb8,0xffb8,0xffb8,0xffb8,0xffcc,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,0x2aae,1,1,1,0x2ab2,0x3c1e,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +0x908,1,0x90c,1,0x910,1,1,1,1,1,0x26f5,0x26fb,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,0x2701,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,0x2707,0x270d,0x2713, +0x914,1,0x918,1,0x91c,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,0x920,0x2719,1,1,1,0x924,0x271f,1,0x928,0x2725,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,0x92c,0x272b,0x930,0x2731,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,0x934,1,1,1, +1,0x2737,1,0x938,0x273d,0x93c,1,0x2743,0x940,0x2749,1,1,1,0x944,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +0x274f,0x948,0x2755,1,0x94c,0x950,1,1,1,1,1,1,1,0x275b,0x2761,0x2767, +0x276d,0x2773,0x954,0x958,0x2779,0x277f,0x95c,0x960,0x2785,0x278b,0x964,0x968,0x96c,0x970,1,1, +0x2791,0x2797,0x974,0x978,0x279d,0x27a3,0x97c,0x980,0x27a9,0x27af,1,1,1,1,1,1, +1,0x984,0x988,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,0x98c,1,1,1,1,1,0x990,0x994,1,0x998,0x27b5,0x27bb,0x27c1,0x27c7, +1,1,0x99c,0x9a0,0x9a4,0x9a8,1,1,1,1,1,1,1,1,1,1, +0x27cd,0x27d3,0x27d9,0x27df,1,1,1,1,1,1,0x27e5,0x27eb,0x27f1,0x27f7,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,0x2ab7,0x2abb,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +0x2abf,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,0xffcc,0xffcc,0xffcc,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,0xfe12,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc, +0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc, +0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,1,1,1,1,1,1,1, +1,1,0xffb4,0xffc8,0xffd0,0xffbc,0xffc0,0xffc0,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,0x9ac,1,1,1,1,0x9b0, +0x27fd,0x9b4,0x2803,0x9b8,0x2809,0x9bc,0x280f,0x9c0,0x2815,0x9c4,0x281b,0x9c8,0x2821,0x9cc,0x2827,0x9d0, +0x282d,0x9d4,0x2833,0x9d8,0x2839,0x9dc,0x283f,1,0x9e0,0x2845,0x9e4,0x284b,0x9e8,0x2851,1,1, +1,1,1,0x9ec,0x2857,0x285d,0x9f4,0x2863,0x2869,0x9fc,0x286f,0x2875,0xa04,0x287b,0x2881,0xa0c, +0x2887,0x288d,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,0x2893,1,1,1,1,0xfc10,0xfc10,1, +1,0xa14,0x2899,1,1,1,1,1,1,1,0xa18,1,1,1,1,0xa1c, +0x289f,0xa20,0x28a5,0xa24,0x28ab,0xa28,0x28b1,0xa2c,0x28b7,0xa30,0x28bd,0xa34,0x28c3,0xa38,0x28c9,0xa3c, +0x28cf,0xa40,0x28d5,0xa44,0x28db,0xa48,0x28e1,1,0xa4c,0x28e7,0xa50,0x28ed,0xa54,0x28f3,1,1, +1,1,1,0xa58,0x28f9,0x28ff,0xa60,0x2905,0x290b,0xa68,0x2911,0x2917,0xa70,0x291d,0x2923,0xa78, +0x2929,0x292f,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,0xa80,0xa84,0xa88,0xa8c,1,0x2935,1,1,0x293b,0x2941,0x2947,0x294d,1, +1,0xa90,0x2953,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,0xffcc,1,1,1,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc, +0xffcc,0xffcc,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,0xffcc,0xffcc,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,0xffcc,0xffcc,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,0xfe12,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +0xfe12,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,0xffcc,0xffcc,0xffcc,0xffcc, +0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0xffb8, +0xffb8,0xffb8,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,0xfe12,1,1,1,1,1,1,1,1, +1,1,1,1,0xfe12,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,0xffcc,1,0xffcc,0xffcc,0xffb8,1,1,0xffcc,0xffcc,1,1,1, +1,1,0xffcc,0xffcc,1,0xffcc,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,0xfe12,1,1,1,1,1,1,1,1,1, +0x2ac5,0x2ac9,0x2acd,0x2ad1,0x2ad5,0x2ad9,0x2add,0x2ae1,0x2ae1,0x2ae5,0x2ae9,0x2aed,0x2af1,0x2af5,0x2af9,0x2afd, +0x2b01,0x2b05,0x2b09,0x2b0d,0x2b11,0x2b15,0x2b19,0x2b1d,0x2b21,0x2b25,0x2b29,0x2b2d,0x2b31,0x2b35,0x2b39,0x2b3d, +0x2b41,0x2b45,0x2b49,0x2b4d,0x2b51,0x2b55,0x2b59,0x2b5d,0x2b61,0x2b65,0x2b69,0x2b6d,0x2b71,0x2b75,0x2b79,0x2b7d, +0x2b81,0x2b85,0x2b89,0x2b8d,0x2b91,0x2b95,0x2b99,0x2b9d,0x2ba1,0x2ba5,0x2ba9,0x2bad,0x2bb1,0x2bb5,0x2bb9,0x2bbd, +0x2bc1,0x2bc5,0x2bc9,0x2bcd,0x2bd1,0x2bd5,0x2bd9,0x2bdd,0x2be1,0x2be5,0x2be9,0x2bed,0x2bf1,0x2bf5,0x2bf9,0x2bfd, +0x2c01,0x2c05,0x2c09,0x2c0d,0x2c11,0x2c15,0x2c19,0x2c1d,0x2c21,0x2c25,0x2c29,0x2c2d,0x2b11,0x2c31,0x2c35,0x2c39, +0x2c3d,0x2c41,0x2c45,0x2c49,0x2c4d,0x2c51,0x2c55,0x2c59,0x2c5d,0x2c61,0x2c65,0x2c69,0x2c6d,0x2c71,0x2c75,0x2c79, +0x2c7d,0x2c81,0x2c85,0x2c89,0x2c8d,0x2c91,0x2c95,0x2c99,0x2c9d,0x2ca1,0x2ca5,0x2ca9,0x2cad,0x2cb1,0x2cb5,0x2cb9, +0x2cbd,0x2cc1,0x2cc5,0x2cc9,0x2ccd,0x2cd1,0x2cd5,0x2cd9,0x2cdd,0x2ce1,0x2ce5,0x2ce9,0x2ced,0x2cf1,0x2cf5,0x2cf9, +0x2cfd,0x2d01,0x2d05,0x2d09,0x2d0d,0x2d11,0x2d15,0x2d19,0x2d1d,0x2d21,0x2d25,0x2d29,0x2d2d,0x2d31,0x2d35,0x2d39, +0x2d3d,0x2c79,0x2d41,0x2d45,0x2d49,0x2d4d,0x2d51,0x2d55,0x2d59,0x2d5d,0x2c39,0x2d61,0x2d65,0x2d69,0x2d6d,0x2d71, +0x2d75,0x2d79,0x2d7d,0x2d81,0x2d85,0x2d89,0x2d8d,0x2d91,0x2d95,0x2d99,0x2d9d,0x2da1,0x2da5,0x2da9,0x2dad,0x2b11, +0x2db1,0x2db5,0x2db9,0x2dbd,0x2dc1,0x2dc5,0x2dc9,0x2dcd,0x2dd1,0x2dd5,0x2dd9,0x2ddd,0x2de1,0x2de5,0x2de9,0x2ded, +0x2df1,0x2df5,0x2df9,0x2dfd,0x2e01,0x2e05,0x2e09,0x2e0d,0x2e11,0x2e15,0x2e19,0x2c41,0x2e1d,0x2e21,0x2e25,0x2e29, +0x2e2d,0x2e31,0x2e35,0x2e39,0x2e3d,0x2e41,0x2e45,0x2e49,0x2e4d,0x2e51,0x2e55,0x2e59,0x2e5d,0x2e61,0x2e65,0x2e69, +0x2e6d,0x2e71,0x2e75,0x2e79,0x2e7d,0x2e81,0x2e85,0x2e89,0x2e8d,0x2e91,0x2e95,0x2e99,0x2e9d,0x2ea1,0x2ea5,0x2ea9, +0x2ead,0x2eb1,0x2eb5,0x2eb9,0x2ebd,0x2ec1,0x2ec5,0x2ec9,0x2ecd,0x2ed1,0x2ed5,0x2ed9,0x2edd,0x2ee1,1,1, +0x2ee5,1,0x2ee9,1,1,0x2eed,0x2ef1,0x2ef5,0x2ef9,0x2efd,0x2f01,0x2f05,0x2f09,0x2f0d,0x2f11,1, +0x2f15,1,0x2f19,1,1,0x2f1d,0x2f21,1,1,1,0x2f25,0x2f29,0x2f2d,0x2f31,0x2f35,0x2f39, +0x2f3d,0x2f41,0x2f45,0x2f49,0x2f4d,0x2f51,0x2f55,0x2f59,0x2f5d,0x2f61,0x2f65,0x2f69,0x2f6d,0x2f71,0x2f75,0x2f79, +0x2f7d,0x2f81,0x2f85,0x2f89,0x2f8d,0x2f91,0x2f95,0x2f99,0x2f9d,0x2fa1,0x2fa5,0x2fa9,0x2fad,0x2fb1,0x2fb5,0x2fb9, +0x2fbd,0x2fc1,0x2fc5,0x2fc9,0x2fcd,0x2fd1,0x2fd5,0x2d15,0x2fd9,0x2fdd,0x2fe1,0x2fe5,0x2fe9,0x2fed,0x2fed,0x2ff1, +0x2ff5,0x2ff9,0x2ffd,0x3001,0x3005,0x3009,0x300d,0x2f1d,0x3011,0x3015,0x3019,0x301d,0x3021,0x3027,1,1, +0x302b,0x302f,0x3033,0x3037,0x303b,0x303f,0x3043,0x3047,0x2f55,0x304b,0x304f,0x3053,0x2ee5,0x3057,0x305b,0x305f, +0x3063,0x3067,0x306b,0x306f,0x3073,0x3077,0x307b,0x307f,0x3083,0x2f79,0x3087,0x2f7d,0x308b,0x308f,0x3093,0x3097, +0x309b,0x2ee9,0x2b65,0x309f,0x30a3,0x30a7,0x2c7d,0x2dd9,0x30ab,0x30af,0x2f99,0x30b3,0x2f9d,0x30b7,0x30bb,0x30bf, +0x2ef1,0x30c3,0x30c7,0x30cb,0x30cf,0x30d3,0x2ef5,0x30d7,0x30db,0x30df,0x30e3,0x30e7,0x30eb,0x2fd5,0x30ef,0x30f3, +0x2d15,0x30f7,0x2fe5,0x30fb,0x30ff,0x3103,0x3107,0x310b,0x2ff9,0x310f,0x2f19,0x3113,0x2ffd,0x2c31,0x3117,0x3001, +0x311b,0x3009,0x311f,0x3123,0x3127,0x312b,0x312f,0x3011,0x2f09,0x3133,0x3015,0x3137,0x3019,0x313b,0x2ae1,0x313f, +0x3145,0x314b,0x3151,0x3155,0x3159,0x315d,0x3163,0x3169,0x316f,0x3173,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,0x3177,0xfe34,0x317d,1,1,1,1, +1,1,1,1,1,1,0x3183,0x3189,0x3191,0x319b,0x31a3,0x31a9,0x31af,0x31b5,0x31bb,0x31c1, +0x31c7,0x31cd,0x31d3,1,0x31d9,0x31df,0x31e5,0x31eb,0x31f1,1,0x31f7,1,0x31fd,0x3203,1,0x3209, +0x320f,1,0x3215,0x321b,0x3221,0x3227,0x322d,0x3233,0x3239,0x323f,0x3245,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,0xffcc,0xffcc,0xffcc,0xffcc, +0xffcc,0xffcc,0xffcc,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xffcc,0xffcc,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,0xffb8,1,1,0xffb8,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,0xffcc,0xffcc, +0xffcc,0xffcc,0xffcc,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,0xffb8,1,0xffcc,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,0xffcc,0xfe02,0xffb8,1, +1,1,1,0xfe12,1,1,1,1,1,0xffcc,0xffb8,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,0xa94,0x2959,0xa9a,0x2963,1,1,1,1,1,1,1, +1,0xaa0,1,1,1,1,1,0x296d,1,1,1,1,1,1,1,1, +1,1,1,1,1,0xfe12,0xfc0e,1,1,1,1,1,0xffcc,0xffcc,0xffcc,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0xfc00, +1,1,1,1,1,1,0x2977,0x2981,1,0xaa6,0xaac,0xfe12,0xfe12,1,1,1, +1,1,1,1,1,1,1,1,0xfe12,1,1,1,1,1,1,1, +1,1,0xfe0e,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,0xfe12,0xfe0e,1,1,1,1,1, +1,1,1,1,1,0xfe0e,0xfe12,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0xab2, +1,1,1,0x298b,0x2995,0xfe12,1,1,1,1,1,1,1,1,1,0xfc00, +1,1,1,1,1,1,1,1,1,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc, +0xffcc,1,1,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,1,1,1,1,1,1, +1,1,1,1,1,1,0xfe12,1,1,1,0xfe0e,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,0xfc00,1,1,1,1,1,1,1,1,0xabe,0xfc00,0x299f, +0x29a9,0xfc00,0x29b3,1,1,1,0xfe12,0xfe0e,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,0xfc00,1,1,1,1,1,1,1,1, +0xad0,0xad6,0x29bd,0x29c7,1,1,1,0xfe12,0xfe0e,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,0xfe12,0xfe0e,1,1,1,1, +1,1,1,1,1,1,1,0xfe12,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,0xfe12,1,1,1,1,1,1,1,1,0xfe0e,1,0xfe12,0xfe12,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,0xfe02,0xfe02,0xfe02,0xfe02,0xfe02,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,0xfe02,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,0x324b,0x3255,0x3269,0x3281,0x3299,0x32b1,0x32c9,0xffb0,0xffb0,0xfe02, +0xfe02,0xfe02,1,1,1,0xffc4,0xffb0,0xffb0,0xffb0,0xffb0,0xffb0,1,1,1,1,1, +1,1,1,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,1,1,0xffcc,0xffcc,0xffcc, +0xffcc,0xffcc,0xffb8,0xffb8,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,0xffcc,0xffcc,0xffcc,0xffcc,1,1, +1,1,1,1,1,1,1,1,1,1,1,0x32d7,0x32e1,0x32f5,0x330d,0x3325, +0x333d,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,0xffcc,0xffcc,0xffcc,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc, +0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc, +0xffcc,0xffcc,1,0xffcc,0xffcc,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,1,1,1,1,1,1,1,1,1, +0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xfe0e,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,0x334b,0x334f,0x3353,0x3357, +0x335d,0x2f3d,0x3361,0x3365,0x3369,0x336d,0x2f41,0x3371,0x3375,0x3379,0x2f45,0x337f,0x3383,0x3387,0x338b,0x3391, +0x3395,0x3399,0x339d,0x33a3,0x33a7,0x33ab,0x33af,0x302f,0x33b3,0x33b9,0x33bd,0x33c1,0x33c5,0x33c9,0x33cd,0x33d1, +0x33d5,0x3043,0x2f49,0x2f4d,0x3047,0x33d9,0x33dd,0x2c49,0x33e1,0x2f51,0x33e5,0x33e9,0x33ed,0x33f1,0x33f1,0x33f1, +0x33f5,0x33fb,0x33ff,0x3403,0x3407,0x340d,0x3411,0x3415,0x3419,0x341d,0x3421,0x3425,0x3429,0x342d,0x3431,0x3435, +0x3439,0x343d,0x343d,0x304f,0x3441,0x3445,0x3449,0x344d,0x2f59,0x3451,0x3455,0x3459,0x2ead,0x345d,0x3461,0x3465, +0x3469,0x346d,0x3471,0x3475,0x3479,0x347d,0x3483,0x3487,0x348b,0x348f,0x3493,0x3497,0x349b,0x34a1,0x34a7,0x34ab, +0x34af,0x34b3,0x34b7,0x34bb,0x34bf,0x34c3,0x34c7,0x34c7,0x34cb,0x34d1,0x34d5,0x2c39,0x34d9,0x34dd,0x34e3,0x34e7, +0x34eb,0x34ef,0x34f3,0x34f7,0x2f6d,0x34fb,0x34ff,0x3503,0x3509,0x350d,0x3513,0x3517,0x351b,0x351f,0x3523,0x3527, +0x352b,0x352f,0x3533,0x3537,0x353b,0x353f,0x3545,0x3549,0x354d,0x3551,0x2b61,0x3555,0x355b,0x355f,0x355f,0x3565, +0x3569,0x3569,0x356d,0x3571,0x3577,0x357d,0x3581,0x3585,0x3589,0x358d,0x3591,0x3595,0x3599,0x359d,0x35a1,0x2f71, +0x35a5,0x35ab,0x35af,0x35b3,0x307f,0x35b3,0x35b7,0x2f79,0x35bb,0x35bf,0x35c3,0x35c7,0x2f7d,0x2af5,0x35cb,0x35cf, +0x35d3,0x35d7,0x35db,0x35df,0x35e3,0x35e9,0x35ed,0x35f1,0x35f5,0x35f9,0x35fd,0x3603,0x3607,0x360b,0x360f,0x3613, +0x3617,0x361b,0x361f,0x3623,0x2f81,0x3627,0x362b,0x3631,0x3635,0x3639,0x363d,0x2f89,0x3641,0x3645,0x3649,0x364d, +0x3651,0x3655,0x3659,0x365d,0x2b65,0x309f,0x3661,0x3665,0x3669,0x366d,0x3673,0x3677,0x367b,0x367f,0x2f8d,0x3683, +0x3689,0x368d,0x3691,0x3151,0x3695,0x3699,0x369d,0x36a1,0x36a5,0x36ab,0x36af,0x36b3,0x36b7,0x36bd,0x36c1,0x36c5, +0x36c9,0x2c7d,0x36cd,0x36d1,0x36d7,0x36dd,0x36e3,0x36e7,0x36ed,0x36f1,0x36f5,0x36f9,0x36fd,0x2f91,0x2dd9,0x3701, +0x3705,0x3709,0x370d,0x3713,0x3717,0x371b,0x371f,0x30af,0x3723,0x3727,0x372d,0x3731,0x3735,0x373b,0x3741,0x3745, +0x30b3,0x3749,0x374d,0x3751,0x3755,0x3759,0x375d,0x3761,0x3767,0x376b,0x3771,0x3775,0x377b,0x30bb,0x377f,0x3783, +0x3789,0x378d,0x3791,0x3797,0x379d,0x37a1,0x37a5,0x37a9,0x37ad,0x37ad,0x37b1,0x37b5,0x30c3,0x37b9,0x37bd,0x37c1, +0x37c5,0x37c9,0x37cf,0x37d3,0x2c45,0x37d9,0x37df,0x37e3,0x37e9,0x37ef,0x37f5,0x37f9,0x30db,0x37fd,0x3803,0x3809, +0x380f,0x3815,0x3819,0x3819,0x30df,0x3159,0x381d,0x3821,0x3825,0x3829,0x382f,0x2bad,0x30e7,0x3833,0x3837,0x2fbd, +0x383d,0x3843,0x2f05,0x3849,0x384d,0x2fcd,0x3851,0x3855,0x3859,0x385f,0x385f,0x3865,0x3869,0x386d,0x3873,0x3877, +0x387b,0x387f,0x3885,0x3889,0x388d,0x3891,0x3895,0x3899,0x389f,0x38a3,0x38a7,0x38ab,0x38af,0x38b3,0x38b7,0x38bd, +0x38c3,0x38c7,0x38cd,0x38d1,0x38d7,0x38db,0x2fe5,0x38df,0x38e5,0x38eb,0x38ef,0x38f5,0x38f9,0x38ff,0x3903,0x3907, +0x390b,0x390f,0x3913,0x3917,0x391d,0x3923,0x3929,0x3565,0x392f,0x3933,0x3937,0x393b,0x393f,0x3943,0x3947,0x394b, +0x394f,0x3953,0x3957,0x395b,0x2c8d,0x3961,0x3965,0x3969,0x396d,0x3971,0x3975,0x2ff1,0x3979,0x397d,0x3981,0x3985, +0x3989,0x398f,0x3995,0x399b,0x399f,0x39a3,0x39a7,0x39ab,0x39b1,0x39b5,0x39bb,0x39bf,0x39c3,0x39c9,0x39cf,0x39d3, +0x2b99,0x39d7,0x39db,0x39df,0x39e3,0x39e7,0x39eb,0x3103,0x39ef,0x39f3,0x39f7,0x39fb,0x39ff,0x3a03,0x3a07,0x3a0b, +0x3a0f,0x3a13,0x3a19,0x3a1d,0x3a21,0x3a25,0x3a29,0x3a2d,0x3a33,0x3a39,0x3a3d,0x3a41,0x3117,0x311b,0x3a45,0x3a49, +0x3a4f,0x3a53,0x3a57,0x3a5b,0x3a5f,0x3a65,0x3a6b,0x3a6f,0x3a73,0x3a77,0x3a7d,0x311f,0x3a81,0x3a87,0x3a8d,0x3a91, +0x3a95,0x3a99,0x3a9f,0x3aa3,0x3aa7,0x3aab,0x3aaf,0x3ab3,0x3ab7,0x3abb,0x3ac1,0x3ac5,0x3ac9,0x3acd,0x3ad3,0x3ad7, +0x3adb,0x3adf,0x3ae3,0x3ae9,0x3aef,0x3af3,0x3af7,0x3afb,0x3b01,0x3b05,0x3137,0x3137,0x3b0b,0x3b0f,0x3b15,0x3b19, +0x3b1d,0x3b21,0x3b25,0x3b29,0x3b2d,0x3b31,0x313b,0x3b37,0x3b3b,0x3b3f,0x3b43,0x3b47,0x3b4b,0x3b51,0x3b55,0x3b5b, +0x3b61,0x3b67,0x3b6b,0x3b6f,0x3b73,0x3b77,0x3b7b,0x3b7f,0x3b83,0x3b87,1,1,2,2,2,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,0xfe00,0xfe00,0xfe00, +0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00, +0xfe00,0xfe00,1,1,1,1,1,1,1,1,1,1,0xfe00,0xfe00,0xfe00,0xfe00, +0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00, +0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,0xadc,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283, +0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283, +0xadc,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283, +0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,0x1283,0x1283,0x1283,0x1283,0xadc,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283, +0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283,0x1283, +0x1283,0x1283,0x1283,0x1283,0x3c54,1,0x3c54,1,0x3c54,0x3c54,0x3c54,0x3c54,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,0x3c54,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0x3c54, +1,1,1,1,0x3c54,1,1,1,0x3c54,1,0x3c54,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,0x3b87,1,1,1,1,1 }; -static const uint16_t norm2_nfc_data_extraData[7722]={ +static const uint16_t norm2_nfc_data_extraData[7724]={ 0xffff,0xffff,0x8670,0x44dc,0x8670,0x44c0,0x8670,0x44de,0x600,0x180,0x602,0x182,0x604,0x185,0x606,0x186, 0x608,0x200,0x60c,0x205,0x60e,0x44d,0x610,0x189,0x612,0x3d44,0x614,0x18b,0x618,0x39a,0x61e,0x400, 0x622,0x404,0x646,0x3d41,0x64a,0x3c00,0x8650,0x208,0x60e,0x3c04,0x646,0x3c08,0x8662,0x3c0c,0x602,0x20c, @@ -716,403 +720,403 @@ static const uint16_t norm2_nfc_data_extraData[7722]={ 0x6132,0x61a6,0xe134,0x61a8,0x6132,0x61ac,0xe134,0x61ae,0x6132,0x61b2,0xe134,0x61b4,0x6132,0x61b8,0xe134,0x61ba, 0xe132,0x61ee,0xe132,0x61f0,0xe132,0x61f2,0xe132,0x61f4,0xe132,0x61fc,0xb489,0x2e82,0x2134,0xb489,0x2e82,0x2138, 0xb489,0x2e82,0x2156,0xb489,0x49c2,0x225c,0xb489,0x49c2,0x225e,0x3489,0xcf82,0x2696,0xb489,0xd5c2,0x2698,0x348b, -0x2c02,0x2978,0x348b,0x2e82,0x2976,0xb48b,0x2f42,0x297c,0xb48b,0x6bc2,0x2b74,0xb48b,0x6bc2,0x2b76,0,0xe622, -0x41,0x302,0x600,0x3d4c,0x602,0x3d48,0x606,0x3d54,0x8612,0x3d50,0xe622,0x41,0x308,0x8608,0x3bc,0xe622, -0x41,0x30a,0x8602,0x3f4,0xca22,0x43,0x327,0x8602,0x3c10,0xe622,0x45,0x302,0x600,0x3d80,0x602,0x3d7c, -0x606,0x3d88,0x8612,0x3d84,0xe622,0x49,0x308,0x8602,0x3c5c,0xe622,0x4f,0x302,0x600,0x3da4,0x602,0x3da0, -0x606,0x3dac,0x8612,0x3da8,0xe622,0x4f,0x303,0x602,0x3c98,0x608,0x458,0x8610,0x3c9c,0xe622,0x4f,0x308, -0x8608,0x454,0xe622,0x55,0x308,0x600,0x3b6,0x602,0x3ae,0x608,0x3aa,0x8618,0x3b2,0xe622,0x61,0x302, -0x600,0x3d4e,0x602,0x3d4a,0x606,0x3d56,0x8612,0x3d52,0xe622,0x61,0x308,0x8608,0x3be,0xe622,0x61,0x30a, -0x8602,0x3f6,0xca22,0x63,0x327,0x8602,0x3c12,0xe622,0x65,0x302,0x600,0x3d82,0x602,0x3d7e,0x606,0x3d8a, -0x8612,0x3d86,0xe622,0x69,0x308,0x8602,0x3c5e,0xe622,0x6f,0x302,0x600,0x3da6,0x602,0x3da2,0x606,0x3dae, -0x8612,0x3daa,0xe622,0x6f,0x303,0x602,0x3c9a,0x608,0x45a,0x8610,0x3c9e,0xe622,0x6f,0x308,0x8608,0x456, -0xe622,0x75,0x308,0x600,0x3b8,0x602,0x3b0,0x608,0x3ac,0x8618,0x3b4,0xe622,0x41,0x306,0x600,0x3d60, -0x602,0x3d5c,0x606,0x3d68,0x8612,0x3d64,0xe622,0x61,0x306,0x600,0x3d62,0x602,0x3d5e,0x606,0x3d6a,0x8612, -0x3d66,0xe622,0x45,0x304,0x600,0x3c28,0x8602,0x3c2c,0xe622,0x65,0x304,0x600,0x3c2a,0x8602,0x3c2e,0xe622, -0x4f,0x304,0x600,0x3ca0,0x8602,0x3ca4,0xe622,0x6f,0x304,0x600,0x3ca2,0x8602,0x3ca6,0xe622,0x53,0x301, -0x860e,0x3cc8,0xe622,0x73,0x301,0x860e,0x3cca,0xe622,0x53,0x30c,0x860e,0x3ccc,0xe622,0x73,0x30c,0x860e, -0x3cce,0xe622,0x55,0x303,0x8602,0x3cf0,0xe622,0x75,0x303,0x8602,0x3cf2,0xe622,0x55,0x304,0x8610,0x3cf4, -0xe622,0x75,0x304,0x8610,0x3cf6,0xd822,0x4f,0x31b,0x600,0x3db8,0x602,0x3db4,0x606,0x3dc0,0x612,0x3dbc, -0x8646,0x3dc4,0xd822,0x6f,0x31b,0x600,0x3dba,0x602,0x3db6,0x606,0x3dc2,0x612,0x3dbe,0x8646,0x3dc6,0xd822, -0x55,0x31b,0x600,0x3dd4,0x602,0x3dd0,0x606,0x3ddc,0x612,0x3dd8,0x8646,0x3de0,0xd822,0x75,0x31b,0x600, -0x3dd6,0x602,0x3dd2,0x606,0x3dde,0x612,0x3dda,0x8646,0x3de2,0xca22,0x4f,0x328,0x8608,0x3d8,0xca22,0x6f, -0x328,0x8608,0x3da,0xe622,0x41,0x307,0x8608,0x3c0,0xe622,0x61,0x307,0x8608,0x3c2,0xca22,0x45,0x327, -0x860c,0x3c38,0xca22,0x65,0x327,0x860c,0x3c3a,0xe622,0x4f,0x307,0x8608,0x460,0xe622,0x6f,0x307,0x8608, -0x462,0xe622,0x3b1,0x301,0x868a,0x3f68,0xe622,0x3b7,0x301,0x868a,0x3f88,0xe622,0x3b9,0x308,0x600,0x3fa4, -0x602,0x720,0x8684,0x3fae,0xe622,0x3c5,0x308,0x600,0x3fc4,0x602,0x760,0x8684,0x3fce,0xe622,0x3c9,0x301, -0x868a,0x3fe8,0x22,0xcc6,0xcc2,0x99aa,0x1996,0x22,0xdd9,0xdcf,0x9b94,0x1bba,0xdc22,0x4c,0x323,0x8608, -0x3c70,0xdc22,0x6c,0x323,0x8608,0x3c72,0xdc22,0x52,0x323,0x8608,0x3cb8,0xdc22,0x72,0x323,0x8608,0x3cba, -0xdc22,0x53,0x323,0x860e,0x3cd0,0xdc22,0x73,0x323,0x860e,0x3cd2,0xdc22,0x41,0x323,0x604,0x3d58,0x860c, -0x3d6c,0xdc22,0x61,0x323,0x604,0x3d5a,0x860c,0x3d6e,0xdc22,0x45,0x323,0x8604,0x3d8c,0xdc22,0x65,0x323, -0x8604,0x3d8e,0xdc22,0x4f,0x323,0x8604,0x3db0,0xdc22,0x6f,0x323,0x8604,0x3db2,0xe622,0x3b1,0x313,0x600, -0x3e05,0x602,0x3e09,0x684,0x3e0d,0x868a,0x3f00,0xe622,0x3b1,0x314,0x600,0x3e07,0x602,0x3e0b,0x684,0x3e0f, -0x868a,0x3f02,0x1f00,0xe663,0x3b1,0x313,0x300,0x868a,0x3f04,0x1f01,0xe663,0x3b1,0x314,0x300,0x868a,0x3f06, -0x1f00,0xe663,0x3b1,0x313,0x301,0x868a,0x3f08,0x1f01,0xe663,0x3b1,0x314,0x301,0x868a,0x3f0a,0x1f00,0xe663, -0x3b1,0x313,0x342,0x868a,0x3f0c,0x1f01,0xe663,0x3b1,0x314,0x342,0x868a,0x3f0e,0xe622,0x391,0x313,0x600, -0x3e15,0x602,0x3e19,0x684,0x3e1d,0x868a,0x3f10,0xe622,0x391,0x314,0x600,0x3e17,0x602,0x3e1b,0x684,0x3e1f, -0x868a,0x3f12,0x1f08,0xe663,0x391,0x313,0x300,0x868a,0x3f14,0x1f09,0xe663,0x391,0x314,0x300,0x868a,0x3f16, -0x1f08,0xe663,0x391,0x313,0x301,0x868a,0x3f18,0x1f09,0xe663,0x391,0x314,0x301,0x868a,0x3f1a,0x1f08,0xe663, -0x391,0x313,0x342,0x868a,0x3f1c,0x1f09,0xe663,0x391,0x314,0x342,0x868a,0x3f1e,0xe622,0x3b5,0x313,0x600, -0x3e24,0x8602,0x3e28,0xe622,0x3b5,0x314,0x600,0x3e26,0x8602,0x3e2a,0xe622,0x395,0x313,0x600,0x3e34,0x8602, -0x3e38,0xe622,0x395,0x314,0x600,0x3e36,0x8602,0x3e3a,0xe622,0x3b7,0x313,0x600,0x3e45,0x602,0x3e49,0x684, -0x3e4d,0x868a,0x3f20,0xe622,0x3b7,0x314,0x600,0x3e47,0x602,0x3e4b,0x684,0x3e4f,0x868a,0x3f22,0x1f20,0xe663, -0x3b7,0x313,0x300,0x868a,0x3f24,0x1f21,0xe663,0x3b7,0x314,0x300,0x868a,0x3f26,0x1f20,0xe663,0x3b7,0x313, -0x301,0x868a,0x3f28,0x1f21,0xe663,0x3b7,0x314,0x301,0x868a,0x3f2a,0x1f20,0xe663,0x3b7,0x313,0x342,0x868a, -0x3f2c,0x1f21,0xe663,0x3b7,0x314,0x342,0x868a,0x3f2e,0xe622,0x397,0x313,0x600,0x3e55,0x602,0x3e59,0x684, -0x3e5d,0x868a,0x3f30,0xe622,0x397,0x314,0x600,0x3e57,0x602,0x3e5b,0x684,0x3e5f,0x868a,0x3f32,0x1f28,0xe663, -0x397,0x313,0x300,0x868a,0x3f34,0x1f29,0xe663,0x397,0x314,0x300,0x868a,0x3f36,0x1f28,0xe663,0x397,0x313, -0x301,0x868a,0x3f38,0x1f29,0xe663,0x397,0x314,0x301,0x868a,0x3f3a,0x1f28,0xe663,0x397,0x313,0x342,0x868a, -0x3f3c,0x1f29,0xe663,0x397,0x314,0x342,0x868a,0x3f3e,0xe622,0x3b9,0x313,0x600,0x3e64,0x602,0x3e68,0x8684, -0x3e6c,0xe622,0x3b9,0x314,0x600,0x3e66,0x602,0x3e6a,0x8684,0x3e6e,0xe622,0x399,0x313,0x600,0x3e74,0x602, -0x3e78,0x8684,0x3e7c,0xe622,0x399,0x314,0x600,0x3e76,0x602,0x3e7a,0x8684,0x3e7e,0xe622,0x3bf,0x313,0x600, -0x3e84,0x8602,0x3e88,0xe622,0x3bf,0x314,0x600,0x3e86,0x8602,0x3e8a,0xe622,0x39f,0x313,0x600,0x3e94,0x8602, -0x3e98,0xe622,0x39f,0x314,0x600,0x3e96,0x8602,0x3e9a,0xe622,0x3c5,0x313,0x600,0x3ea4,0x602,0x3ea8,0x8684, -0x3eac,0xe622,0x3c5,0x314,0x600,0x3ea6,0x602,0x3eaa,0x8684,0x3eae,0xe622,0x3a5,0x314,0x600,0x3eb6,0x602, -0x3eba,0x8684,0x3ebe,0xe622,0x3c9,0x313,0x600,0x3ec5,0x602,0x3ec9,0x684,0x3ecd,0x868a,0x3f40,0xe622,0x3c9, -0x314,0x600,0x3ec7,0x602,0x3ecb,0x684,0x3ecf,0x868a,0x3f42,0x1f60,0xe663,0x3c9,0x313,0x300,0x868a,0x3f44, -0x1f61,0xe663,0x3c9,0x314,0x300,0x868a,0x3f46,0x1f60,0xe663,0x3c9,0x313,0x301,0x868a,0x3f48,0x1f61,0xe663, -0x3c9,0x314,0x301,0x868a,0x3f4a,0x1f60,0xe663,0x3c9,0x313,0x342,0x868a,0x3f4c,0x1f61,0xe663,0x3c9,0x314, -0x342,0x868a,0x3f4e,0xe622,0x3a9,0x313,0x600,0x3ed5,0x602,0x3ed9,0x684,0x3edd,0x868a,0x3f50,0xe622,0x3a9, -0x314,0x600,0x3ed7,0x602,0x3edb,0x684,0x3edf,0x868a,0x3f52,0x1f68,0xe663,0x3a9,0x313,0x300,0x868a,0x3f54, -0x1f69,0xe663,0x3a9,0x314,0x300,0x868a,0x3f56,0x1f68,0xe663,0x3a9,0x313,0x301,0x868a,0x3f58,0x1f69,0xe663, -0x3a9,0x314,0x301,0x868a,0x3f5a,0x1f68,0xe663,0x3a9,0x313,0x342,0x868a,0x3f5c,0x1f69,0xe663,0x3a9,0x314, -0x342,0x868a,0x3f5e,0xe622,0x3b1,0x300,0x868a,0x3f64,0xe622,0x3b7,0x300,0x868a,0x3f84,0xe622,0x3c9,0x300, -0x868a,0x3fe4,0xe622,0x3b1,0x342,0x868a,0x3f6e,0xe622,0x3b7,0x342,0x868a,0x3f8e,0xe622,0x3c9,0x342,0x868a, -0x3fee,0xe622,0x41,0x300,0xe622,0x41,0x301,0xe622,0x41,0x303,0xe622,0x45,0x300,0xe622,0x45,0x301, -0xe622,0x45,0x308,0xe622,0x49,0x300,0xe622,0x49,0x301,0xe622,0x49,0x302,0xe622,0x4e,0x303,0xe622, -0x4f,0x300,0xe622,0x4f,0x301,0xe622,0x55,0x300,0xe622,0x55,0x301,0xe622,0x55,0x302,0xe622,0x59, -0x301,0xe622,0x61,0x300,0xe622,0x61,0x301,0xe622,0x61,0x303,0xe622,0x65,0x300,0xe622,0x65,0x301, -0xe622,0x65,0x308,0xe622,0x69,0x300,0xe622,0x69,0x301,0xe622,0x69,0x302,0xe622,0x6e,0x303,0xe622, -0x6f,0x300,0xe622,0x6f,0x301,0xe622,0x75,0x300,0xe622,0x75,0x301,0xe622,0x75,0x302,0xe622,0x79, -0x301,0xe622,0x79,0x308,0xe622,0x41,0x304,0xe622,0x61,0x304,0xca02,0x41,0x328,0xca02,0x61,0x328, -0xe622,0x43,0x301,0xe622,0x63,0x301,0xe622,0x43,0x302,0xe622,0x63,0x302,0xe622,0x43,0x307,0xe622, -0x63,0x307,0xe622,0x43,0x30c,0xe622,0x63,0x30c,0xe622,0x44,0x30c,0xe622,0x64,0x30c,0xe622,0x45, -0x306,0xe622,0x65,0x306,0xe622,0x45,0x307,0xe622,0x65,0x307,0xca02,0x45,0x328,0xca02,0x65,0x328, -0xe622,0x45,0x30c,0xe622,0x65,0x30c,0xe622,0x47,0x302,0xe622,0x67,0x302,0xe622,0x47,0x306,0xe622, -0x67,0x306,0xe622,0x47,0x307,0xe622,0x67,0x307,0xca02,0x47,0x327,0xca02,0x67,0x327,0xe622,0x48, -0x302,0xe622,0x68,0x302,0xe622,0x49,0x303,0xe622,0x69,0x303,0xe622,0x49,0x304,0xe622,0x69,0x304, -0xe622,0x49,0x306,0xe622,0x69,0x306,0xca02,0x49,0x328,0xca02,0x69,0x328,0xe622,0x49,0x307,0xe602, -0x4a,0x302,0xe602,0x6a,0x302,0xca02,0x4b,0x327,0xca02,0x6b,0x327,0xe622,0x4c,0x301,0xe622,0x6c, -0x301,0xca02,0x4c,0x327,0xca02,0x6c,0x327,0xe622,0x4c,0x30c,0xe622,0x6c,0x30c,0xe622,0x4e,0x301, -0xe622,0x6e,0x301,0xca02,0x4e,0x327,0xca02,0x6e,0x327,0xe622,0x4e,0x30c,0xe622,0x6e,0x30c,0xe622, -0x4f,0x306,0xe622,0x6f,0x306,0xe622,0x4f,0x30b,0xe622,0x6f,0x30b,0xe622,0x52,0x301,0xe622,0x72, -0x301,0xca02,0x52,0x327,0xca02,0x72,0x327,0xe622,0x52,0x30c,0xe622,0x72,0x30c,0xe622,0x53,0x302, -0xe622,0x73,0x302,0xca02,0x53,0x327,0xca02,0x73,0x327,0xca02,0x54,0x327,0xca02,0x74,0x327,0xe622, -0x54,0x30c,0xe622,0x74,0x30c,0xe622,0x55,0x306,0xe622,0x75,0x306,0xe622,0x55,0x30a,0xe622,0x75, -0x30a,0xe622,0x55,0x30b,0xe622,0x75,0x30b,0xca02,0x55,0x328,0xca02,0x75,0x328,0xe622,0x57,0x302, -0xe622,0x77,0x302,0xe622,0x59,0x302,0xe622,0x79,0x302,0xe622,0x59,0x308,0xe622,0x5a,0x301,0xe622, -0x7a,0x301,0xe622,0x5a,0x307,0xe622,0x7a,0x307,0xe622,0x5a,0x30c,0xe622,0x7a,0x30c,0xe622,0x41, -0x30c,0xe622,0x61,0x30c,0xe622,0x49,0x30c,0xe622,0x69,0x30c,0xe622,0x4f,0x30c,0xe622,0x6f,0x30c, -0xe622,0x55,0x30c,0xe622,0x75,0x30c,0xdc,0xe663,0x55,0x308,0x304,0xfc,0xe663,0x75,0x308,0x304, -0xdc,0xe663,0x55,0x308,0x301,0xfc,0xe663,0x75,0x308,0x301,0xdc,0xe663,0x55,0x308,0x30c,0xfc, -0xe663,0x75,0x308,0x30c,0xdc,0xe663,0x55,0x308,0x300,0xfc,0xe663,0x75,0x308,0x300,0xc4,0xe663, -0x41,0x308,0x304,0xe4,0xe663,0x61,0x308,0x304,0x226,0xe663,0x41,0x307,0x304,0x227,0xe663,0x61, -0x307,0x304,0xe602,0xc6,0x304,0xe602,0xe6,0x304,0xe622,0x47,0x30c,0xe622,0x67,0x30c,0xe622,0x4b, -0x30c,0xe622,0x6b,0x30c,0x1ea,0xe643,0x4f,0x328,0x304,0x1eb,0xe643,0x6f,0x328,0x304,0xe602,0x1b7, -0x30c,0xe602,0x292,0x30c,0xe602,0x6a,0x30c,0xe622,0x47,0x301,0xe622,0x67,0x301,0xe622,0x4e,0x300, -0xe622,0x6e,0x300,0xc5,0xe663,0x41,0x30a,0x301,0xe5,0xe663,0x61,0x30a,0x301,0xe602,0xc6,0x301, -0xe602,0xe6,0x301,0xe602,0xd8,0x301,0xe602,0xf8,0x301,0xe622,0x41,0x30f,0xe622,0x61,0x30f,0xe622, -0x41,0x311,0xe622,0x61,0x311,0xe622,0x45,0x30f,0xe622,0x65,0x30f,0xe622,0x45,0x311,0xe622,0x65, -0x311,0xe622,0x49,0x30f,0xe622,0x69,0x30f,0xe622,0x49,0x311,0xe622,0x69,0x311,0xe622,0x4f,0x30f, -0xe622,0x6f,0x30f,0xe622,0x4f,0x311,0xe622,0x6f,0x311,0xe622,0x52,0x30f,0xe622,0x72,0x30f,0xe622, -0x52,0x311,0xe622,0x72,0x311,0xe622,0x55,0x30f,0xe622,0x75,0x30f,0xe622,0x55,0x311,0xe622,0x75, -0x311,0xdc22,0x53,0x326,0xdc22,0x73,0x326,0xdc22,0x54,0x326,0xdc22,0x74,0x326,0xe622,0x48,0x30c, -0xe622,0x68,0x30c,0xd6,0xe663,0x4f,0x308,0x304,0xf6,0xe663,0x6f,0x308,0x304,0xd5,0xe663,0x4f, -0x303,0x304,0xf5,0xe663,0x6f,0x303,0x304,0x22e,0xe663,0x4f,0x307,0x304,0x22f,0xe663,0x6f,0x307, -0x304,0xe622,0x59,0x304,0xe622,0x79,0x304,0xe602,0xa8,0x301,0xe602,0x391,0x301,0xe602,0x395,0x301, -0xe602,0x397,0x301,0xe602,0x399,0x301,0xe602,0x39f,0x301,0xe602,0x3a5,0x301,0xe602,0x3a9,0x301,0x3ca, -0xe643,0x3b9,0x308,0x301,0xe602,0x399,0x308,0xe602,0x3a5,0x308,0xe602,0x3b5,0x301,0xe602,0x3b9,0x301, -0x3cb,0xe643,0x3c5,0x308,0x301,0xe602,0x3bf,0x301,0xe602,0x3c5,0x301,0xe602,0x3d2,0x301,0xe602,0x3d2, -0x308,0xe602,0x415,0x300,0xe602,0x415,0x308,0xe602,0x413,0x301,0xe602,0x406,0x308,0xe602,0x41a,0x301, -0xe602,0x418,0x300,0xe602,0x423,0x306,0xe602,0x418,0x306,0xe602,0x438,0x306,0xe602,0x435,0x300,0xe602, -0x435,0x308,0xe602,0x433,0x301,0xe602,0x456,0x308,0xe602,0x43a,0x301,0xe602,0x438,0x300,0xe602,0x443, -0x306,0xe602,0x474,0x30f,0xe602,0x475,0x30f,0xe602,0x416,0x306,0xe602,0x436,0x306,0xe602,0x410,0x306, -0xe602,0x430,0x306,0xe602,0x410,0x308,0xe602,0x430,0x308,0xe602,0x415,0x306,0xe602,0x435,0x306,0xe602, -0x4d8,0x308,0xe602,0x4d9,0x308,0xe602,0x416,0x308,0xe602,0x436,0x308,0xe602,0x417,0x308,0xe602,0x437, -0x308,0xe602,0x418,0x304,0xe602,0x438,0x304,0xe602,0x418,0x308,0xe602,0x438,0x308,0xe602,0x41e,0x308, -0xe602,0x43e,0x308,0xe602,0x4e8,0x308,0xe602,0x4e9,0x308,0xe602,0x42d,0x308,0xe602,0x44d,0x308,0xe602, -0x423,0x304,0xe602,0x443,0x304,0xe602,0x423,0x308,0xe602,0x443,0x308,0xe602,0x423,0x30b,0xe602,0x443, -0x30b,0xe602,0x427,0x308,0xe602,0x447,0x308,0xe602,0x42b,0x308,0xe602,0x44b,0x308,0xe622,0x627,0x653, -0xe622,0x627,0x654,0xe602,0x648,0x654,0xdc02,0x627,0x655,0xe602,0x64a,0x654,0xe602,0x6d5,0x654,0xe602, -0x6c1,0x654,0xe602,0x6d2,0x654,0x702,0x928,0x93c,0x702,0x930,0x93c,0x702,0x933,0x93c,2,0x9c7, -0x9be,2,0x9c7,0x9d7,2,0xb47,0xb56,2,0xb47,0xb3e,2,0xb47,0xb57,2,0xb92,0xbd7, -2,0xbc6,0xbbe,2,0xbc7,0xbbe,2,0xbc6,0xbd7,0x5b02,0xc46,0xc56,2,0xcbf,0xcd5,2, -0xcc6,0xcd5,2,0xcc6,0xcd6,0xcca,0x43,0xcc6,0xcc2,0xcd5,2,0xd46,0xd3e,2,0xd47,0xd3e, -2,0xd46,0xd57,0x902,0xdd9,0xdca,0xddc,0x943,0xdd9,0xdcf,0xdca,2,0xdd9,0xddf,2,0x1025, -0x102e,2,0x1b05,0x1b35,2,0x1b07,0x1b35,2,0x1b09,0x1b35,2,0x1b0b,0x1b35,2,0x1b0d,0x1b35, -2,0x1b11,0x1b35,2,0x1b3a,0x1b35,2,0x1b3c,0x1b35,2,0x1b3e,0x1b35,2,0x1b3f,0x1b35,2, -0x1b42,0x1b35,0xdc22,0x41,0x325,0xdc22,0x61,0x325,0xe622,0x42,0x307,0xe622,0x62,0x307,0xdc02,0x42, -0x323,0xdc02,0x62,0x323,0xdc02,0x42,0x331,0xdc02,0x62,0x331,0xc7,0xe643,0x43,0x327,0x301,0xe7, -0xe643,0x63,0x327,0x301,0xe622,0x44,0x307,0xe622,0x64,0x307,0xdc22,0x44,0x323,0xdc22,0x64,0x323, -0xdc22,0x44,0x331,0xdc22,0x64,0x331,0xca02,0x44,0x327,0xca02,0x64,0x327,0xdc22,0x44,0x32d,0xdc22, -0x64,0x32d,0x112,0xe663,0x45,0x304,0x300,0x113,0xe663,0x65,0x304,0x300,0x112,0xe663,0x45,0x304, -0x301,0x113,0xe663,0x65,0x304,0x301,0xdc22,0x45,0x32d,0xdc22,0x65,0x32d,0xdc22,0x45,0x330,0xdc22, -0x65,0x330,0x228,0xe643,0x45,0x327,0x306,0x229,0xe643,0x65,0x327,0x306,0xe602,0x46,0x307,0xe602, -0x66,0x307,0xe622,0x47,0x304,0xe622,0x67,0x304,0xe622,0x48,0x307,0xe622,0x68,0x307,0xdc22,0x48, -0x323,0xdc22,0x68,0x323,0xe622,0x48,0x308,0xe622,0x68,0x308,0xca02,0x48,0x327,0xca02,0x68,0x327, -0xdc22,0x48,0x32e,0xdc22,0x68,0x32e,0xdc22,0x49,0x330,0xdc22,0x69,0x330,0xcf,0xe663,0x49,0x308, -0x301,0xef,0xe663,0x69,0x308,0x301,0xe622,0x4b,0x301,0xe622,0x6b,0x301,0xdc22,0x4b,0x323,0xdc22, -0x6b,0x323,0xdc22,0x4b,0x331,0xdc22,0x6b,0x331,0x1e36,0xe663,0x4c,0x323,0x304,0x1e37,0xe663,0x6c, -0x323,0x304,0xdc22,0x4c,0x331,0xdc22,0x6c,0x331,0xdc22,0x4c,0x32d,0xdc22,0x6c,0x32d,0xe622,0x4d, -0x301,0xe622,0x6d,0x301,0xe622,0x4d,0x307,0xe622,0x6d,0x307,0xdc02,0x4d,0x323,0xdc02,0x6d,0x323, -0xe622,0x4e,0x307,0xe622,0x6e,0x307,0xdc22,0x4e,0x323,0xdc22,0x6e,0x323,0xdc22,0x4e,0x331,0xdc22, -0x6e,0x331,0xdc22,0x4e,0x32d,0xdc22,0x6e,0x32d,0xd5,0xe663,0x4f,0x303,0x301,0xf5,0xe663,0x6f, -0x303,0x301,0xd5,0xe663,0x4f,0x303,0x308,0xf5,0xe663,0x6f,0x303,0x308,0x14c,0xe663,0x4f,0x304, -0x300,0x14d,0xe663,0x6f,0x304,0x300,0x14c,0xe663,0x4f,0x304,0x301,0x14d,0xe663,0x6f,0x304,0x301, -0xe602,0x50,0x301,0xe602,0x70,0x301,0xe602,0x50,0x307,0xe602,0x70,0x307,0xe622,0x52,0x307,0xe622, -0x72,0x307,0x1e5a,0xe663,0x52,0x323,0x304,0x1e5b,0xe663,0x72,0x323,0x304,0xdc22,0x52,0x331,0xdc22, -0x72,0x331,0xe622,0x53,0x307,0xe622,0x73,0x307,0x15a,0xe663,0x53,0x301,0x307,0x15b,0xe663,0x73, -0x301,0x307,0x160,0xe663,0x53,0x30c,0x307,0x161,0xe663,0x73,0x30c,0x307,0x1e62,0xe663,0x53,0x323, -0x307,0x1e63,0xe663,0x73,0x323,0x307,0xe622,0x54,0x307,0xe622,0x74,0x307,0xdc22,0x54,0x323,0xdc22, -0x74,0x323,0xdc22,0x54,0x331,0xdc22,0x74,0x331,0xdc22,0x54,0x32d,0xdc22,0x74,0x32d,0xdc22,0x55, -0x324,0xdc22,0x75,0x324,0xdc22,0x55,0x330,0xdc22,0x75,0x330,0xdc22,0x55,0x32d,0xdc22,0x75,0x32d, -0x168,0xe663,0x55,0x303,0x301,0x169,0xe663,0x75,0x303,0x301,0x16a,0xe663,0x55,0x304,0x308,0x16b, -0xe663,0x75,0x304,0x308,0xe622,0x56,0x303,0xe622,0x76,0x303,0xdc02,0x56,0x323,0xdc02,0x76,0x323, -0xe622,0x57,0x300,0xe622,0x77,0x300,0xe622,0x57,0x301,0xe622,0x77,0x301,0xe622,0x57,0x308,0xe622, -0x77,0x308,0xe622,0x57,0x307,0xe622,0x77,0x307,0xdc02,0x57,0x323,0xdc02,0x77,0x323,0xe602,0x58, -0x307,0xe602,0x78,0x307,0xe602,0x58,0x308,0xe602,0x78,0x308,0xe622,0x59,0x307,0xe622,0x79,0x307, -0xe622,0x5a,0x302,0xe622,0x7a,0x302,0xdc02,0x5a,0x323,0xdc02,0x7a,0x323,0xdc02,0x5a,0x331,0xdc02, -0x7a,0x331,0xdc22,0x68,0x331,0xe622,0x74,0x308,0xe622,0x77,0x30a,0xe622,0x79,0x30a,0xe602,0x17f, -0x307,0xe622,0x41,0x309,0xe622,0x61,0x309,0xc2,0xe663,0x41,0x302,0x301,0xe2,0xe663,0x61,0x302, -0x301,0xc2,0xe663,0x41,0x302,0x300,0xe2,0xe663,0x61,0x302,0x300,0xc2,0xe663,0x41,0x302,0x309, -0xe2,0xe663,0x61,0x302,0x309,0xc2,0xe663,0x41,0x302,0x303,0xe2,0xe663,0x61,0x302,0x303,0x1ea0, -0xe663,0x41,0x323,0x302,0x1ea1,0xe663,0x61,0x323,0x302,0x102,0xe663,0x41,0x306,0x301,0x103,0xe663, -0x61,0x306,0x301,0x102,0xe663,0x41,0x306,0x300,0x103,0xe663,0x61,0x306,0x300,0x102,0xe663,0x41, -0x306,0x309,0x103,0xe663,0x61,0x306,0x309,0x102,0xe663,0x41,0x306,0x303,0x103,0xe663,0x61,0x306, -0x303,0x1ea0,0xe663,0x41,0x323,0x306,0x1ea1,0xe663,0x61,0x323,0x306,0xe622,0x45,0x309,0xe622,0x65, -0x309,0xe622,0x45,0x303,0xe622,0x65,0x303,0xca,0xe663,0x45,0x302,0x301,0xea,0xe663,0x65,0x302, -0x301,0xca,0xe663,0x45,0x302,0x300,0xea,0xe663,0x65,0x302,0x300,0xca,0xe663,0x45,0x302,0x309, -0xea,0xe663,0x65,0x302,0x309,0xca,0xe663,0x45,0x302,0x303,0xea,0xe663,0x65,0x302,0x303,0x1eb8, -0xe663,0x45,0x323,0x302,0x1eb9,0xe663,0x65,0x323,0x302,0xe622,0x49,0x309,0xe622,0x69,0x309,0xdc22, -0x49,0x323,0xdc22,0x69,0x323,0xe622,0x4f,0x309,0xe622,0x6f,0x309,0xd4,0xe663,0x4f,0x302,0x301, -0xf4,0xe663,0x6f,0x302,0x301,0xd4,0xe663,0x4f,0x302,0x300,0xf4,0xe663,0x6f,0x302,0x300,0xd4, -0xe663,0x4f,0x302,0x309,0xf4,0xe663,0x6f,0x302,0x309,0xd4,0xe663,0x4f,0x302,0x303,0xf4,0xe663, -0x6f,0x302,0x303,0x1ecc,0xe663,0x4f,0x323,0x302,0x1ecd,0xe663,0x6f,0x323,0x302,0x1a0,0xe663,0x4f, -0x31b,0x301,0x1a1,0xe663,0x6f,0x31b,0x301,0x1a0,0xe663,0x4f,0x31b,0x300,0x1a1,0xe663,0x6f,0x31b, -0x300,0x1a0,0xe663,0x4f,0x31b,0x309,0x1a1,0xe663,0x6f,0x31b,0x309,0x1a0,0xe663,0x4f,0x31b,0x303, -0x1a1,0xe663,0x6f,0x31b,0x303,0x1a0,0xdc63,0x4f,0x31b,0x323,0x1a1,0xdc63,0x6f,0x31b,0x323,0xdc22, -0x55,0x323,0xdc22,0x75,0x323,0xe622,0x55,0x309,0xe622,0x75,0x309,0x1af,0xe663,0x55,0x31b,0x301, -0x1b0,0xe663,0x75,0x31b,0x301,0x1af,0xe663,0x55,0x31b,0x300,0x1b0,0xe663,0x75,0x31b,0x300,0x1af, -0xe663,0x55,0x31b,0x309,0x1b0,0xe663,0x75,0x31b,0x309,0x1af,0xe663,0x55,0x31b,0x303,0x1b0,0xe663, -0x75,0x31b,0x303,0x1af,0xdc63,0x55,0x31b,0x323,0x1b0,0xdc63,0x75,0x31b,0x323,0xe622,0x59,0x300, -0xe622,0x79,0x300,0xdc02,0x59,0x323,0xdc02,0x79,0x323,0xe622,0x59,0x309,0xe622,0x79,0x309,0xe622, -0x59,0x303,0xe622,0x79,0x303,0x1f10,0xe643,0x3b5,0x313,0x300,0x1f11,0xe643,0x3b5,0x314,0x300,0x1f10, -0xe643,0x3b5,0x313,0x301,0x1f11,0xe643,0x3b5,0x314,0x301,0x1f18,0xe643,0x395,0x313,0x300,0x1f19,0xe643, -0x395,0x314,0x300,0x1f18,0xe643,0x395,0x313,0x301,0x1f19,0xe643,0x395,0x314,0x301,0x1f30,0xe643,0x3b9, -0x313,0x300,0x1f31,0xe643,0x3b9,0x314,0x300,0x1f30,0xe643,0x3b9,0x313,0x301,0x1f31,0xe643,0x3b9,0x314, -0x301,0x1f30,0xe643,0x3b9,0x313,0x342,0x1f31,0xe643,0x3b9,0x314,0x342,0x1f38,0xe643,0x399,0x313,0x300, -0x1f39,0xe643,0x399,0x314,0x300,0x1f38,0xe643,0x399,0x313,0x301,0x1f39,0xe643,0x399,0x314,0x301,0x1f38, -0xe643,0x399,0x313,0x342,0x1f39,0xe643,0x399,0x314,0x342,0x1f40,0xe643,0x3bf,0x313,0x300,0x1f41,0xe643, -0x3bf,0x314,0x300,0x1f40,0xe643,0x3bf,0x313,0x301,0x1f41,0xe643,0x3bf,0x314,0x301,0x1f48,0xe643,0x39f, -0x313,0x300,0x1f49,0xe643,0x39f,0x314,0x300,0x1f48,0xe643,0x39f,0x313,0x301,0x1f49,0xe643,0x39f,0x314, -0x301,0x1f50,0xe643,0x3c5,0x313,0x300,0x1f51,0xe643,0x3c5,0x314,0x300,0x1f50,0xe643,0x3c5,0x313,0x301, -0x1f51,0xe643,0x3c5,0x314,0x301,0x1f50,0xe643,0x3c5,0x313,0x342,0x1f51,0xe643,0x3c5,0x314,0x342,0x1f59, -0xe643,0x3a5,0x314,0x300,0x1f59,0xe643,0x3a5,0x314,0x301,0x1f59,0xe643,0x3a5,0x314,0x342,0xe602,0x3b5, -0x300,0xe602,0x3b9,0x300,0xe602,0x3bf,0x300,0xe602,0x3c5,0x300,0x1f00,0xf063,0x3b1,0x313,0x345,0x1f01, -0xf063,0x3b1,0x314,0x345,0x1f02,0x345,2,0xf044,0x3b1,0x313,0x300,0x345,0x1f03,0x345,2,0xf044, -0x3b1,0x314,0x300,0x345,0x1f04,0x345,2,0xf044,0x3b1,0x313,0x301,0x345,0x1f05,0x345,2,0xf044, -0x3b1,0x314,0x301,0x345,0x1f06,0x345,2,0xf044,0x3b1,0x313,0x342,0x345,0x1f07,0x345,2,0xf044, -0x3b1,0x314,0x342,0x345,0x1f08,0xf063,0x391,0x313,0x345,0x1f09,0xf063,0x391,0x314,0x345,0x1f0a,0x345, -2,0xf044,0x391,0x313,0x300,0x345,0x1f0b,0x345,2,0xf044,0x391,0x314,0x300,0x345,0x1f0c,0x345, -2,0xf044,0x391,0x313,0x301,0x345,0x1f0d,0x345,2,0xf044,0x391,0x314,0x301,0x345,0x1f0e,0x345, -2,0xf044,0x391,0x313,0x342,0x345,0x1f0f,0x345,2,0xf044,0x391,0x314,0x342,0x345,0x1f20,0xf063, -0x3b7,0x313,0x345,0x1f21,0xf063,0x3b7,0x314,0x345,0x1f22,0x345,2,0xf044,0x3b7,0x313,0x300,0x345, -0x1f23,0x345,2,0xf044,0x3b7,0x314,0x300,0x345,0x1f24,0x345,2,0xf044,0x3b7,0x313,0x301,0x345, -0x1f25,0x345,2,0xf044,0x3b7,0x314,0x301,0x345,0x1f26,0x345,2,0xf044,0x3b7,0x313,0x342,0x345, -0x1f27,0x345,2,0xf044,0x3b7,0x314,0x342,0x345,0x1f28,0xf063,0x397,0x313,0x345,0x1f29,0xf063,0x397, -0x314,0x345,0x1f2a,0x345,2,0xf044,0x397,0x313,0x300,0x345,0x1f2b,0x345,2,0xf044,0x397,0x314, -0x300,0x345,0x1f2c,0x345,2,0xf044,0x397,0x313,0x301,0x345,0x1f2d,0x345,2,0xf044,0x397,0x314, -0x301,0x345,0x1f2e,0x345,2,0xf044,0x397,0x313,0x342,0x345,0x1f2f,0x345,2,0xf044,0x397,0x314, -0x342,0x345,0x1f60,0xf063,0x3c9,0x313,0x345,0x1f61,0xf063,0x3c9,0x314,0x345,0x1f62,0x345,2,0xf044, -0x3c9,0x313,0x300,0x345,0x1f63,0x345,2,0xf044,0x3c9,0x314,0x300,0x345,0x1f64,0x345,2,0xf044, -0x3c9,0x313,0x301,0x345,0x1f65,0x345,2,0xf044,0x3c9,0x314,0x301,0x345,0x1f66,0x345,2,0xf044, -0x3c9,0x313,0x342,0x345,0x1f67,0x345,2,0xf044,0x3c9,0x314,0x342,0x345,0x1f68,0xf063,0x3a9,0x313, -0x345,0x1f69,0xf063,0x3a9,0x314,0x345,0x1f6a,0x345,2,0xf044,0x3a9,0x313,0x300,0x345,0x1f6b,0x345, -2,0xf044,0x3a9,0x314,0x300,0x345,0x1f6c,0x345,2,0xf044,0x3a9,0x313,0x301,0x345,0x1f6d,0x345, -2,0xf044,0x3a9,0x314,0x301,0x345,0x1f6e,0x345,2,0xf044,0x3a9,0x313,0x342,0x345,0x1f6f,0x345, -2,0xf044,0x3a9,0x314,0x342,0x345,0xe602,0x3b1,0x306,0xe602,0x3b1,0x304,0x1f70,0xf043,0x3b1,0x300, -0x345,0xf022,0x3b1,0x345,0x3ac,0xf043,0x3b1,0x301,0x345,0x1fb6,0xf043,0x3b1,0x342,0x345,0xe602,0x391, -0x306,0xe602,0x391,0x304,0xe602,0x391,0x300,0xf022,0x391,0x345,0xe602,0xa8,0x342,0x1f74,0xf043,0x3b7, -0x300,0x345,0xf022,0x3b7,0x345,0x3ae,0xf043,0x3b7,0x301,0x345,0x1fc6,0xf043,0x3b7,0x342,0x345,0xe602, -0x395,0x300,0xe602,0x397,0x300,0xf022,0x397,0x345,0xe602,0x1fbf,0x300,0xe602,0x1fbf,0x301,0xe602,0x1fbf, -0x342,0xe602,0x3b9,0x306,0xe602,0x3b9,0x304,0x3ca,0xe643,0x3b9,0x308,0x300,0xe602,0x3b9,0x342,0x3ca, -0xe643,0x3b9,0x308,0x342,0xe602,0x399,0x306,0xe602,0x399,0x304,0xe602,0x399,0x300,0xe602,0x1ffe,0x300, -0xe602,0x1ffe,0x301,0xe602,0x1ffe,0x342,0xe602,0x3c5,0x306,0xe602,0x3c5,0x304,0x3cb,0xe643,0x3c5,0x308, -0x300,0xe602,0x3c1,0x313,0xe602,0x3c1,0x314,0xe602,0x3c5,0x342,0x3cb,0xe643,0x3c5,0x308,0x342,0xe602, -0x3a5,0x306,0xe602,0x3a5,0x304,0xe602,0x3a5,0x300,0xe602,0x3a1,0x314,0xe602,0xa8,0x300,0x1f7c,0xf043, -0x3c9,0x300,0x345,0xf022,0x3c9,0x345,0x3ce,0xf043,0x3c9,0x301,0x345,0x1ff6,0xf043,0x3c9,0x342,0x345, -0xe602,0x39f,0x300,0xe602,0x3a9,0x300,0xf022,0x3a9,0x345,0x102,0x2190,0x338,0x102,0x2192,0x338,0x102, -0x2194,0x338,0x102,0x21d0,0x338,0x102,0x21d4,0x338,0x102,0x21d2,0x338,0x102,0x2203,0x338,0x102,0x2208, -0x338,0x102,0x220b,0x338,0x102,0x2223,0x338,0x102,0x2225,0x338,0x102,0x223c,0x338,0x102,0x2243,0x338, -0x102,0x2245,0x338,0x102,0x2248,0x338,0x102,0x3d,0x338,0x102,0x2261,0x338,0x102,0x224d,0x338,0x102, -0x3c,0x338,0x102,0x3e,0x338,0x102,0x2264,0x338,0x102,0x2265,0x338,0x102,0x2272,0x338,0x102,0x2273, -0x338,0x102,0x2276,0x338,0x102,0x2277,0x338,0x102,0x227a,0x338,0x102,0x227b,0x338,0x102,0x2282,0x338, -0x102,0x2283,0x338,0x102,0x2286,0x338,0x102,0x2287,0x338,0x102,0x22a2,0x338,0x102,0x22a8,0x338,0x102, -0x22a9,0x338,0x102,0x22ab,0x338,0x102,0x227c,0x338,0x102,0x227d,0x338,0x102,0x2291,0x338,0x102,0x2292, -0x338,0x102,0x22b2,0x338,0x102,0x22b3,0x338,0x102,0x22b4,0x338,0x102,0x22b5,0x338,0x802,0x304b,0x3099, -0x802,0x304d,0x3099,0x802,0x304f,0x3099,0x802,0x3051,0x3099,0x802,0x3053,0x3099,0x802,0x3055,0x3099,0x802, -0x3057,0x3099,0x802,0x3059,0x3099,0x802,0x305b,0x3099,0x802,0x305d,0x3099,0x802,0x305f,0x3099,0x802,0x3061, -0x3099,0x802,0x3064,0x3099,0x802,0x3066,0x3099,0x802,0x3068,0x3099,0x802,0x306f,0x3099,0x802,0x306f,0x309a, -0x802,0x3072,0x3099,0x802,0x3072,0x309a,0x802,0x3075,0x3099,0x802,0x3075,0x309a,0x802,0x3078,0x3099,0x802, -0x3078,0x309a,0x802,0x307b,0x3099,0x802,0x307b,0x309a,0x802,0x3046,0x3099,0x802,0x309d,0x3099,0x802,0x30ab, -0x3099,0x802,0x30ad,0x3099,0x802,0x30af,0x3099,0x802,0x30b1,0x3099,0x802,0x30b3,0x3099,0x802,0x30b5,0x3099, -0x802,0x30b7,0x3099,0x802,0x30b9,0x3099,0x802,0x30bb,0x3099,0x802,0x30bd,0x3099,0x802,0x30bf,0x3099,0x802, -0x30c1,0x3099,0x802,0x30c4,0x3099,0x802,0x30c6,0x3099,0x802,0x30c8,0x3099,0x802,0x30cf,0x3099,0x802,0x30cf, -0x309a,0x802,0x30d2,0x3099,0x802,0x30d2,0x309a,0x802,0x30d5,0x3099,0x802,0x30d5,0x309a,0x802,0x30d8,0x3099, -0x802,0x30d8,0x309a,0x802,0x30db,0x3099,0x802,0x30db,0x309a,0x802,0x30a6,0x3099,0x802,0x30ef,0x3099,0x802, -0x30f0,0x3099,0x802,0x30f1,0x3099,0x802,0x30f2,0x3099,0x802,0x30fd,0x3099,0x704,0xd804,0xdc99,0xd804,0xdcba, -0x704,0xd804,0xdc9b,0xd804,0xdcba,0x704,0xd804,0xdca5,0xd804,0xdcba,4,0xd804,0xdd31,0xd804,0xdd27,4, -0xd804,0xdd32,0xd804,0xdd27,4,0xd804,0xdf47,0xd804,0xdf3e,4,0xd804,0xdf47,0xd804,0xdf57,4,0xd805, -0xdcb9,0xd805,0xdcba,4,0xd805,0xdcb9,0xd805,0xdcb0,4,0xd805,0xdcb9,0xd805,0xdcbd,4,0xd805,0xddb8, -0xd805,0xddaf,4,0xd805,0xddb9,0xd805,0xddaf,0xe6e6,0xe6a1,0x300,0xe6e6,0xe6a1,0x301,0xe6e6,0xe6a1,0x313, -0xe6e6,0xe6a2,0x308,0x301,1,0x2b9,1,0x3b,1,0xb7,0x702,0x915,0x93c,0x702,0x916,0x93c, -0x702,0x917,0x93c,0x702,0x91c,0x93c,0x702,0x921,0x93c,0x702,0x922,0x93c,0x702,0x92b,0x93c,0x702, -0x92f,0x93c,0x702,0x9a1,0x9bc,0x702,0x9a2,0x9bc,0x702,0x9af,0x9bc,0x702,0xa32,0xa3c,0x702,0xa38, -0xa3c,0x702,0xa16,0xa3c,0x702,0xa17,0xa3c,0x702,0xa1c,0xa3c,0x702,0xa2b,0xa3c,0x702,0xb21,0xb3c, -0x702,0xb22,0xb3c,2,0xf42,0xfb7,2,0xf4c,0xfb7,2,0xf51,0xfb7,2,0xf56,0xfb7,2, -0xf5b,0xfb7,2,0xf40,0xfb5,0x8100,0x82a2,0xf71,0xf72,0x8100,0x84a2,0xf71,0xf74,0x8202,0xfb2,0xf80, -0x8202,0xfb3,0xf80,0x8100,0x82a2,0xf71,0xf80,2,0xf92,0xfb7,2,0xf9c,0xfb7,2,0xfa1,0xfb7, -2,0xfa6,0xfb7,2,0xfab,0xfb7,2,0xf90,0xfb5,0x3ac,0xe662,0x3b1,0x301,0x3ad,0xe642,0x3b5, -0x301,0x3ae,0xe662,0x3b7,0x301,0x3af,0xe642,0x3b9,0x301,0x3cc,0xe642,0x3bf,0x301,0x3cd,0xe642,0x3c5, -0x301,0x3ce,0xe662,0x3c9,0x301,0x386,0xe642,0x391,0x301,0x21,0x3b9,0x388,0xe642,0x395,0x301,0x389, -0xe642,0x397,0x301,0x390,1,0xe643,0x3b9,0x308,0x301,0x38a,0xe642,0x399,0x301,0x3b0,1,0xe643, -0x3c5,0x308,0x301,0x38e,0xe642,0x3a5,0x301,0x385,0xe642,0xa8,0x301,1,0x60,0x38c,0xe642,0x39f, -0x301,0x38f,0xe642,0x3a9,0x301,1,0xb4,0x21,0x3a9,0x21,0x4b,0xc5,0xe662,0x41,0x30a,1, -0x3008,1,0x3009,0x102,0x2add,0x338,1,0x8c48,1,0x66f4,1,0x8eca,1,0x8cc8,1,0x6ed1, -1,0x4e32,1,0x53e5,1,0x9f9c,1,0x5951,1,0x91d1,1,0x5587,1,0x5948,1,0x61f6, -1,0x7669,1,0x7f85,1,0x863f,1,0x87ba,1,0x88f8,1,0x908f,1,0x6a02,1,0x6d1b, -1,0x70d9,1,0x73de,1,0x843d,1,0x916a,1,0x99f1,1,0x4e82,1,0x5375,1,0x6b04, -1,0x721b,1,0x862d,1,0x9e1e,1,0x5d50,1,0x6feb,1,0x85cd,1,0x8964,1,0x62c9, -1,0x81d8,1,0x881f,1,0x5eca,1,0x6717,1,0x6d6a,1,0x72fc,1,0x90ce,1,0x4f86, -1,0x51b7,1,0x52de,1,0x64c4,1,0x6ad3,1,0x7210,1,0x76e7,1,0x8001,1,0x8606, -1,0x865c,1,0x8def,1,0x9732,1,0x9b6f,1,0x9dfa,1,0x788c,1,0x797f,1,0x7da0, -1,0x83c9,1,0x9304,1,0x9e7f,1,0x8ad6,1,0x58df,1,0x5f04,1,0x7c60,1,0x807e, -1,0x7262,1,0x78ca,1,0x8cc2,1,0x96f7,1,0x58d8,1,0x5c62,1,0x6a13,1,0x6dda, -1,0x6f0f,1,0x7d2f,1,0x7e37,1,0x964b,1,0x52d2,1,0x808b,1,0x51dc,1,0x51cc, -1,0x7a1c,1,0x7dbe,1,0x83f1,1,0x9675,1,0x8b80,1,0x62cf,1,0x8afe,1,0x4e39, -1,0x5be7,1,0x6012,1,0x7387,1,0x7570,1,0x5317,1,0x78fb,1,0x4fbf,1,0x5fa9, -1,0x4e0d,1,0x6ccc,1,0x6578,1,0x7d22,1,0x53c3,1,0x585e,1,0x7701,1,0x8449, -1,0x8aaa,1,0x6bba,1,0x8fb0,1,0x6c88,1,0x62fe,1,0x82e5,1,0x63a0,1,0x7565, -1,0x4eae,1,0x5169,1,0x51c9,1,0x6881,1,0x7ce7,1,0x826f,1,0x8ad2,1,0x91cf, -1,0x52f5,1,0x5442,1,0x5973,1,0x5eec,1,0x65c5,1,0x6ffe,1,0x792a,1,0x95ad, -1,0x9a6a,1,0x9e97,1,0x9ece,1,0x529b,1,0x66c6,1,0x6b77,1,0x8f62,1,0x5e74, -1,0x6190,1,0x6200,1,0x649a,1,0x6f23,1,0x7149,1,0x7489,1,0x79ca,1,0x7df4, -1,0x806f,1,0x8f26,1,0x84ee,1,0x9023,1,0x934a,1,0x5217,1,0x52a3,1,0x54bd, -1,0x70c8,1,0x88c2,1,0x5ec9,1,0x5ff5,1,0x637b,1,0x6bae,1,0x7c3e,1,0x7375, -1,0x4ee4,1,0x56f9,1,0x5dba,1,0x601c,1,0x73b2,1,0x7469,1,0x7f9a,1,0x8046, -1,0x9234,1,0x96f6,1,0x9748,1,0x9818,1,0x4f8b,1,0x79ae,1,0x91b4,1,0x96b8, -1,0x60e1,1,0x4e86,1,0x50da,1,0x5bee,1,0x5c3f,1,0x6599,1,0x71ce,1,0x7642, -1,0x84fc,1,0x907c,1,0x9f8d,1,0x6688,1,0x962e,1,0x5289,1,0x677b,1,0x67f3, -1,0x6d41,1,0x6e9c,1,0x7409,1,0x7559,1,0x786b,1,0x7d10,1,0x985e,1,0x516d, -1,0x622e,1,0x9678,1,0x502b,1,0x5d19,1,0x6dea,1,0x8f2a,1,0x5f8b,1,0x6144, -1,0x6817,1,0x9686,1,0x5229,1,0x540f,1,0x5c65,1,0x6613,1,0x674e,1,0x68a8, -1,0x6ce5,1,0x7406,1,0x75e2,1,0x7f79,1,0x88cf,1,0x88e1,1,0x91cc,1,0x96e2, -1,0x533f,1,0x6eba,1,0x541d,1,0x71d0,1,0x7498,1,0x85fa,1,0x96a3,1,0x9c57, -1,0x9e9f,1,0x6797,1,0x6dcb,1,0x81e8,1,0x7acb,1,0x7b20,1,0x7c92,1,0x72c0, -1,0x7099,1,0x8b58,1,0x4ec0,1,0x8336,1,0x523a,1,0x5207,1,0x5ea6,1,0x62d3, -1,0x7cd6,1,0x5b85,1,0x6d1e,1,0x66b4,1,0x8f3b,1,0x884c,1,0x964d,1,0x898b, -1,0x5ed3,1,0x5140,1,0x55c0,1,0x585a,1,0x6674,1,0x51de,1,0x732a,1,0x76ca, -1,0x793c,1,0x795e,1,0x7965,1,0x798f,1,0x9756,1,0x7cbe,1,0x7fbd,1,0x8612, -1,0x8af8,1,0x9038,1,0x90fd,1,0x98ef,1,0x98fc,1,0x9928,1,0x9db4,1,0x90de, -1,0x96b7,1,0x4fae,1,0x50e7,1,0x514d,1,0x52c9,1,0x52e4,1,0x5351,1,0x559d, -1,0x5606,1,0x5668,1,0x5840,1,0x58a8,1,0x5c64,1,0x5c6e,1,0x6094,1,0x6168, -1,0x618e,1,0x61f2,1,0x654f,1,0x65e2,1,0x6691,1,0x6885,1,0x6d77,1,0x6e1a, -1,0x6f22,1,0x716e,1,0x722b,1,0x7422,1,0x7891,1,0x793e,1,0x7949,1,0x7948, -1,0x7950,1,0x7956,1,0x795d,1,0x798d,1,0x798e,1,0x7a40,1,0x7a81,1,0x7bc0, -1,0x7e09,1,0x7e41,1,0x7f72,1,0x8005,1,0x81ed,1,0x8279,1,0x8457,1,0x8910, -1,0x8996,1,0x8b01,1,0x8b39,1,0x8cd3,1,0x8d08,1,0x8fb6,1,0x96e3,1,0x97ff, -1,0x983b,1,0x6075,2,0xd850,0xdeee,1,0x8218,1,0x4e26,1,0x51b5,1,0x5168,1, -0x4f80,1,0x5145,1,0x5180,1,0x52c7,1,0x52fa,1,0x5555,1,0x5599,1,0x55e2,1, -0x58b3,1,0x5944,1,0x5954,1,0x5a62,1,0x5b28,1,0x5ed2,1,0x5ed9,1,0x5f69,1, -0x5fad,1,0x60d8,1,0x614e,1,0x6108,1,0x6160,1,0x6234,1,0x63c4,1,0x641c,1, -0x6452,1,0x6556,1,0x671b,1,0x6756,1,0x6b79,1,0x6edb,1,0x6ecb,1,0x701e,1, -0x77a7,1,0x7235,1,0x72af,1,0x7471,1,0x7506,1,0x753b,1,0x761d,1,0x761f,1, -0x76db,1,0x76f4,1,0x774a,1,0x7740,1,0x78cc,1,0x7ab1,1,0x7c7b,1,0x7d5b,1, -0x7f3e,1,0x8352,1,0x83ef,1,0x8779,1,0x8941,1,0x8986,1,0x8abf,1,0x8acb,1, -0x8aed,1,0x8b8a,1,0x8f38,1,0x9072,1,0x9199,1,0x9276,1,0x967c,1,0x97db,1, -0x980b,1,0x9b12,2,0xd84a,0xdc4a,2,0xd84a,0xdc44,2,0xd84c,0xdfd5,1,0x3b9d,1,0x4018, -1,0x4039,2,0xd854,0xde49,2,0xd857,0xdcd0,2,0xd85f,0xded3,1,0x9f43,1,0x9f8e,0xe02, -0x5d9,0x5b4,0x1102,0x5f2,0x5b7,0x1802,0x5e9,0x5c1,0x1902,0x5e9,0x5c2,0xfb49,0x1843,0x5e9,0x5bc,0x5c1, -0xfb49,0x1943,0x5e9,0x5bc,0x5c2,0x1102,0x5d0,0x5b7,0x1202,0x5d0,0x5b8,0x1502,0x5d0,0x5bc,0x1502,0x5d1, -0x5bc,0x1502,0x5d2,0x5bc,0x1502,0x5d3,0x5bc,0x1502,0x5d4,0x5bc,0x1502,0x5d5,0x5bc,0x1502,0x5d6,0x5bc, -0x1502,0x5d8,0x5bc,0x1502,0x5d9,0x5bc,0x1502,0x5da,0x5bc,0x1502,0x5db,0x5bc,0x1502,0x5dc,0x5bc,0x1502, -0x5de,0x5bc,0x1502,0x5e0,0x5bc,0x1502,0x5e1,0x5bc,0x1502,0x5e3,0x5bc,0x1502,0x5e4,0x5bc,0x1502,0x5e6, -0x5bc,0x1502,0x5e7,0x5bc,0x1502,0x5e8,0x5bc,0x1502,0x5e9,0x5bc,0x1502,0x5ea,0x5bc,0x1302,0x5d5,0x5b9, -0x1702,0x5d1,0x5bf,0x1702,0x5db,0x5bf,0x1702,0x5e4,0x5bf,0xd804,0xd834,0xdd57,0xd834,0xdd65,0xd804,0xd834, -0xdd58,0xd834,0xdd65,0xd834,0xdd5f,0xd834,0xdd6e,4,0xd846,0xd834,0xdd58,0xd834,0xdd65,0xd834,0xdd6e,0xd834, -0xdd5f,0xd834,0xdd6f,4,0xd846,0xd834,0xdd58,0xd834,0xdd65,0xd834,0xdd6f,0xd834,0xdd5f,0xd834,0xdd70,4, -0xd846,0xd834,0xdd58,0xd834,0xdd65,0xd834,0xdd70,0xd834,0xdd5f,0xd834,0xdd71,4,0xd846,0xd834,0xdd58,0xd834, -0xdd65,0xd834,0xdd71,0xd834,0xdd5f,0xd834,0xdd72,4,0xd846,0xd834,0xdd58,0xd834,0xdd65,0xd834,0xdd72,0xd804, -0xd834,0xddb9,0xd834,0xdd65,0xd804,0xd834,0xddba,0xd834,0xdd65,0xd834,0xddbb,0xd834,0xdd6e,4,0xd846,0xd834, -0xddb9,0xd834,0xdd65,0xd834,0xdd6e,0xd834,0xddbc,0xd834,0xdd6e,4,0xd846,0xd834,0xddba,0xd834,0xdd65,0xd834, -0xdd6e,0xd834,0xddbb,0xd834,0xdd6f,4,0xd846,0xd834,0xddb9,0xd834,0xdd65,0xd834,0xdd6f,0xd834,0xddbc,0xd834, -0xdd6f,4,0xd846,0xd834,0xddba,0xd834,0xdd65,0xd834,0xdd6f,1,0x4e3d,1,0x4e38,1,0x4e41,2, -0xd840,0xdd22,1,0x4f60,1,0x4fbb,1,0x5002,1,0x507a,1,0x5099,1,0x50cf,1,0x349e, -2,0xd841,0xde3a,1,0x5154,1,0x5164,1,0x5177,2,0xd841,0xdd1c,1,0x34b9,1,0x5167, -1,0x518d,2,0xd841,0xdd4b,1,0x5197,1,0x51a4,1,0x4ecc,1,0x51ac,2,0xd864,0xdddf, -1,0x51f5,1,0x5203,1,0x34df,1,0x523b,1,0x5246,1,0x5272,1,0x5277,1,0x3515, -1,0x5305,1,0x5306,1,0x5349,1,0x535a,1,0x5373,1,0x537d,1,0x537f,2,0xd842, -0xde2c,1,0x7070,1,0x53ca,1,0x53df,2,0xd842,0xdf63,1,0x53eb,1,0x53f1,1,0x5406, -1,0x549e,1,0x5438,1,0x5448,1,0x5468,1,0x54a2,1,0x54f6,1,0x5510,1,0x5553, -1,0x5563,1,0x5584,1,0x55ab,1,0x55b3,1,0x55c2,1,0x5716,1,0x5717,1,0x5651, -1,0x5674,1,0x58ee,1,0x57ce,1,0x57f4,1,0x580d,1,0x578b,1,0x5832,1,0x5831, -1,0x58ac,2,0xd845,0xdce4,1,0x58f2,1,0x58f7,1,0x5906,1,0x591a,1,0x5922,1, -0x5962,2,0xd845,0xdea8,2,0xd845,0xdeea,1,0x59ec,1,0x5a1b,1,0x5a27,1,0x59d8,1, -0x5a66,1,0x36ee,1,0x36fc,1,0x5b08,1,0x5b3e,2,0xd846,0xddc8,1,0x5bc3,1,0x5bd8, -1,0x5bf3,2,0xd846,0xdf18,1,0x5bff,1,0x5c06,1,0x5f53,1,0x5c22,1,0x3781,1, -0x5c60,1,0x5cc0,1,0x5c8d,2,0xd847,0xdde4,1,0x5d43,2,0xd847,0xdde6,1,0x5d6e,1, -0x5d6b,1,0x5d7c,1,0x5de1,1,0x5de2,1,0x382f,1,0x5dfd,1,0x5e28,1,0x5e3d,1, -0x5e69,1,0x3862,2,0xd848,0xdd83,1,0x387c,1,0x5eb0,1,0x5eb3,1,0x5eb6,2,0xd868, -0xdf92,1,0x5efe,2,0xd848,0xdf31,1,0x8201,1,0x5f22,1,0x38c7,2,0xd84c,0xdeb8,2, -0xd858,0xddda,1,0x5f62,1,0x5f6b,1,0x38e3,1,0x5f9a,1,0x5fcd,1,0x5fd7,1,0x5ff9, -1,0x6081,1,0x393a,1,0x391c,2,0xd849,0xded4,1,0x60c7,1,0x6148,1,0x614c,1, -0x617a,1,0x61b2,1,0x61a4,1,0x61af,1,0x61de,1,0x6210,1,0x621b,1,0x625d,1, -0x62b1,1,0x62d4,1,0x6350,2,0xd84a,0xdf0c,1,0x633d,1,0x62fc,1,0x6368,1,0x6383, -1,0x63e4,2,0xd84a,0xdff1,1,0x6422,1,0x63c5,1,0x63a9,1,0x3a2e,1,0x6469,1, -0x647e,1,0x649d,1,0x6477,1,0x3a6c,1,0x656c,2,0xd84c,0xdc0a,1,0x65e3,1,0x66f8, -1,0x6649,1,0x3b19,1,0x3b08,1,0x3ae4,1,0x5192,1,0x5195,1,0x6700,1,0x669c, -1,0x80ad,1,0x43d9,1,0x6721,1,0x675e,1,0x6753,2,0xd84c,0xdfc3,1,0x3b49,1, -0x67fa,1,0x6785,1,0x6852,2,0xd84d,0xdc6d,1,0x688e,1,0x681f,1,0x6914,1,0x6942, -1,0x69a3,1,0x69ea,1,0x6aa8,2,0xd84d,0xdea3,1,0x6adb,1,0x3c18,1,0x6b21,2, -0xd84e,0xdca7,1,0x6b54,1,0x3c4e,1,0x6b72,1,0x6b9f,1,0x6bbb,2,0xd84e,0xde8d,2, -0xd847,0xdd0b,2,0xd84e,0xdefa,1,0x6c4e,2,0xd84f,0xdcbc,1,0x6cbf,1,0x6ccd,1,0x6c67, -1,0x6d16,1,0x6d3e,1,0x6d69,1,0x6d78,1,0x6d85,2,0xd84f,0xdd1e,1,0x6d34,1, -0x6e2f,1,0x6e6e,1,0x3d33,1,0x6ec7,2,0xd84f,0xded1,1,0x6df9,1,0x6f6e,2,0xd84f, -0xdf5e,2,0xd84f,0xdf8e,1,0x6fc6,1,0x7039,1,0x701b,1,0x3d96,1,0x704a,1,0x707d, -1,0x7077,1,0x70ad,2,0xd841,0xdd25,1,0x7145,2,0xd850,0xde63,1,0x719c,2,0xd850, -0xdfab,1,0x7228,1,0x7250,2,0xd851,0xde08,1,0x7280,1,0x7295,2,0xd851,0xdf35,2, -0xd852,0xdc14,1,0x737a,1,0x738b,1,0x3eac,1,0x73a5,1,0x3eb8,1,0x7447,1,0x745c, -1,0x7485,1,0x74ca,1,0x3f1b,1,0x7524,2,0xd853,0xdc36,1,0x753e,2,0xd853,0xdc92, -2,0xd848,0xdd9f,1,0x7610,2,0xd853,0xdfa1,2,0xd853,0xdfb8,2,0xd854,0xdc44,1,0x3ffc, -1,0x4008,2,0xd854,0xdcf3,2,0xd854,0xdcf2,2,0xd854,0xdd19,2,0xd854,0xdd33,1,0x771e, -1,0x771f,1,0x778b,1,0x4046,1,0x4096,2,0xd855,0xdc1d,1,0x784e,1,0x40e3,2, -0xd855,0xde26,2,0xd855,0xde9a,2,0xd855,0xdec5,1,0x79eb,1,0x412f,1,0x7a4a,1,0x7a4f, -2,0xd856,0xdd7c,2,0xd856,0xdea7,1,0x7aee,1,0x4202,2,0xd856,0xdfab,1,0x7bc6,1, -0x7bc9,1,0x4227,2,0xd857,0xdc80,1,0x7cd2,1,0x42a0,1,0x7ce8,1,0x7ce3,1,0x7d00, -2,0xd857,0xdf86,1,0x7d63,1,0x4301,1,0x7dc7,1,0x7e02,1,0x7e45,1,0x4334,2, -0xd858,0xde28,2,0xd858,0xde47,1,0x4359,2,0xd858,0xded9,1,0x7f7a,2,0xd858,0xdf3e,1, -0x7f95,1,0x7ffa,2,0xd859,0xdcda,2,0xd859,0xdd23,1,0x8060,2,0xd859,0xdda8,1,0x8070, -2,0xd84c,0xdf5f,1,0x43d5,1,0x80b2,1,0x8103,1,0x440b,1,0x813e,1,0x5ab5,2, -0xd859,0xdfa7,2,0xd859,0xdfb5,2,0xd84c,0xdf93,2,0xd84c,0xdf9c,1,0x8204,1,0x8f9e,1, -0x446b,1,0x8291,1,0x828b,1,0x829d,1,0x52b3,1,0x82b1,1,0x82b3,1,0x82bd,1, -0x82e6,2,0xd85a,0xdf3c,1,0x831d,1,0x8363,1,0x83ad,1,0x8323,1,0x83bd,1,0x83e7, -1,0x8353,1,0x83ca,1,0x83cc,1,0x83dc,2,0xd85b,0xdc36,2,0xd85b,0xdd6b,2,0xd85b, -0xdcd5,1,0x452b,1,0x84f1,1,0x84f3,1,0x8516,2,0xd85c,0xdfca,1,0x8564,2,0xd85b, -0xdf2c,1,0x455d,1,0x4561,2,0xd85b,0xdfb1,2,0xd85c,0xdcd2,1,0x456b,1,0x8650,1, -0x8667,1,0x8669,1,0x86a9,1,0x8688,1,0x870e,1,0x86e2,1,0x8728,1,0x876b,1, -0x8786,1,0x45d7,1,0x87e1,1,0x8801,1,0x45f9,1,0x8860,1,0x8863,2,0xd85d,0xde67, -1,0x88d7,1,0x88de,1,0x4635,1,0x88fa,1,0x34bb,2,0xd85e,0xdcae,2,0xd85e,0xdd66, -1,0x46be,1,0x46c7,1,0x8aa0,1,0x8c55,2,0xd85f,0xdca8,1,0x8cab,1,0x8cc1,1, -0x8d1b,1,0x8d77,2,0xd85f,0xdf2f,2,0xd842,0xdc04,1,0x8dcb,1,0x8dbc,1,0x8df0,2, -0xd842,0xdcde,1,0x8ed4,2,0xd861,0xddd2,2,0xd861,0xdded,1,0x9094,1,0x90f1,1,0x9111, -2,0xd861,0xdf2e,1,0x911b,1,0x9238,1,0x92d7,1,0x92d8,1,0x927c,1,0x93f9,1, -0x9415,2,0xd862,0xdffa,1,0x958b,1,0x4995,1,0x95b7,2,0xd863,0xdd77,1,0x49e6,1, -0x96c3,1,0x5db2,1,0x9723,2,0xd864,0xdd45,2,0xd864,0xde1a,1,0x4a6e,1,0x4a76,1, -0x97e0,2,0xd865,0xdc0a,1,0x4ab2,2,0xd865,0xdc96,1,0x9829,2,0xd865,0xddb6,1,0x98e2, -1,0x4b33,1,0x9929,1,0x99a7,1,0x99c2,1,0x99fe,1,0x4bce,2,0xd866,0xdf30,1, -0x9c40,1,0x9cfd,1,0x4cce,1,0x4ced,1,0x9d67,2,0xd868,0xdcce,1,0x4cf8,2,0xd868, -0xdd05,2,0xd868,0xde0e,2,0xd868,0xde91,1,0x9ebb,1,0x4d56,1,0x9ef9,1,0x9efe,1, -0x9f05,1,0x9f0f,1,0x9f16,1,0x9f3b,2,0xd869,0xde00 +0x2c02,0x2978,0x348b,0x2e82,0x2976,0xb48b,0x2f42,0x297c,0xb48b,0x6bc2,0x2b74,0xb48b,0x6bc2,0x2b76,2,0xe602, +0x41,0x302,0x600,0x3d4c,0x602,0x3d48,0x606,0x3d54,0x8612,0x3d50,0xe602,0x41,0x308,0x8608,0x3bc,0xe602, +0x41,0x30a,0x8602,0x3f4,0xca02,0x43,0x327,0x8602,0x3c10,0xe602,0x45,0x302,0x600,0x3d80,0x602,0x3d7c, +0x606,0x3d88,0x8612,0x3d84,0xe602,0x49,0x308,0x8602,0x3c5c,0xe602,0x4f,0x302,0x600,0x3da4,0x602,0x3da0, +0x606,0x3dac,0x8612,0x3da8,0xe602,0x4f,0x303,0x602,0x3c98,0x608,0x458,0x8610,0x3c9c,0xe602,0x4f,0x308, +0x8608,0x454,0xe602,0x55,0x308,0x600,0x3b6,0x602,0x3ae,0x608,0x3aa,0x8618,0x3b2,0xe602,0x61,0x302, +0x600,0x3d4e,0x602,0x3d4a,0x606,0x3d56,0x8612,0x3d52,0xe602,0x61,0x308,0x8608,0x3be,0xe602,0x61,0x30a, +0x8602,0x3f6,0xca02,0x63,0x327,0x8602,0x3c12,0xe602,0x65,0x302,0x600,0x3d82,0x602,0x3d7e,0x606,0x3d8a, +0x8612,0x3d86,0xe602,0x69,0x308,0x8602,0x3c5e,0xe602,0x6f,0x302,0x600,0x3da6,0x602,0x3da2,0x606,0x3dae, +0x8612,0x3daa,0xe602,0x6f,0x303,0x602,0x3c9a,0x608,0x45a,0x8610,0x3c9e,0xe602,0x6f,0x308,0x8608,0x456, +0xe602,0x75,0x308,0x600,0x3b8,0x602,0x3b0,0x608,0x3ac,0x8618,0x3b4,0xe602,0x41,0x306,0x600,0x3d60, +0x602,0x3d5c,0x606,0x3d68,0x8612,0x3d64,0xe602,0x61,0x306,0x600,0x3d62,0x602,0x3d5e,0x606,0x3d6a,0x8612, +0x3d66,0xe602,0x45,0x304,0x600,0x3c28,0x8602,0x3c2c,0xe602,0x65,0x304,0x600,0x3c2a,0x8602,0x3c2e,0xe602, +0x4f,0x304,0x600,0x3ca0,0x8602,0x3ca4,0xe602,0x6f,0x304,0x600,0x3ca2,0x8602,0x3ca6,0xe602,0x53,0x301, +0x860e,0x3cc8,0xe602,0x73,0x301,0x860e,0x3cca,0xe602,0x53,0x30c,0x860e,0x3ccc,0xe602,0x73,0x30c,0x860e, +0x3cce,0xe602,0x55,0x303,0x8602,0x3cf0,0xe602,0x75,0x303,0x8602,0x3cf2,0xe602,0x55,0x304,0x8610,0x3cf4, +0xe602,0x75,0x304,0x8610,0x3cf6,0xd802,0x4f,0x31b,0x600,0x3db8,0x602,0x3db4,0x606,0x3dc0,0x612,0x3dbc, +0x8646,0x3dc4,0xd802,0x6f,0x31b,0x600,0x3dba,0x602,0x3db6,0x606,0x3dc2,0x612,0x3dbe,0x8646,0x3dc6,0xd802, +0x55,0x31b,0x600,0x3dd4,0x602,0x3dd0,0x606,0x3ddc,0x612,0x3dd8,0x8646,0x3de0,0xd802,0x75,0x31b,0x600, +0x3dd6,0x602,0x3dd2,0x606,0x3dde,0x612,0x3dda,0x8646,0x3de2,0xca02,0x4f,0x328,0x8608,0x3d8,0xca02,0x6f, +0x328,0x8608,0x3da,0xe602,0x41,0x307,0x8608,0x3c0,0xe602,0x61,0x307,0x8608,0x3c2,0xca02,0x45,0x327, +0x860c,0x3c38,0xca02,0x65,0x327,0x860c,0x3c3a,0xe602,0x4f,0x307,0x8608,0x460,0xe602,0x6f,0x307,0x8608, +0x462,0xe602,0x3b1,0x301,0x868a,0x3f68,0xe602,0x3b7,0x301,0x868a,0x3f88,0xe602,0x3b9,0x308,0x600,0x3fa4, +0x602,0x720,0x8684,0x3fae,0xe602,0x3c5,0x308,0x600,0x3fc4,0x602,0x760,0x8684,0x3fce,0xe602,0x3c9,0x301, +0x868a,0x3fe8,2,0xcc6,0xcc2,0x99aa,0x1996,2,0xdd9,0xdcf,0x9b94,0x1bba,0xdc02,0x4c,0x323,0x8608, +0x3c70,0xdc02,0x6c,0x323,0x8608,0x3c72,0xdc02,0x52,0x323,0x8608,0x3cb8,0xdc02,0x72,0x323,0x8608,0x3cba, +0xdc02,0x53,0x323,0x860e,0x3cd0,0xdc02,0x73,0x323,0x860e,0x3cd2,0xdc02,0x41,0x323,0x604,0x3d58,0x860c, +0x3d6c,0xdc02,0x61,0x323,0x604,0x3d5a,0x860c,0x3d6e,0xdc02,0x45,0x323,0x8604,0x3d8c,0xdc02,0x65,0x323, +0x8604,0x3d8e,0xdc02,0x4f,0x323,0x8604,0x3db0,0xdc02,0x6f,0x323,0x8604,0x3db2,0xe602,0x3b1,0x313,0x600, +0x3e05,0x602,0x3e09,0x684,0x3e0d,0x868a,0x3f00,0xe602,0x3b1,0x314,0x600,0x3e07,0x602,0x3e0b,0x684,0x3e0f, +0x868a,0x3f02,0x1f00,0xe643,0x3b1,0x313,0x300,0x868a,0x3f04,0x1f01,0xe643,0x3b1,0x314,0x300,0x868a,0x3f06, +0x1f00,0xe643,0x3b1,0x313,0x301,0x868a,0x3f08,0x1f01,0xe643,0x3b1,0x314,0x301,0x868a,0x3f0a,0x1f00,0xe643, +0x3b1,0x313,0x342,0x868a,0x3f0c,0x1f01,0xe643,0x3b1,0x314,0x342,0x868a,0x3f0e,0xe602,0x391,0x313,0x600, +0x3e15,0x602,0x3e19,0x684,0x3e1d,0x868a,0x3f10,0xe602,0x391,0x314,0x600,0x3e17,0x602,0x3e1b,0x684,0x3e1f, +0x868a,0x3f12,0x1f08,0xe643,0x391,0x313,0x300,0x868a,0x3f14,0x1f09,0xe643,0x391,0x314,0x300,0x868a,0x3f16, +0x1f08,0xe643,0x391,0x313,0x301,0x868a,0x3f18,0x1f09,0xe643,0x391,0x314,0x301,0x868a,0x3f1a,0x1f08,0xe643, +0x391,0x313,0x342,0x868a,0x3f1c,0x1f09,0xe643,0x391,0x314,0x342,0x868a,0x3f1e,0xe602,0x3b5,0x313,0x600, +0x3e24,0x8602,0x3e28,0xe602,0x3b5,0x314,0x600,0x3e26,0x8602,0x3e2a,0xe602,0x395,0x313,0x600,0x3e34,0x8602, +0x3e38,0xe602,0x395,0x314,0x600,0x3e36,0x8602,0x3e3a,0xe602,0x3b7,0x313,0x600,0x3e45,0x602,0x3e49,0x684, +0x3e4d,0x868a,0x3f20,0xe602,0x3b7,0x314,0x600,0x3e47,0x602,0x3e4b,0x684,0x3e4f,0x868a,0x3f22,0x1f20,0xe643, +0x3b7,0x313,0x300,0x868a,0x3f24,0x1f21,0xe643,0x3b7,0x314,0x300,0x868a,0x3f26,0x1f20,0xe643,0x3b7,0x313, +0x301,0x868a,0x3f28,0x1f21,0xe643,0x3b7,0x314,0x301,0x868a,0x3f2a,0x1f20,0xe643,0x3b7,0x313,0x342,0x868a, +0x3f2c,0x1f21,0xe643,0x3b7,0x314,0x342,0x868a,0x3f2e,0xe602,0x397,0x313,0x600,0x3e55,0x602,0x3e59,0x684, +0x3e5d,0x868a,0x3f30,0xe602,0x397,0x314,0x600,0x3e57,0x602,0x3e5b,0x684,0x3e5f,0x868a,0x3f32,0x1f28,0xe643, +0x397,0x313,0x300,0x868a,0x3f34,0x1f29,0xe643,0x397,0x314,0x300,0x868a,0x3f36,0x1f28,0xe643,0x397,0x313, +0x301,0x868a,0x3f38,0x1f29,0xe643,0x397,0x314,0x301,0x868a,0x3f3a,0x1f28,0xe643,0x397,0x313,0x342,0x868a, +0x3f3c,0x1f29,0xe643,0x397,0x314,0x342,0x868a,0x3f3e,0xe602,0x3b9,0x313,0x600,0x3e64,0x602,0x3e68,0x8684, +0x3e6c,0xe602,0x3b9,0x314,0x600,0x3e66,0x602,0x3e6a,0x8684,0x3e6e,0xe602,0x399,0x313,0x600,0x3e74,0x602, +0x3e78,0x8684,0x3e7c,0xe602,0x399,0x314,0x600,0x3e76,0x602,0x3e7a,0x8684,0x3e7e,0xe602,0x3bf,0x313,0x600, +0x3e84,0x8602,0x3e88,0xe602,0x3bf,0x314,0x600,0x3e86,0x8602,0x3e8a,0xe602,0x39f,0x313,0x600,0x3e94,0x8602, +0x3e98,0xe602,0x39f,0x314,0x600,0x3e96,0x8602,0x3e9a,0xe602,0x3c5,0x313,0x600,0x3ea4,0x602,0x3ea8,0x8684, +0x3eac,0xe602,0x3c5,0x314,0x600,0x3ea6,0x602,0x3eaa,0x8684,0x3eae,0xe602,0x3a5,0x314,0x600,0x3eb6,0x602, +0x3eba,0x8684,0x3ebe,0xe602,0x3c9,0x313,0x600,0x3ec5,0x602,0x3ec9,0x684,0x3ecd,0x868a,0x3f40,0xe602,0x3c9, +0x314,0x600,0x3ec7,0x602,0x3ecb,0x684,0x3ecf,0x868a,0x3f42,0x1f60,0xe643,0x3c9,0x313,0x300,0x868a,0x3f44, +0x1f61,0xe643,0x3c9,0x314,0x300,0x868a,0x3f46,0x1f60,0xe643,0x3c9,0x313,0x301,0x868a,0x3f48,0x1f61,0xe643, +0x3c9,0x314,0x301,0x868a,0x3f4a,0x1f60,0xe643,0x3c9,0x313,0x342,0x868a,0x3f4c,0x1f61,0xe643,0x3c9,0x314, +0x342,0x868a,0x3f4e,0xe602,0x3a9,0x313,0x600,0x3ed5,0x602,0x3ed9,0x684,0x3edd,0x868a,0x3f50,0xe602,0x3a9, +0x314,0x600,0x3ed7,0x602,0x3edb,0x684,0x3edf,0x868a,0x3f52,0x1f68,0xe643,0x3a9,0x313,0x300,0x868a,0x3f54, +0x1f69,0xe643,0x3a9,0x314,0x300,0x868a,0x3f56,0x1f68,0xe643,0x3a9,0x313,0x301,0x868a,0x3f58,0x1f69,0xe643, +0x3a9,0x314,0x301,0x868a,0x3f5a,0x1f68,0xe643,0x3a9,0x313,0x342,0x868a,0x3f5c,0x1f69,0xe643,0x3a9,0x314, +0x342,0x868a,0x3f5e,0xe602,0x3b1,0x300,0x868a,0x3f64,0xe602,0x3b7,0x300,0x868a,0x3f84,0xe602,0x3c9,0x300, +0x868a,0x3fe4,0xe602,0x3b1,0x342,0x868a,0x3f6e,0xe602,0x3b7,0x342,0x868a,0x3f8e,0xe602,0x3c9,0x342,0x868a, +0x3fee,3,0xe602,0x41,0x300,0xe602,0x41,0x301,0xe602,0x41,0x303,0xe602,0x45,0x300,0xe602,0x45, +0x301,0xe602,0x45,0x308,0xe602,0x49,0x300,0xe602,0x49,0x301,0xe602,0x49,0x302,0xe602,0x4e,0x303, +0xe602,0x4f,0x300,0xe602,0x4f,0x301,0xe602,0x55,0x300,0xe602,0x55,0x301,0xe602,0x55,0x302,0xe602, +0x59,0x301,0xe602,0x61,0x300,0xe602,0x61,0x301,0xe602,0x61,0x303,0xe602,0x65,0x300,0xe602,0x65, +0x301,0xe602,0x65,0x308,0xe602,0x69,0x300,0xe602,0x69,0x301,0xe602,0x69,0x302,0xe602,0x6e,0x303, +0xe602,0x6f,0x300,0xe602,0x6f,0x301,0xe602,0x75,0x300,0xe602,0x75,0x301,0xe602,0x75,0x302,0xe602, +0x79,0x301,0xe602,0x79,0x308,0xe602,0x41,0x304,0xe602,0x61,0x304,0xca02,0x41,0x328,0xca02,0x61, +0x328,0xe602,0x43,0x301,0xe602,0x63,0x301,0xe602,0x43,0x302,0xe602,0x63,0x302,0xe602,0x43,0x307, +0xe602,0x63,0x307,0xe602,0x43,0x30c,0xe602,0x63,0x30c,0xe602,0x44,0x30c,0xe602,0x64,0x30c,0xe602, +0x45,0x306,0xe602,0x65,0x306,0xe602,0x45,0x307,0xe602,0x65,0x307,0xca02,0x45,0x328,0xca02,0x65, +0x328,0xe602,0x45,0x30c,0xe602,0x65,0x30c,0xe602,0x47,0x302,0xe602,0x67,0x302,0xe602,0x47,0x306, +0xe602,0x67,0x306,0xe602,0x47,0x307,0xe602,0x67,0x307,0xca02,0x47,0x327,0xca02,0x67,0x327,0xe602, +0x48,0x302,0xe602,0x68,0x302,0xe602,0x49,0x303,0xe602,0x69,0x303,0xe602,0x49,0x304,0xe602,0x69, +0x304,0xe602,0x49,0x306,0xe602,0x69,0x306,0xca02,0x49,0x328,0xca02,0x69,0x328,0xe602,0x49,0x307, +0xe602,0x4a,0x302,0xe602,0x6a,0x302,0xca02,0x4b,0x327,0xca02,0x6b,0x327,0xe602,0x4c,0x301,0xe602, +0x6c,0x301,0xca02,0x4c,0x327,0xca02,0x6c,0x327,0xe602,0x4c,0x30c,0xe602,0x6c,0x30c,0xe602,0x4e, +0x301,0xe602,0x6e,0x301,0xca02,0x4e,0x327,0xca02,0x6e,0x327,0xe602,0x4e,0x30c,0xe602,0x6e,0x30c, +0xe602,0x4f,0x306,0xe602,0x6f,0x306,0xe602,0x4f,0x30b,0xe602,0x6f,0x30b,0xe602,0x52,0x301,0xe602, +0x72,0x301,0xca02,0x52,0x327,0xca02,0x72,0x327,0xe602,0x52,0x30c,0xe602,0x72,0x30c,0xe602,0x53, +0x302,0xe602,0x73,0x302,0xca02,0x53,0x327,0xca02,0x73,0x327,0xca02,0x54,0x327,0xca02,0x74,0x327, +0xe602,0x54,0x30c,0xe602,0x74,0x30c,0xe602,0x55,0x306,0xe602,0x75,0x306,0xe602,0x55,0x30a,0xe602, +0x75,0x30a,0xe602,0x55,0x30b,0xe602,0x75,0x30b,0xca02,0x55,0x328,0xca02,0x75,0x328,0xe602,0x57, +0x302,0xe602,0x77,0x302,0xe602,0x59,0x302,0xe602,0x79,0x302,0xe602,0x59,0x308,0xe602,0x5a,0x301, +0xe602,0x7a,0x301,0xe602,0x5a,0x307,0xe602,0x7a,0x307,0xe602,0x5a,0x30c,0xe602,0x7a,0x30c,0xe602, +0x41,0x30c,0xe602,0x61,0x30c,0xe602,0x49,0x30c,0xe602,0x69,0x30c,0xe602,0x4f,0x30c,0xe602,0x6f, +0x30c,0xe602,0x55,0x30c,0xe602,0x75,0x30c,0xdc,0xe643,0x55,0x308,0x304,0xfc,0xe643,0x75,0x308, +0x304,0xdc,0xe643,0x55,0x308,0x301,0xfc,0xe643,0x75,0x308,0x301,0xdc,0xe643,0x55,0x308,0x30c, +0xfc,0xe643,0x75,0x308,0x30c,0xdc,0xe643,0x55,0x308,0x300,0xfc,0xe643,0x75,0x308,0x300,0xc4, +0xe643,0x41,0x308,0x304,0xe4,0xe643,0x61,0x308,0x304,0x226,0xe643,0x41,0x307,0x304,0x227,0xe643, +0x61,0x307,0x304,0xe602,0xc6,0x304,0xe602,0xe6,0x304,0xe602,0x47,0x30c,0xe602,0x67,0x30c,0xe602, +0x4b,0x30c,0xe602,0x6b,0x30c,0x1ea,0xe643,0x4f,0x328,0x304,0x1eb,0xe643,0x6f,0x328,0x304,0xe602, +0x1b7,0x30c,0xe602,0x292,0x30c,0xe602,0x6a,0x30c,0xe602,0x47,0x301,0xe602,0x67,0x301,0xe602,0x4e, +0x300,0xe602,0x6e,0x300,0xc5,0xe643,0x41,0x30a,0x301,0xe5,0xe643,0x61,0x30a,0x301,0xe602,0xc6, +0x301,0xe602,0xe6,0x301,0xe602,0xd8,0x301,0xe602,0xf8,0x301,0xe602,0x41,0x30f,0xe602,0x61,0x30f, +0xe602,0x41,0x311,0xe602,0x61,0x311,0xe602,0x45,0x30f,0xe602,0x65,0x30f,0xe602,0x45,0x311,0xe602, +0x65,0x311,0xe602,0x49,0x30f,0xe602,0x69,0x30f,0xe602,0x49,0x311,0xe602,0x69,0x311,0xe602,0x4f, +0x30f,0xe602,0x6f,0x30f,0xe602,0x4f,0x311,0xe602,0x6f,0x311,0xe602,0x52,0x30f,0xe602,0x72,0x30f, +0xe602,0x52,0x311,0xe602,0x72,0x311,0xe602,0x55,0x30f,0xe602,0x75,0x30f,0xe602,0x55,0x311,0xe602, +0x75,0x311,0xdc02,0x53,0x326,0xdc02,0x73,0x326,0xdc02,0x54,0x326,0xdc02,0x74,0x326,0xe602,0x48, +0x30c,0xe602,0x68,0x30c,0xd6,0xe643,0x4f,0x308,0x304,0xf6,0xe643,0x6f,0x308,0x304,0xd5,0xe643, +0x4f,0x303,0x304,0xf5,0xe643,0x6f,0x303,0x304,0x22e,0xe643,0x4f,0x307,0x304,0x22f,0xe643,0x6f, +0x307,0x304,0xe602,0x59,0x304,0xe602,0x79,0x304,0xe602,0xa8,0x301,0xe602,0x391,0x301,0xe602,0x395, +0x301,0xe602,0x397,0x301,0xe602,0x399,0x301,0xe602,0x39f,0x301,0xe602,0x3a5,0x301,0xe602,0x3a9,0x301, +0x3ca,0xe643,0x3b9,0x308,0x301,0xe602,0x399,0x308,0xe602,0x3a5,0x308,0xe602,0x3b5,0x301,0xe602,0x3b9, +0x301,0x3cb,0xe643,0x3c5,0x308,0x301,0xe602,0x3bf,0x301,0xe602,0x3c5,0x301,0xe602,0x3d2,0x301,0xe602, +0x3d2,0x308,0xe602,0x415,0x300,0xe602,0x415,0x308,0xe602,0x413,0x301,0xe602,0x406,0x308,0xe602,0x41a, +0x301,0xe602,0x418,0x300,0xe602,0x423,0x306,0xe602,0x418,0x306,0xe602,0x438,0x306,0xe602,0x435,0x300, +0xe602,0x435,0x308,0xe602,0x433,0x301,0xe602,0x456,0x308,0xe602,0x43a,0x301,0xe602,0x438,0x300,0xe602, +0x443,0x306,0xe602,0x474,0x30f,0xe602,0x475,0x30f,0xe602,0x416,0x306,0xe602,0x436,0x306,0xe602,0x410, +0x306,0xe602,0x430,0x306,0xe602,0x410,0x308,0xe602,0x430,0x308,0xe602,0x415,0x306,0xe602,0x435,0x306, +0xe602,0x4d8,0x308,0xe602,0x4d9,0x308,0xe602,0x416,0x308,0xe602,0x436,0x308,0xe602,0x417,0x308,0xe602, +0x437,0x308,0xe602,0x418,0x304,0xe602,0x438,0x304,0xe602,0x418,0x308,0xe602,0x438,0x308,0xe602,0x41e, +0x308,0xe602,0x43e,0x308,0xe602,0x4e8,0x308,0xe602,0x4e9,0x308,0xe602,0x42d,0x308,0xe602,0x44d,0x308, +0xe602,0x423,0x304,0xe602,0x443,0x304,0xe602,0x423,0x308,0xe602,0x443,0x308,0xe602,0x423,0x30b,0xe602, +0x443,0x30b,0xe602,0x427,0x308,0xe602,0x447,0x308,0xe602,0x42b,0x308,0xe602,0x44b,0x308,0xe602,0x627, +0x653,0xe602,0x627,0x654,0xe602,0x648,0x654,0xdc02,0x627,0x655,0xe602,0x64a,0x654,0xe602,0x6d5,0x654, +0xe602,0x6c1,0x654,0xe602,0x6d2,0x654,0x702,0x928,0x93c,0x702,0x930,0x93c,0x702,0x933,0x93c,2, +0x9c7,0x9be,2,0x9c7,0x9d7,2,0xb47,0xb56,2,0xb47,0xb3e,2,0xb47,0xb57,2,0xb92, +0xbd7,2,0xbc6,0xbbe,2,0xbc7,0xbbe,2,0xbc6,0xbd7,0x5b02,0xc46,0xc56,2,0xcbf,0xcd5, +2,0xcc6,0xcd5,2,0xcc6,0xcd6,0xcca,0x43,0xcc6,0xcc2,0xcd5,2,0xd46,0xd3e,2,0xd47, +0xd3e,2,0xd46,0xd57,0x902,0xdd9,0xdca,0xddc,0x943,0xdd9,0xdcf,0xdca,2,0xdd9,0xddf,2, +0x1025,0x102e,2,0x1b05,0x1b35,2,0x1b07,0x1b35,2,0x1b09,0x1b35,2,0x1b0b,0x1b35,2,0x1b0d, +0x1b35,2,0x1b11,0x1b35,2,0x1b3a,0x1b35,2,0x1b3c,0x1b35,2,0x1b3e,0x1b35,2,0x1b3f,0x1b35, +2,0x1b42,0x1b35,0xdc02,0x41,0x325,0xdc02,0x61,0x325,0xe602,0x42,0x307,0xe602,0x62,0x307,0xdc02, +0x42,0x323,0xdc02,0x62,0x323,0xdc02,0x42,0x331,0xdc02,0x62,0x331,0xc7,0xe643,0x43,0x327,0x301, +0xe7,0xe643,0x63,0x327,0x301,0xe602,0x44,0x307,0xe602,0x64,0x307,0xdc02,0x44,0x323,0xdc02,0x64, +0x323,0xdc02,0x44,0x331,0xdc02,0x64,0x331,0xca02,0x44,0x327,0xca02,0x64,0x327,0xdc02,0x44,0x32d, +0xdc02,0x64,0x32d,0x112,0xe643,0x45,0x304,0x300,0x113,0xe643,0x65,0x304,0x300,0x112,0xe643,0x45, +0x304,0x301,0x113,0xe643,0x65,0x304,0x301,0xdc02,0x45,0x32d,0xdc02,0x65,0x32d,0xdc02,0x45,0x330, +0xdc02,0x65,0x330,0x228,0xe643,0x45,0x327,0x306,0x229,0xe643,0x65,0x327,0x306,0xe602,0x46,0x307, +0xe602,0x66,0x307,0xe602,0x47,0x304,0xe602,0x67,0x304,0xe602,0x48,0x307,0xe602,0x68,0x307,0xdc02, +0x48,0x323,0xdc02,0x68,0x323,0xe602,0x48,0x308,0xe602,0x68,0x308,0xca02,0x48,0x327,0xca02,0x68, +0x327,0xdc02,0x48,0x32e,0xdc02,0x68,0x32e,0xdc02,0x49,0x330,0xdc02,0x69,0x330,0xcf,0xe643,0x49, +0x308,0x301,0xef,0xe643,0x69,0x308,0x301,0xe602,0x4b,0x301,0xe602,0x6b,0x301,0xdc02,0x4b,0x323, +0xdc02,0x6b,0x323,0xdc02,0x4b,0x331,0xdc02,0x6b,0x331,0x1e36,0xe643,0x4c,0x323,0x304,0x1e37,0xe643, +0x6c,0x323,0x304,0xdc02,0x4c,0x331,0xdc02,0x6c,0x331,0xdc02,0x4c,0x32d,0xdc02,0x6c,0x32d,0xe602, +0x4d,0x301,0xe602,0x6d,0x301,0xe602,0x4d,0x307,0xe602,0x6d,0x307,0xdc02,0x4d,0x323,0xdc02,0x6d, +0x323,0xe602,0x4e,0x307,0xe602,0x6e,0x307,0xdc02,0x4e,0x323,0xdc02,0x6e,0x323,0xdc02,0x4e,0x331, +0xdc02,0x6e,0x331,0xdc02,0x4e,0x32d,0xdc02,0x6e,0x32d,0xd5,0xe643,0x4f,0x303,0x301,0xf5,0xe643, +0x6f,0x303,0x301,0xd5,0xe643,0x4f,0x303,0x308,0xf5,0xe643,0x6f,0x303,0x308,0x14c,0xe643,0x4f, +0x304,0x300,0x14d,0xe643,0x6f,0x304,0x300,0x14c,0xe643,0x4f,0x304,0x301,0x14d,0xe643,0x6f,0x304, +0x301,0xe602,0x50,0x301,0xe602,0x70,0x301,0xe602,0x50,0x307,0xe602,0x70,0x307,0xe602,0x52,0x307, +0xe602,0x72,0x307,0x1e5a,0xe643,0x52,0x323,0x304,0x1e5b,0xe643,0x72,0x323,0x304,0xdc02,0x52,0x331, +0xdc02,0x72,0x331,0xe602,0x53,0x307,0xe602,0x73,0x307,0x15a,0xe643,0x53,0x301,0x307,0x15b,0xe643, +0x73,0x301,0x307,0x160,0xe643,0x53,0x30c,0x307,0x161,0xe643,0x73,0x30c,0x307,0x1e62,0xe643,0x53, +0x323,0x307,0x1e63,0xe643,0x73,0x323,0x307,0xe602,0x54,0x307,0xe602,0x74,0x307,0xdc02,0x54,0x323, +0xdc02,0x74,0x323,0xdc02,0x54,0x331,0xdc02,0x74,0x331,0xdc02,0x54,0x32d,0xdc02,0x74,0x32d,0xdc02, +0x55,0x324,0xdc02,0x75,0x324,0xdc02,0x55,0x330,0xdc02,0x75,0x330,0xdc02,0x55,0x32d,0xdc02,0x75, +0x32d,0x168,0xe643,0x55,0x303,0x301,0x169,0xe643,0x75,0x303,0x301,0x16a,0xe643,0x55,0x304,0x308, +0x16b,0xe643,0x75,0x304,0x308,0xe602,0x56,0x303,0xe602,0x76,0x303,0xdc02,0x56,0x323,0xdc02,0x76, +0x323,0xe602,0x57,0x300,0xe602,0x77,0x300,0xe602,0x57,0x301,0xe602,0x77,0x301,0xe602,0x57,0x308, +0xe602,0x77,0x308,0xe602,0x57,0x307,0xe602,0x77,0x307,0xdc02,0x57,0x323,0xdc02,0x77,0x323,0xe602, +0x58,0x307,0xe602,0x78,0x307,0xe602,0x58,0x308,0xe602,0x78,0x308,0xe602,0x59,0x307,0xe602,0x79, +0x307,0xe602,0x5a,0x302,0xe602,0x7a,0x302,0xdc02,0x5a,0x323,0xdc02,0x7a,0x323,0xdc02,0x5a,0x331, +0xdc02,0x7a,0x331,0xdc02,0x68,0x331,0xe602,0x74,0x308,0xe602,0x77,0x30a,0xe602,0x79,0x30a,0xe602, +0x17f,0x307,0xe602,0x41,0x309,0xe602,0x61,0x309,0xc2,0xe643,0x41,0x302,0x301,0xe2,0xe643,0x61, +0x302,0x301,0xc2,0xe643,0x41,0x302,0x300,0xe2,0xe643,0x61,0x302,0x300,0xc2,0xe643,0x41,0x302, +0x309,0xe2,0xe643,0x61,0x302,0x309,0xc2,0xe643,0x41,0x302,0x303,0xe2,0xe643,0x61,0x302,0x303, +0x1ea0,0xe643,0x41,0x323,0x302,0x1ea1,0xe643,0x61,0x323,0x302,0x102,0xe643,0x41,0x306,0x301,0x103, +0xe643,0x61,0x306,0x301,0x102,0xe643,0x41,0x306,0x300,0x103,0xe643,0x61,0x306,0x300,0x102,0xe643, +0x41,0x306,0x309,0x103,0xe643,0x61,0x306,0x309,0x102,0xe643,0x41,0x306,0x303,0x103,0xe643,0x61, +0x306,0x303,0x1ea0,0xe643,0x41,0x323,0x306,0x1ea1,0xe643,0x61,0x323,0x306,0xe602,0x45,0x309,0xe602, +0x65,0x309,0xe602,0x45,0x303,0xe602,0x65,0x303,0xca,0xe643,0x45,0x302,0x301,0xea,0xe643,0x65, +0x302,0x301,0xca,0xe643,0x45,0x302,0x300,0xea,0xe643,0x65,0x302,0x300,0xca,0xe643,0x45,0x302, +0x309,0xea,0xe643,0x65,0x302,0x309,0xca,0xe643,0x45,0x302,0x303,0xea,0xe643,0x65,0x302,0x303, +0x1eb8,0xe643,0x45,0x323,0x302,0x1eb9,0xe643,0x65,0x323,0x302,0xe602,0x49,0x309,0xe602,0x69,0x309, +0xdc02,0x49,0x323,0xdc02,0x69,0x323,0xe602,0x4f,0x309,0xe602,0x6f,0x309,0xd4,0xe643,0x4f,0x302, +0x301,0xf4,0xe643,0x6f,0x302,0x301,0xd4,0xe643,0x4f,0x302,0x300,0xf4,0xe643,0x6f,0x302,0x300, +0xd4,0xe643,0x4f,0x302,0x309,0xf4,0xe643,0x6f,0x302,0x309,0xd4,0xe643,0x4f,0x302,0x303,0xf4, +0xe643,0x6f,0x302,0x303,0x1ecc,0xe643,0x4f,0x323,0x302,0x1ecd,0xe643,0x6f,0x323,0x302,0x1a0,0xe643, +0x4f,0x31b,0x301,0x1a1,0xe643,0x6f,0x31b,0x301,0x1a0,0xe643,0x4f,0x31b,0x300,0x1a1,0xe643,0x6f, +0x31b,0x300,0x1a0,0xe643,0x4f,0x31b,0x309,0x1a1,0xe643,0x6f,0x31b,0x309,0x1a0,0xe643,0x4f,0x31b, +0x303,0x1a1,0xe643,0x6f,0x31b,0x303,0x1a0,0xdc43,0x4f,0x31b,0x323,0x1a1,0xdc43,0x6f,0x31b,0x323, +0xdc02,0x55,0x323,0xdc02,0x75,0x323,0xe602,0x55,0x309,0xe602,0x75,0x309,0x1af,0xe643,0x55,0x31b, +0x301,0x1b0,0xe643,0x75,0x31b,0x301,0x1af,0xe643,0x55,0x31b,0x300,0x1b0,0xe643,0x75,0x31b,0x300, +0x1af,0xe643,0x55,0x31b,0x309,0x1b0,0xe643,0x75,0x31b,0x309,0x1af,0xe643,0x55,0x31b,0x303,0x1b0, +0xe643,0x75,0x31b,0x303,0x1af,0xdc43,0x55,0x31b,0x323,0x1b0,0xdc43,0x75,0x31b,0x323,0xe602,0x59, +0x300,0xe602,0x79,0x300,0xdc02,0x59,0x323,0xdc02,0x79,0x323,0xe602,0x59,0x309,0xe602,0x79,0x309, +0xe602,0x59,0x303,0xe602,0x79,0x303,0x1f10,0xe643,0x3b5,0x313,0x300,0x1f11,0xe643,0x3b5,0x314,0x300, +0x1f10,0xe643,0x3b5,0x313,0x301,0x1f11,0xe643,0x3b5,0x314,0x301,0x1f18,0xe643,0x395,0x313,0x300,0x1f19, +0xe643,0x395,0x314,0x300,0x1f18,0xe643,0x395,0x313,0x301,0x1f19,0xe643,0x395,0x314,0x301,0x1f30,0xe643, +0x3b9,0x313,0x300,0x1f31,0xe643,0x3b9,0x314,0x300,0x1f30,0xe643,0x3b9,0x313,0x301,0x1f31,0xe643,0x3b9, +0x314,0x301,0x1f30,0xe643,0x3b9,0x313,0x342,0x1f31,0xe643,0x3b9,0x314,0x342,0x1f38,0xe643,0x399,0x313, +0x300,0x1f39,0xe643,0x399,0x314,0x300,0x1f38,0xe643,0x399,0x313,0x301,0x1f39,0xe643,0x399,0x314,0x301, +0x1f38,0xe643,0x399,0x313,0x342,0x1f39,0xe643,0x399,0x314,0x342,0x1f40,0xe643,0x3bf,0x313,0x300,0x1f41, +0xe643,0x3bf,0x314,0x300,0x1f40,0xe643,0x3bf,0x313,0x301,0x1f41,0xe643,0x3bf,0x314,0x301,0x1f48,0xe643, +0x39f,0x313,0x300,0x1f49,0xe643,0x39f,0x314,0x300,0x1f48,0xe643,0x39f,0x313,0x301,0x1f49,0xe643,0x39f, +0x314,0x301,0x1f50,0xe643,0x3c5,0x313,0x300,0x1f51,0xe643,0x3c5,0x314,0x300,0x1f50,0xe643,0x3c5,0x313, +0x301,0x1f51,0xe643,0x3c5,0x314,0x301,0x1f50,0xe643,0x3c5,0x313,0x342,0x1f51,0xe643,0x3c5,0x314,0x342, +0x1f59,0xe643,0x3a5,0x314,0x300,0x1f59,0xe643,0x3a5,0x314,0x301,0x1f59,0xe643,0x3a5,0x314,0x342,0xe602, +0x3b5,0x300,0xe602,0x3b9,0x300,0xe602,0x3bf,0x300,0xe602,0x3c5,0x300,0x1f00,0xf043,0x3b1,0x313,0x345, +0x1f01,0xf043,0x3b1,0x314,0x345,0x1f02,0x345,2,0xf044,0x3b1,0x313,0x300,0x345,0x1f03,0x345,2, +0xf044,0x3b1,0x314,0x300,0x345,0x1f04,0x345,2,0xf044,0x3b1,0x313,0x301,0x345,0x1f05,0x345,2, +0xf044,0x3b1,0x314,0x301,0x345,0x1f06,0x345,2,0xf044,0x3b1,0x313,0x342,0x345,0x1f07,0x345,2, +0xf044,0x3b1,0x314,0x342,0x345,0x1f08,0xf043,0x391,0x313,0x345,0x1f09,0xf043,0x391,0x314,0x345,0x1f0a, +0x345,2,0xf044,0x391,0x313,0x300,0x345,0x1f0b,0x345,2,0xf044,0x391,0x314,0x300,0x345,0x1f0c, +0x345,2,0xf044,0x391,0x313,0x301,0x345,0x1f0d,0x345,2,0xf044,0x391,0x314,0x301,0x345,0x1f0e, +0x345,2,0xf044,0x391,0x313,0x342,0x345,0x1f0f,0x345,2,0xf044,0x391,0x314,0x342,0x345,0x1f20, +0xf043,0x3b7,0x313,0x345,0x1f21,0xf043,0x3b7,0x314,0x345,0x1f22,0x345,2,0xf044,0x3b7,0x313,0x300, +0x345,0x1f23,0x345,2,0xf044,0x3b7,0x314,0x300,0x345,0x1f24,0x345,2,0xf044,0x3b7,0x313,0x301, +0x345,0x1f25,0x345,2,0xf044,0x3b7,0x314,0x301,0x345,0x1f26,0x345,2,0xf044,0x3b7,0x313,0x342, +0x345,0x1f27,0x345,2,0xf044,0x3b7,0x314,0x342,0x345,0x1f28,0xf043,0x397,0x313,0x345,0x1f29,0xf043, +0x397,0x314,0x345,0x1f2a,0x345,2,0xf044,0x397,0x313,0x300,0x345,0x1f2b,0x345,2,0xf044,0x397, +0x314,0x300,0x345,0x1f2c,0x345,2,0xf044,0x397,0x313,0x301,0x345,0x1f2d,0x345,2,0xf044,0x397, +0x314,0x301,0x345,0x1f2e,0x345,2,0xf044,0x397,0x313,0x342,0x345,0x1f2f,0x345,2,0xf044,0x397, +0x314,0x342,0x345,0x1f60,0xf043,0x3c9,0x313,0x345,0x1f61,0xf043,0x3c9,0x314,0x345,0x1f62,0x345,2, +0xf044,0x3c9,0x313,0x300,0x345,0x1f63,0x345,2,0xf044,0x3c9,0x314,0x300,0x345,0x1f64,0x345,2, +0xf044,0x3c9,0x313,0x301,0x345,0x1f65,0x345,2,0xf044,0x3c9,0x314,0x301,0x345,0x1f66,0x345,2, +0xf044,0x3c9,0x313,0x342,0x345,0x1f67,0x345,2,0xf044,0x3c9,0x314,0x342,0x345,0x1f68,0xf043,0x3a9, +0x313,0x345,0x1f69,0xf043,0x3a9,0x314,0x345,0x1f6a,0x345,2,0xf044,0x3a9,0x313,0x300,0x345,0x1f6b, +0x345,2,0xf044,0x3a9,0x314,0x300,0x345,0x1f6c,0x345,2,0xf044,0x3a9,0x313,0x301,0x345,0x1f6d, +0x345,2,0xf044,0x3a9,0x314,0x301,0x345,0x1f6e,0x345,2,0xf044,0x3a9,0x313,0x342,0x345,0x1f6f, +0x345,2,0xf044,0x3a9,0x314,0x342,0x345,0xe602,0x3b1,0x306,0xe602,0x3b1,0x304,0x1f70,0xf043,0x3b1, +0x300,0x345,0xf002,0x3b1,0x345,0x3ac,0xf043,0x3b1,0x301,0x345,0x1fb6,0xf043,0x3b1,0x342,0x345,0xe602, +0x391,0x306,0xe602,0x391,0x304,0xe602,0x391,0x300,0xf002,0x391,0x345,0xe602,0xa8,0x342,0x1f74,0xf043, +0x3b7,0x300,0x345,0xf002,0x3b7,0x345,0x3ae,0xf043,0x3b7,0x301,0x345,0x1fc6,0xf043,0x3b7,0x342,0x345, +0xe602,0x395,0x300,0xe602,0x397,0x300,0xf002,0x397,0x345,0xe602,0x1fbf,0x300,0xe602,0x1fbf,0x301,0xe602, +0x1fbf,0x342,0xe602,0x3b9,0x306,0xe602,0x3b9,0x304,0x3ca,0xe643,0x3b9,0x308,0x300,0xe602,0x3b9,0x342, +0x3ca,0xe643,0x3b9,0x308,0x342,0xe602,0x399,0x306,0xe602,0x399,0x304,0xe602,0x399,0x300,0xe602,0x1ffe, +0x300,0xe602,0x1ffe,0x301,0xe602,0x1ffe,0x342,0xe602,0x3c5,0x306,0xe602,0x3c5,0x304,0x3cb,0xe643,0x3c5, +0x308,0x300,0xe602,0x3c1,0x313,0xe602,0x3c1,0x314,0xe602,0x3c5,0x342,0x3cb,0xe643,0x3c5,0x308,0x342, +0xe602,0x3a5,0x306,0xe602,0x3a5,0x304,0xe602,0x3a5,0x300,0xe602,0x3a1,0x314,0xe602,0xa8,0x300,0x1f7c, +0xf043,0x3c9,0x300,0x345,0xf002,0x3c9,0x345,0x3ce,0xf043,0x3c9,0x301,0x345,0x1ff6,0xf043,0x3c9,0x342, +0x345,0xe602,0x39f,0x300,0xe602,0x3a9,0x300,0xf002,0x3a9,0x345,0x102,0x2190,0x338,0x102,0x2192,0x338, +0x102,0x2194,0x338,0x102,0x21d0,0x338,0x102,0x21d4,0x338,0x102,0x21d2,0x338,0x102,0x2203,0x338,0x102, +0x2208,0x338,0x102,0x220b,0x338,0x102,0x2223,0x338,0x102,0x2225,0x338,0x102,0x223c,0x338,0x102,0x2243, +0x338,0x102,0x2245,0x338,0x102,0x2248,0x338,0x102,0x3d,0x338,0x102,0x2261,0x338,0x102,0x224d,0x338, +0x102,0x3c,0x338,0x102,0x3e,0x338,0x102,0x2264,0x338,0x102,0x2265,0x338,0x102,0x2272,0x338,0x102, +0x2273,0x338,0x102,0x2276,0x338,0x102,0x2277,0x338,0x102,0x227a,0x338,0x102,0x227b,0x338,0x102,0x2282, +0x338,0x102,0x2283,0x338,0x102,0x2286,0x338,0x102,0x2287,0x338,0x102,0x22a2,0x338,0x102,0x22a8,0x338, +0x102,0x22a9,0x338,0x102,0x22ab,0x338,0x102,0x227c,0x338,0x102,0x227d,0x338,0x102,0x2291,0x338,0x102, +0x2292,0x338,0x102,0x22b2,0x338,0x102,0x22b3,0x338,0x102,0x22b4,0x338,0x102,0x22b5,0x338,0x802,0x304b, +0x3099,0x802,0x304d,0x3099,0x802,0x304f,0x3099,0x802,0x3051,0x3099,0x802,0x3053,0x3099,0x802,0x3055,0x3099, +0x802,0x3057,0x3099,0x802,0x3059,0x3099,0x802,0x305b,0x3099,0x802,0x305d,0x3099,0x802,0x305f,0x3099,0x802, +0x3061,0x3099,0x802,0x3064,0x3099,0x802,0x3066,0x3099,0x802,0x3068,0x3099,0x802,0x306f,0x3099,0x802,0x306f, +0x309a,0x802,0x3072,0x3099,0x802,0x3072,0x309a,0x802,0x3075,0x3099,0x802,0x3075,0x309a,0x802,0x3078,0x3099, +0x802,0x3078,0x309a,0x802,0x307b,0x3099,0x802,0x307b,0x309a,0x802,0x3046,0x3099,0x802,0x309d,0x3099,0x802, +0x30ab,0x3099,0x802,0x30ad,0x3099,0x802,0x30af,0x3099,0x802,0x30b1,0x3099,0x802,0x30b3,0x3099,0x802,0x30b5, +0x3099,0x802,0x30b7,0x3099,0x802,0x30b9,0x3099,0x802,0x30bb,0x3099,0x802,0x30bd,0x3099,0x802,0x30bf,0x3099, +0x802,0x30c1,0x3099,0x802,0x30c4,0x3099,0x802,0x30c6,0x3099,0x802,0x30c8,0x3099,0x802,0x30cf,0x3099,0x802, +0x30cf,0x309a,0x802,0x30d2,0x3099,0x802,0x30d2,0x309a,0x802,0x30d5,0x3099,0x802,0x30d5,0x309a,0x802,0x30d8, +0x3099,0x802,0x30d8,0x309a,0x802,0x30db,0x3099,0x802,0x30db,0x309a,0x802,0x30a6,0x3099,0x802,0x30ef,0x3099, +0x802,0x30f0,0x3099,0x802,0x30f1,0x3099,0x802,0x30f2,0x3099,0x802,0x30fd,0x3099,0x704,0xd804,0xdc99,0xd804, +0xdcba,0x704,0xd804,0xdc9b,0xd804,0xdcba,0x704,0xd804,0xdca5,0xd804,0xdcba,4,0xd804,0xdd31,0xd804,0xdd27, +4,0xd804,0xdd32,0xd804,0xdd27,4,0xd804,0xdf47,0xd804,0xdf3e,4,0xd804,0xdf47,0xd804,0xdf57,4, +0xd805,0xdcb9,0xd805,0xdcba,4,0xd805,0xdcb9,0xd805,0xdcb0,4,0xd805,0xdcb9,0xd805,0xdcbd,4,0xd805, +0xddb8,0xd805,0xddaf,4,0xd805,0xddb9,0xd805,0xddaf,1,0x2b9,1,0x3b,1,0xb7,0x702,0x915, +0x93c,0x702,0x916,0x93c,0x702,0x917,0x93c,0x702,0x91c,0x93c,0x702,0x921,0x93c,0x702,0x922,0x93c, +0x702,0x92b,0x93c,0x702,0x92f,0x93c,0x702,0x9a1,0x9bc,0x702,0x9a2,0x9bc,0x702,0x9af,0x9bc,0x702, +0xa32,0xa3c,0x702,0xa38,0xa3c,0x702,0xa16,0xa3c,0x702,0xa17,0xa3c,0x702,0xa1c,0xa3c,0x702,0xa2b, +0xa3c,0x702,0xb21,0xb3c,0x702,0xb22,0xb3c,2,0xf42,0xfb7,2,0xf4c,0xfb7,2,0xf51,0xfb7, +2,0xf56,0xfb7,2,0xf5b,0xfb7,2,0xf40,0xfb5,0x8202,0xfb2,0xf80,0x8202,0xfb3,0xf80,2, +0xf92,0xfb7,2,0xf9c,0xfb7,2,0xfa1,0xfb7,2,0xfa6,0xfb7,2,0xfab,0xfb7,2,0xf90, +0xfb5,1,0x3b9,1,0x60,1,0xb4,1,0x3a9,1,0x4b,1,0x3008,1,0x3009,0x102, +0x2add,0x338,1,0x8c48,1,0x66f4,1,0x8eca,1,0x8cc8,1,0x6ed1,1,0x4e32,1,0x53e5, +1,0x9f9c,1,0x5951,1,0x91d1,1,0x5587,1,0x5948,1,0x61f6,1,0x7669,1,0x7f85, +1,0x863f,1,0x87ba,1,0x88f8,1,0x908f,1,0x6a02,1,0x6d1b,1,0x70d9,1,0x73de, +1,0x843d,1,0x916a,1,0x99f1,1,0x4e82,1,0x5375,1,0x6b04,1,0x721b,1,0x862d, +1,0x9e1e,1,0x5d50,1,0x6feb,1,0x85cd,1,0x8964,1,0x62c9,1,0x81d8,1,0x881f, +1,0x5eca,1,0x6717,1,0x6d6a,1,0x72fc,1,0x90ce,1,0x4f86,1,0x51b7,1,0x52de, +1,0x64c4,1,0x6ad3,1,0x7210,1,0x76e7,1,0x8001,1,0x8606,1,0x865c,1,0x8def, +1,0x9732,1,0x9b6f,1,0x9dfa,1,0x788c,1,0x797f,1,0x7da0,1,0x83c9,1,0x9304, +1,0x9e7f,1,0x8ad6,1,0x58df,1,0x5f04,1,0x7c60,1,0x807e,1,0x7262,1,0x78ca, +1,0x8cc2,1,0x96f7,1,0x58d8,1,0x5c62,1,0x6a13,1,0x6dda,1,0x6f0f,1,0x7d2f, +1,0x7e37,1,0x964b,1,0x52d2,1,0x808b,1,0x51dc,1,0x51cc,1,0x7a1c,1,0x7dbe, +1,0x83f1,1,0x9675,1,0x8b80,1,0x62cf,1,0x8afe,1,0x4e39,1,0x5be7,1,0x6012, +1,0x7387,1,0x7570,1,0x5317,1,0x78fb,1,0x4fbf,1,0x5fa9,1,0x4e0d,1,0x6ccc, +1,0x6578,1,0x7d22,1,0x53c3,1,0x585e,1,0x7701,1,0x8449,1,0x8aaa,1,0x6bba, +1,0x8fb0,1,0x6c88,1,0x62fe,1,0x82e5,1,0x63a0,1,0x7565,1,0x4eae,1,0x5169, +1,0x51c9,1,0x6881,1,0x7ce7,1,0x826f,1,0x8ad2,1,0x91cf,1,0x52f5,1,0x5442, +1,0x5973,1,0x5eec,1,0x65c5,1,0x6ffe,1,0x792a,1,0x95ad,1,0x9a6a,1,0x9e97, +1,0x9ece,1,0x529b,1,0x66c6,1,0x6b77,1,0x8f62,1,0x5e74,1,0x6190,1,0x6200, +1,0x649a,1,0x6f23,1,0x7149,1,0x7489,1,0x79ca,1,0x7df4,1,0x806f,1,0x8f26, +1,0x84ee,1,0x9023,1,0x934a,1,0x5217,1,0x52a3,1,0x54bd,1,0x70c8,1,0x88c2, +1,0x5ec9,1,0x5ff5,1,0x637b,1,0x6bae,1,0x7c3e,1,0x7375,1,0x4ee4,1,0x56f9, +1,0x5dba,1,0x601c,1,0x73b2,1,0x7469,1,0x7f9a,1,0x8046,1,0x9234,1,0x96f6, +1,0x9748,1,0x9818,1,0x4f8b,1,0x79ae,1,0x91b4,1,0x96b8,1,0x60e1,1,0x4e86, +1,0x50da,1,0x5bee,1,0x5c3f,1,0x6599,1,0x71ce,1,0x7642,1,0x84fc,1,0x907c, +1,0x9f8d,1,0x6688,1,0x962e,1,0x5289,1,0x677b,1,0x67f3,1,0x6d41,1,0x6e9c, +1,0x7409,1,0x7559,1,0x786b,1,0x7d10,1,0x985e,1,0x516d,1,0x622e,1,0x9678, +1,0x502b,1,0x5d19,1,0x6dea,1,0x8f2a,1,0x5f8b,1,0x6144,1,0x6817,1,0x9686, +1,0x5229,1,0x540f,1,0x5c65,1,0x6613,1,0x674e,1,0x68a8,1,0x6ce5,1,0x7406, +1,0x75e2,1,0x7f79,1,0x88cf,1,0x88e1,1,0x91cc,1,0x96e2,1,0x533f,1,0x6eba, +1,0x541d,1,0x71d0,1,0x7498,1,0x85fa,1,0x96a3,1,0x9c57,1,0x9e9f,1,0x6797, +1,0x6dcb,1,0x81e8,1,0x7acb,1,0x7b20,1,0x7c92,1,0x72c0,1,0x7099,1,0x8b58, +1,0x4ec0,1,0x8336,1,0x523a,1,0x5207,1,0x5ea6,1,0x62d3,1,0x7cd6,1,0x5b85, +1,0x6d1e,1,0x66b4,1,0x8f3b,1,0x884c,1,0x964d,1,0x898b,1,0x5ed3,1,0x5140, +1,0x55c0,1,0x585a,1,0x6674,1,0x51de,1,0x732a,1,0x76ca,1,0x793c,1,0x795e, +1,0x7965,1,0x798f,1,0x9756,1,0x7cbe,1,0x7fbd,1,0x8612,1,0x8af8,1,0x9038, +1,0x90fd,1,0x98ef,1,0x98fc,1,0x9928,1,0x9db4,1,0x90de,1,0x96b7,1,0x4fae, +1,0x50e7,1,0x514d,1,0x52c9,1,0x52e4,1,0x5351,1,0x559d,1,0x5606,1,0x5668, +1,0x5840,1,0x58a8,1,0x5c64,1,0x5c6e,1,0x6094,1,0x6168,1,0x618e,1,0x61f2, +1,0x654f,1,0x65e2,1,0x6691,1,0x6885,1,0x6d77,1,0x6e1a,1,0x6f22,1,0x716e, +1,0x722b,1,0x7422,1,0x7891,1,0x793e,1,0x7949,1,0x7948,1,0x7950,1,0x7956, +1,0x795d,1,0x798d,1,0x798e,1,0x7a40,1,0x7a81,1,0x7bc0,1,0x7e09,1,0x7e41, +1,0x7f72,1,0x8005,1,0x81ed,1,0x8279,1,0x8457,1,0x8910,1,0x8996,1,0x8b01, +1,0x8b39,1,0x8cd3,1,0x8d08,1,0x8fb6,1,0x96e3,1,0x97ff,1,0x983b,1,0x6075, +2,0xd850,0xdeee,1,0x8218,1,0x4e26,1,0x51b5,1,0x5168,1,0x4f80,1,0x5145,1, +0x5180,1,0x52c7,1,0x52fa,1,0x5555,1,0x5599,1,0x55e2,1,0x58b3,1,0x5944,1, +0x5954,1,0x5a62,1,0x5b28,1,0x5ed2,1,0x5ed9,1,0x5f69,1,0x5fad,1,0x60d8,1, +0x614e,1,0x6108,1,0x6160,1,0x6234,1,0x63c4,1,0x641c,1,0x6452,1,0x6556,1, +0x671b,1,0x6756,1,0x6b79,1,0x6edb,1,0x6ecb,1,0x701e,1,0x77a7,1,0x7235,1, +0x72af,1,0x7471,1,0x7506,1,0x753b,1,0x761d,1,0x761f,1,0x76db,1,0x76f4,1, +0x774a,1,0x7740,1,0x78cc,1,0x7ab1,1,0x7c7b,1,0x7d5b,1,0x7f3e,1,0x8352,1, +0x83ef,1,0x8779,1,0x8941,1,0x8986,1,0x8abf,1,0x8acb,1,0x8aed,1,0x8b8a,1, +0x8f38,1,0x9072,1,0x9199,1,0x9276,1,0x967c,1,0x97db,1,0x980b,1,0x9b12,2, +0xd84a,0xdc4a,2,0xd84a,0xdc44,2,0xd84c,0xdfd5,1,0x3b9d,1,0x4018,1,0x4039,2,0xd854, +0xde49,2,0xd857,0xdcd0,2,0xd85f,0xded3,1,0x9f43,1,0x9f8e,0xe02,0x5d9,0x5b4,0x1102,0x5f2, +0x5b7,0x1802,0x5e9,0x5c1,0x1902,0x5e9,0x5c2,0xfb49,0x1843,0x5e9,0x5bc,0x5c1,0xfb49,0x1943,0x5e9,0x5bc, +0x5c2,0x1102,0x5d0,0x5b7,0x1202,0x5d0,0x5b8,0x1502,0x5d0,0x5bc,0x1502,0x5d1,0x5bc,0x1502,0x5d2,0x5bc, +0x1502,0x5d3,0x5bc,0x1502,0x5d4,0x5bc,0x1502,0x5d5,0x5bc,0x1502,0x5d6,0x5bc,0x1502,0x5d8,0x5bc,0x1502, +0x5d9,0x5bc,0x1502,0x5da,0x5bc,0x1502,0x5db,0x5bc,0x1502,0x5dc,0x5bc,0x1502,0x5de,0x5bc,0x1502,0x5e0, +0x5bc,0x1502,0x5e1,0x5bc,0x1502,0x5e3,0x5bc,0x1502,0x5e4,0x5bc,0x1502,0x5e6,0x5bc,0x1502,0x5e7,0x5bc, +0x1502,0x5e8,0x5bc,0x1502,0x5e9,0x5bc,0x1502,0x5ea,0x5bc,0x1302,0x5d5,0x5b9,0x1702,0x5d1,0x5bf,0x1702, +0x5db,0x5bf,0x1702,0x5e4,0x5bf,0xd804,0xd834,0xdd57,0xd834,0xdd65,0xd804,0xd834,0xdd58,0xd834,0xdd65,0xd834, +0xdd5f,0xd834,0xdd6e,4,0xd846,0xd834,0xdd58,0xd834,0xdd65,0xd834,0xdd6e,0xd834,0xdd5f,0xd834,0xdd6f,4, +0xd846,0xd834,0xdd58,0xd834,0xdd65,0xd834,0xdd6f,0xd834,0xdd5f,0xd834,0xdd70,4,0xd846,0xd834,0xdd58,0xd834, +0xdd65,0xd834,0xdd70,0xd834,0xdd5f,0xd834,0xdd71,4,0xd846,0xd834,0xdd58,0xd834,0xdd65,0xd834,0xdd71,0xd834, +0xdd5f,0xd834,0xdd72,4,0xd846,0xd834,0xdd58,0xd834,0xdd65,0xd834,0xdd72,0xd804,0xd834,0xddb9,0xd834,0xdd65, +0xd804,0xd834,0xddba,0xd834,0xdd65,0xd834,0xddbb,0xd834,0xdd6e,4,0xd846,0xd834,0xddb9,0xd834,0xdd65,0xd834, +0xdd6e,0xd834,0xddbc,0xd834,0xdd6e,4,0xd846,0xd834,0xddba,0xd834,0xdd65,0xd834,0xdd6e,0xd834,0xddbb,0xd834, +0xdd6f,4,0xd846,0xd834,0xddb9,0xd834,0xdd65,0xd834,0xdd6f,0xd834,0xddbc,0xd834,0xdd6f,4,0xd846,0xd834, +0xddba,0xd834,0xdd65,0xd834,0xdd6f,1,0x4e3d,1,0x4e38,1,0x4e41,2,0xd840,0xdd22,1,0x4f60, +1,0x4fbb,1,0x5002,1,0x507a,1,0x5099,1,0x50cf,1,0x349e,2,0xd841,0xde3a,1, +0x5154,1,0x5164,1,0x5177,2,0xd841,0xdd1c,1,0x34b9,1,0x5167,1,0x518d,2,0xd841, +0xdd4b,1,0x5197,1,0x51a4,1,0x4ecc,1,0x51ac,2,0xd864,0xdddf,1,0x51f5,1,0x5203, +1,0x34df,1,0x523b,1,0x5246,1,0x5272,1,0x5277,1,0x3515,1,0x5305,1,0x5306, +1,0x5349,1,0x535a,1,0x5373,1,0x537d,1,0x537f,2,0xd842,0xde2c,1,0x7070,1, +0x53ca,1,0x53df,2,0xd842,0xdf63,1,0x53eb,1,0x53f1,1,0x5406,1,0x549e,1,0x5438, +1,0x5448,1,0x5468,1,0x54a2,1,0x54f6,1,0x5510,1,0x5553,1,0x5563,1,0x5584, +1,0x55ab,1,0x55b3,1,0x55c2,1,0x5716,1,0x5717,1,0x5651,1,0x5674,1,0x58ee, +1,0x57ce,1,0x57f4,1,0x580d,1,0x578b,1,0x5832,1,0x5831,1,0x58ac,2,0xd845, +0xdce4,1,0x58f2,1,0x58f7,1,0x5906,1,0x591a,1,0x5922,1,0x5962,2,0xd845,0xdea8, +2,0xd845,0xdeea,1,0x59ec,1,0x5a1b,1,0x5a27,1,0x59d8,1,0x5a66,1,0x36ee,1, +0x36fc,1,0x5b08,1,0x5b3e,2,0xd846,0xddc8,1,0x5bc3,1,0x5bd8,1,0x5bf3,2,0xd846, +0xdf18,1,0x5bff,1,0x5c06,1,0x5f53,1,0x5c22,1,0x3781,1,0x5c60,1,0x5cc0,1, +0x5c8d,2,0xd847,0xdde4,1,0x5d43,2,0xd847,0xdde6,1,0x5d6e,1,0x5d6b,1,0x5d7c,1, +0x5de1,1,0x5de2,1,0x382f,1,0x5dfd,1,0x5e28,1,0x5e3d,1,0x5e69,1,0x3862,2, +0xd848,0xdd83,1,0x387c,1,0x5eb0,1,0x5eb3,1,0x5eb6,2,0xd868,0xdf92,1,0x5efe,2, +0xd848,0xdf31,1,0x8201,1,0x5f22,1,0x38c7,2,0xd84c,0xdeb8,2,0xd858,0xddda,1,0x5f62, +1,0x5f6b,1,0x38e3,1,0x5f9a,1,0x5fcd,1,0x5fd7,1,0x5ff9,1,0x6081,1,0x393a, +1,0x391c,2,0xd849,0xded4,1,0x60c7,1,0x6148,1,0x614c,1,0x617a,1,0x61b2,1, +0x61a4,1,0x61af,1,0x61de,1,0x6210,1,0x621b,1,0x625d,1,0x62b1,1,0x62d4,1, +0x6350,2,0xd84a,0xdf0c,1,0x633d,1,0x62fc,1,0x6368,1,0x6383,1,0x63e4,2,0xd84a, +0xdff1,1,0x6422,1,0x63c5,1,0x63a9,1,0x3a2e,1,0x6469,1,0x647e,1,0x649d,1, +0x6477,1,0x3a6c,1,0x656c,2,0xd84c,0xdc0a,1,0x65e3,1,0x66f8,1,0x6649,1,0x3b19, +1,0x3b08,1,0x3ae4,1,0x5192,1,0x5195,1,0x6700,1,0x669c,1,0x80ad,1,0x43d9, +1,0x6721,1,0x675e,1,0x6753,2,0xd84c,0xdfc3,1,0x3b49,1,0x67fa,1,0x6785,1, +0x6852,2,0xd84d,0xdc6d,1,0x688e,1,0x681f,1,0x6914,1,0x6942,1,0x69a3,1,0x69ea, +1,0x6aa8,2,0xd84d,0xdea3,1,0x6adb,1,0x3c18,1,0x6b21,2,0xd84e,0xdca7,1,0x6b54, +1,0x3c4e,1,0x6b72,1,0x6b9f,1,0x6bbb,2,0xd84e,0xde8d,2,0xd847,0xdd0b,2,0xd84e, +0xdefa,1,0x6c4e,2,0xd84f,0xdcbc,1,0x6cbf,1,0x6ccd,1,0x6c67,1,0x6d16,1,0x6d3e, +1,0x6d69,1,0x6d78,1,0x6d85,2,0xd84f,0xdd1e,1,0x6d34,1,0x6e2f,1,0x6e6e,1, +0x3d33,1,0x6ec7,2,0xd84f,0xded1,1,0x6df9,1,0x6f6e,2,0xd84f,0xdf5e,2,0xd84f,0xdf8e, +1,0x6fc6,1,0x7039,1,0x701b,1,0x3d96,1,0x704a,1,0x707d,1,0x7077,1,0x70ad, +2,0xd841,0xdd25,1,0x7145,2,0xd850,0xde63,1,0x719c,2,0xd850,0xdfab,1,0x7228,1, +0x7250,2,0xd851,0xde08,1,0x7280,1,0x7295,2,0xd851,0xdf35,2,0xd852,0xdc14,1,0x737a, +1,0x738b,1,0x3eac,1,0x73a5,1,0x3eb8,1,0x7447,1,0x745c,1,0x7485,1,0x74ca, +1,0x3f1b,1,0x7524,2,0xd853,0xdc36,1,0x753e,2,0xd853,0xdc92,2,0xd848,0xdd9f,1, +0x7610,2,0xd853,0xdfa1,2,0xd853,0xdfb8,2,0xd854,0xdc44,1,0x3ffc,1,0x4008,2,0xd854, +0xdcf3,2,0xd854,0xdcf2,2,0xd854,0xdd19,2,0xd854,0xdd33,1,0x771e,1,0x771f,1,0x778b, +1,0x4046,1,0x4096,2,0xd855,0xdc1d,1,0x784e,1,0x40e3,2,0xd855,0xde26,2,0xd855, +0xde9a,2,0xd855,0xdec5,1,0x79eb,1,0x412f,1,0x7a4a,1,0x7a4f,2,0xd856,0xdd7c,2, +0xd856,0xdea7,1,0x7aee,1,0x4202,2,0xd856,0xdfab,1,0x7bc6,1,0x7bc9,1,0x4227,2, +0xd857,0xdc80,1,0x7cd2,1,0x42a0,1,0x7ce8,1,0x7ce3,1,0x7d00,2,0xd857,0xdf86,1, +0x7d63,1,0x4301,1,0x7dc7,1,0x7e02,1,0x7e45,1,0x4334,2,0xd858,0xde28,2,0xd858, +0xde47,1,0x4359,2,0xd858,0xded9,1,0x7f7a,2,0xd858,0xdf3e,1,0x7f95,1,0x7ffa,2, +0xd859,0xdcda,2,0xd859,0xdd23,1,0x8060,2,0xd859,0xdda8,1,0x8070,2,0xd84c,0xdf5f,1, +0x43d5,1,0x80b2,1,0x8103,1,0x440b,1,0x813e,1,0x5ab5,2,0xd859,0xdfa7,2,0xd859, +0xdfb5,2,0xd84c,0xdf93,2,0xd84c,0xdf9c,1,0x8204,1,0x8f9e,1,0x446b,1,0x8291,1, +0x828b,1,0x829d,1,0x52b3,1,0x82b1,1,0x82b3,1,0x82bd,1,0x82e6,2,0xd85a,0xdf3c, +1,0x831d,1,0x8363,1,0x83ad,1,0x8323,1,0x83bd,1,0x83e7,1,0x8353,1,0x83ca, +1,0x83cc,1,0x83dc,2,0xd85b,0xdc36,2,0xd85b,0xdd6b,2,0xd85b,0xdcd5,1,0x452b,1, +0x84f1,1,0x84f3,1,0x8516,2,0xd85c,0xdfca,1,0x8564,2,0xd85b,0xdf2c,1,0x455d,1, +0x4561,2,0xd85b,0xdfb1,2,0xd85c,0xdcd2,1,0x456b,1,0x8650,1,0x8667,1,0x8669,1, +0x86a9,1,0x8688,1,0x870e,1,0x86e2,1,0x8728,1,0x876b,1,0x8786,1,0x45d7,1, +0x87e1,1,0x8801,1,0x45f9,1,0x8860,1,0x8863,2,0xd85d,0xde67,1,0x88d7,1,0x88de, +1,0x4635,1,0x88fa,1,0x34bb,2,0xd85e,0xdcae,2,0xd85e,0xdd66,1,0x46be,1,0x46c7, +1,0x8aa0,1,0x8c55,2,0xd85f,0xdca8,1,0x8cab,1,0x8cc1,1,0x8d1b,1,0x8d77,2, +0xd85f,0xdf2f,2,0xd842,0xdc04,1,0x8dcb,1,0x8dbc,1,0x8df0,2,0xd842,0xdcde,1,0x8ed4, +2,0xd861,0xddd2,2,0xd861,0xdded,1,0x9094,1,0x90f1,1,0x9111,2,0xd861,0xdf2e,1, +0x911b,1,0x9238,1,0x92d7,1,0x92d8,1,0x927c,1,0x93f9,1,0x9415,2,0xd862,0xdffa, +1,0x958b,1,0x4995,1,0x95b7,2,0xd863,0xdd77,1,0x49e6,1,0x96c3,1,0x5db2,1, +0x9723,2,0xd864,0xdd45,2,0xd864,0xde1a,1,0x4a6e,1,0x4a76,1,0x97e0,2,0xd865,0xdc0a, +1,0x4ab2,2,0xd865,0xdc96,1,0x9829,2,0xd865,0xddb6,1,0x98e2,1,0x4b33,1,0x9929, +1,0x99a7,1,0x99c2,1,0x99fe,1,0x4bce,2,0xd866,0xdf30,1,0x9c40,1,0x9cfd,1, +0x4cce,1,0x4ced,1,0x9d67,2,0xd868,0xdcce,1,0x4cf8,2,0xd868,0xdd05,2,0xd868,0xde0e, +2,0xd868,0xde91,1,0x9ebb,1,0x4d56,1,0x9ef9,1,0x9efe,1,0x9f05,1,0x9f0f,1, +0x9f16,1,0x9f3b,2,0xd869,0xde00,0x3ac,0xe642,0x3b1,0x301,0x3ad,0xe642,0x3b5,0x301,0x3ae,0xe642, +0x3b7,0x301,0x3af,0xe642,0x3b9,0x301,0x3cc,0xe642,0x3bf,0x301,0x3cd,0xe642,0x3c5,0x301,0x3ce,0xe642, +0x3c9,0x301,0x386,0xe642,0x391,0x301,0x388,0xe642,0x395,0x301,0x389,0xe642,0x397,0x301,0x390,1, +0xe643,0x3b9,0x308,0x301,0x38a,0xe642,0x399,0x301,0x3b0,1,0xe643,0x3c5,0x308,0x301,0x38e,0xe642, +0x3a5,0x301,0x385,0xe642,0xa8,0x301,0x38c,0xe642,0x39f,0x301,0x38f,0xe642,0x3a9,0x301,0xc5,0xe642, +0x41,0x30a,0xe6e6,0xe681,0x300,0xe6e6,0xe681,0x301,0xe6e6,0xe681,0x313,0xe6e6,0xe682,0x308,0x301,0x8100, +0x8282,0xf71,0xf72,0x8100,0x8482,0xf71,0xf74,0x8100,0x8282,0xf71,0xf80,0 }; static const uint8_t norm2_nfc_data_smallFCD[256]={ @@ -1139,13 +1143,13 @@ static const UTrie2 norm2_nfc_data_trie={ norm2_nfc_data_trieIndex+2720, NULL, 2720, - 7004, + 7056, 0x188, 0xb1c, - 0x0, - 0x0, + 0x1, + 0x1, 0x30000, - 0x25f8, + 0x262c, NULL, 0, FALSE, FALSE, 0, NULL }; diff --git a/icu4c/source/common/norm2allmodes.h b/icu4c/source/common/norm2allmodes.h index 559858c4fe9..638fc87b5c4 100644 --- a/icu4c/source/common/norm2allmodes.h +++ b/icu4c/source/common/norm2allmodes.h @@ -23,6 +23,7 @@ #include "unicode/unistr.h" #include "cpputils.h" #include "normalizer2impl.h" +#include "ustr_imp.h" // U_EDITS_NO_RESET U_NAMESPACE_BEGIN @@ -211,8 +212,8 @@ private: virtual UNormalizationCheckResult getQuickCheck(UChar32 c) const { return impl.isDecompYes(impl.getNorm16(c)) ? UNORM_YES : UNORM_NO; } - virtual UBool hasBoundaryBefore(UChar32 c) const { return impl.hasDecompBoundary(c, TRUE); } - virtual UBool hasBoundaryAfter(UChar32 c) const { return impl.hasDecompBoundary(c, FALSE); } + virtual UBool hasBoundaryBefore(UChar32 c) const { return impl.hasDecompBoundaryBefore(c); } + virtual UBool hasBoundaryAfter(UChar32 c) const { return impl.hasDecompBoundaryAfter(c); } virtual UBool isInert(UChar32 c) const { return impl.isDecompInert(c); } }; @@ -236,12 +237,12 @@ private: if (U_FAILURE(errorCode)) { return; } - if (edits != nullptr) { + if (edits != nullptr && (options & U_EDITS_NO_RESET) == 0) { edits->reset(); } const uint8_t *s = reinterpret_cast(src.data()); - impl.composeUTF8(options, s, s + src.length(), - onlyContiguous, TRUE, sink, edits, errorCode); + impl.composeUTF8(options, onlyContiguous, s, s + src.length(), + &sink, edits, errorCode); sink.Flush(); } @@ -295,10 +296,10 @@ private: return impl.hasCompBoundaryBefore(c); } virtual UBool hasBoundaryAfter(UChar32 c) const override { - return impl.hasCompBoundaryAfter(c, onlyContiguous, FALSE); + return impl.hasCompBoundaryAfter(c, onlyContiguous); } virtual UBool isInert(UChar32 c) const override { - return impl.hasCompBoundaryAfter(c, onlyContiguous, TRUE); + return impl.isCompInert(c, onlyContiguous); } const UBool onlyContiguous; diff --git a/icu4c/source/common/normalizer2.cpp b/icu4c/source/common/normalizer2.cpp index 28e5f353afb..a62a8d930ba 100644 --- a/icu4c/source/common/normalizer2.cpp +++ b/icu4c/source/common/normalizer2.cpp @@ -30,6 +30,7 @@ #include "normalizer2impl.h" #include "uassert.h" #include "ucln_cmn.h" +#include "ustr_imp.h" // U_EDITS_NO_RESET using icu::Normalizer2Impl; @@ -90,14 +91,18 @@ class NoopNormalizer2 : public Normalizer2 { return dest; } virtual void - normalizeUTF8(uint32_t /*options*/, StringPiece src, ByteSink &sink, + normalizeUTF8(uint32_t options, StringPiece src, ByteSink &sink, Edits *edits, UErrorCode &errorCode) const override { if(U_SUCCESS(errorCode)) { - sink.Append(src.data(), src.length()); if (edits != nullptr) { - edits->reset(); + if ((options & U_EDITS_NO_RESET) == 0) { + edits->reset(); + } edits->addUnchanged(src.length()); } + if ((options & U_OMIT_UNCHANGED_TEXT) == 0) { + sink.Append(src.data(), src.length()); + } sink.Flush(); } } diff --git a/icu4c/source/common/normalizer2impl.cpp b/icu4c/source/common/normalizer2impl.cpp index 5ab29e42e8d..1249aede85e 100644 --- a/icu4c/source/common/normalizer2impl.cpp +++ b/icu4c/source/common/normalizer2impl.cpp @@ -59,27 +59,27 @@ inline uint8_t leadByteForCP(UChar32 c) { /** * Returns the code point from one single well-formed UTF-8 byte sequence - * between src and limit. + * between cpStart and cpLimit. * * UTrie2 UTF-8 macros do not assemble whole code points (for efficiency). * When we do need the code point, we call this function. * We should not need it for normalization-inert data (norm16==0). * Illegal sequences yield the error value norm16==0 just like real normalization-inert code points. */ -UChar32 codePointFromValidUTF8(const uint8_t *src, const uint8_t *limit) { +UChar32 codePointFromValidUTF8(const uint8_t *cpStart, const uint8_t *cpLimit) { // Similar to U8_NEXT_UNSAFE(s, i, c). - U_ASSERT(src < limit); - uint8_t c = *src; - switch(limit-src) { + U_ASSERT(cpStart < cpLimit); + uint8_t c = *cpStart; + switch(cpLimit-cpStart) { case 1: return c; case 2: - return ((c&0x1f)<<6) | (src[1]&0x3f); + return ((c&0x1f)<<6) | (cpStart[1]&0x3f); case 3: // no need for (c&0xf) because the upper bits are truncated after <<12 in the cast to (UChar) - return (UChar)((c<<12) | ((src[1]&0x3f)<<6) | (src[2]&0x3f)); + return (UChar)((c<<12) | ((cpStart[1]&0x3f)<<6) | (cpStart[2]&0x3f)); case 4: - return ((c&7)<<18) | ((src[1]&0x3f)<<12) | ((src[2]&0x3f)<<6) | (src[3]&0x3f); + return ((c&7)<<18) | ((cpStart[1]&0x3f)<<12) | ((cpStart[2]&0x3f)<<6) | (cpStart[3]&0x3f); default: U_ASSERT(FALSE); // Should not occur. return U_SENTINEL; @@ -87,18 +87,22 @@ UChar32 codePointFromValidUTF8(const uint8_t *src, const uint8_t *limit) { } /** - * Returns the offset from the Jamo L base if [src, limit[ is a single Jamo L code point. + * Returns the last code point in [start, p[ if it is valid and in U+1000..U+D7FF. * Otherwise returns a negative value. */ -int32_t getJamoLMinusBase(const uint8_t *src, const uint8_t *limit) { - // Jamo L: E1 84 80..92 - if ((limit - src) == 3 && *src == 0xe1 && src[1] == 0x84) { - uint8_t l = src[2] - 0x80; - if (l < Hangul::JAMO_L_COUNT) { - return l; +UChar32 previousHangulOrJamo(const uint8_t *start, const uint8_t *p) { + if ((p - start) >= 3) { + p -= 3; + uint8_t l = *p; + uint8_t t1, t2; + if (0xe1 <= l && l <= 0xed && + (t1 = (uint8_t)(p[1] - 0x80)) <= 0x3f && + (t2 = (uint8_t)(p[2] - 0x80)) <= 0x3f && + (l < 0xed || t1 <= 0x1f)) { + return ((l & 0xf) << 12) | (t1 << 6) | t2; } } - return -1; + return U_SENTINEL; } /** @@ -125,12 +129,6 @@ int32_t getJamoTMinusBase(const uint8_t *src, const uint8_t *limit) { return -1; } -void giveByteSinkAllocationHint(ByteSink &sink, int32_t desiredCapacity) { - char scratch[1]; - int32_t capacity; - sink.GetAppendBuffer(1, desiredCapacity, scratch, UPRV_LENGTHOF(scratch), &capacity); -} - /** The bytes at [src, nextSrc[ were mapped to valid (s16, s16Length). */ UBool appendChange(const uint8_t *src, const uint8_t *nextSrc, @@ -185,6 +183,37 @@ appendCodePoint(const uint8_t *src, const uint8_t *nextSrc, UChar32 c, sink.Append(buffer, length); } +void +appendCodePointDelta(const uint8_t *cpStart, const uint8_t *cpLimit, int32_t delta, + ByteSink &sink, Edits *edits) { + char buffer[U8_MAX_LENGTH]; + int32_t length; + int32_t cpLength = (int32_t)(cpLimit - cpStart); + if (cpLength == 1) { + // The builder makes ASCII map to ASCII. + buffer[0] = (uint8_t)(*cpStart + delta); + length = 1; + } else { + int32_t trail = *(cpLimit-1) + delta; + if (0x80 <= trail && trail <= 0xbf) { + // The delta only changes the last trail byte. + --cpLimit; + length = 0; + do { buffer[length++] = *cpStart++; } while (cpStart < cpLimit); + buffer[length++] = (uint8_t)trail; + } else { + // Decode the code point, add the delta, re-encode. + UChar32 c = codePointFromValidUTF8(cpStart, cpLimit) + delta; + length = 0; + U8_APPEND_UNSAFE(buffer, length, c); + } + } + if (edits != nullptr) { + edits->addReplace(cpLength, length); + } + sink.Append(buffer, length); +} + UBool appendUnchanged(const uint8_t *s, const uint8_t *limit, ByteSink &sink, uint32_t options, Edits *edits, @@ -210,6 +239,17 @@ appendUnchanged(const uint8_t *s, const uint8_t *limit, // ReorderingBuffer -------------------------------------------------------- *** +ReorderingBuffer::ReorderingBuffer(const Normalizer2Impl &ni, UnicodeString &dest, + UErrorCode &errorCode) : + impl(ni), str(dest), + start(str.getBuffer(8)), reorderStart(start), limit(start), + remainingCapacity(str.getCapacity()), lastCC(0) { + if (start == nullptr && U_SUCCESS(errorCode)) { + // getBuffer() already did str.setToBogus() + errorCode = U_MEMORY_ALLOCATION_ERROR; + } +} + UBool ReorderingBuffer::init(int32_t destCapacity, UErrorCode &errorCode) { int32_t length=str.length(); start=str.getBuffer(destCapacity); @@ -415,16 +455,12 @@ uint8_t ReorderingBuffer::previousCC() { return 0; } UChar32 c=*--codePointStart; - if(c>DELTA_SHIFT)-MAX_DELTA-1; normTrie=inTrie; maybeYesCompositions=inExtraData; - extraData=maybeYesCompositions+(MIN_NORMAL_MAYBE_YES-minMaybeYes); + extraData=maybeYesCompositions+((MIN_NORMAL_MAYBE_YES-minMaybeYes)>>OFFSET_SHIFT); smallFCD=inSmallFCD; - - // Build tccc180[]. - // gennorm2 enforces lccc=0 for c>=1) { - if((c&0xff)==0) { - bits=smallFCD[c>>8]; // one byte per 0x100 code points - } - if(bits&1) { - for(int i=0; i<0x20; ++i, ++c) { - tccc180[c]=(uint8_t)getFCD16FromNormData(c); - } - } else { - uprv_memset(tccc180+c, 0, 0x20); - c+=0x20; - } - } } -uint8_t Normalizer2Impl::getTrailCCFromCompYesAndZeroCC(const UChar *cpStart, const UChar *cpLimit) const { - UChar32 c; - if(cpStart==(cpLimit-1)) { - c=*cpStart; - } else { - c=U16_GET_SUPPLEMENTARY(cpStart[0], cpStart[1]); - } - uint16_t prevNorm16=getNorm16(c); - if(prevNorm16<=minYesNo) { - return 0; // yesYes and Hangul LV/LVT have ccc=tccc=0 - } else { - return (uint8_t)(*getMapping(prevNorm16)>>8); // tccc from yesNo - } -} - -namespace { - class LcccContext { public: LcccContext(const Normalizer2Impl &ni, UnicodeSet &s) : impl(ni), set(s) {} void handleRange(UChar32 start, UChar32 end, uint16_t norm16) { - if(impl.isAlgorithmicNoNo(norm16)) { - // Range of code points with same-norm16-value algorithmic decompositions. - // They might have different non-zero FCD16 values. - do { - uint16_t fcd16=impl.getFCD16(start); - if(fcd16>0xff) { set.add(start); } - } while(++start<=end); - } else { + if (norm16 > Normalizer2Impl::MIN_NORMAL_MAYBE_YES && + norm16 != Normalizer2Impl::JAMO_VT) { + set.add(start, end); + } else if (impl.minNoNoCompNoMaybeCC <= norm16 && norm16 < impl.limitNoNo) { uint16_t fcd16=impl.getFCD16(start); if(fcd16>0xff) { set.add(start, end); } } @@ -534,6 +538,8 @@ private: UnicodeSet &set; }; +namespace { + struct PropertyStartsContext { PropertyStartsContext(const Normalizer2Impl &ni, const USetAdder *adder) : impl(ni), sa(adder) {} @@ -558,7 +564,8 @@ enumNorm16PropertyStartsRange(const void *context, UChar32 start, UChar32 end, u const PropertyStartsContext *ctx=(const PropertyStartsContext *)context; const USetAdder *sa=ctx->sa; sa->add(sa->set, start); - if(start!=end && ctx->impl.isAlgorithmicNoNo((uint16_t)value)) { + if (start != end && ctx->impl.isAlgorithmicNoNo((uint16_t)value) && + (value & Normalizer2Impl::DELTA_TCCC_MASK) > Normalizer2Impl::DELTA_TCCC_1) { // Range of code points with same-norm16-value algorithmic decompositions. // They might have different non-zero FCD16 values. uint16_t prevFCD16=ctx->impl.getFCD16(start); @@ -590,7 +597,6 @@ U_CDECL_END void Normalizer2Impl::addLcccChars(UnicodeSet &set) const { - /* add the start code point of each same-value range of each trie */ LcccContext context(*this, set); utrie2_enum(normTrie, NULL, enumLcccRange, &context); } @@ -767,157 +773,174 @@ Normalizer2Impl::decompose(const UChar *src, const UChar *limit, // fail the quick check loop and/or where the quick check loop's overhead // is unlikely to be amortized. // Called by the compose() and makeFCD() implementations. -UBool Normalizer2Impl::decomposeShort(const UChar *src, const UChar *limit, - ReorderingBuffer &buffer, - UErrorCode &errorCode) const { +const UChar * +Normalizer2Impl::decomposeShort(const UChar *src, const UChar *limit, + UBool stopAtCompBoundary, UBool onlyContiguous, + ReorderingBuffer &buffer, UErrorCode &errorCode) const { + if (U_FAILURE(errorCode)) { + return nullptr; + } while(src= limitNoNo) { + if (isMaybeOrNonZeroCC(norm16)) { return buffer.append(c, getCCFromYesOrMaybe(norm16), errorCode); - } else if(isHangul(norm16)) { - // Hangul syllable: decompose algorithmically - UChar jamos[3]; - return buffer.appendZeroCC(jamos, jamos+Hangul::decompose(c, jamos), errorCode); - } else if(isDecompNoAlgorithmic(norm16)) { - c=mapAlgorithmic(c, norm16); - norm16=getNorm16(c); - } else { - // c decomposes, get everything from the variable-length extra data - const uint16_t *mapping=getMapping(norm16); - uint16_t firstUnit=*mapping; - int32_t length=firstUnit&MAPPING_LENGTH_MASK; - uint8_t leadCC, trailCC; - trailCC=(uint8_t)(firstUnit>>8); - if(firstUnit&MAPPING_HAS_CCC_LCCC_WORD) { - leadCC=(uint8_t)(*(mapping-1)>>8); - } else { - leadCC=0; - } - return buffer.append((const UChar *)mapping+1, length, leadCC, trailCC, errorCode); } + // Maps to an isCompYesAndZeroCC. + c=mapAlgorithmic(c, norm16); + norm16=getNorm16(c); } + if (norm16 < minYesNo) { + // c does not decompose + return buffer.append(c, 0, errorCode); + } else if(isHangulLV(norm16) || isHangulLVT(norm16)) { + // Hangul syllable: decompose algorithmically + UChar jamos[3]; + return buffer.appendZeroCC(jamos, jamos+Hangul::decompose(c, jamos), errorCode); + } + // c decomposes, get everything from the variable-length extra data + const uint16_t *mapping=getMapping(norm16); + uint16_t firstUnit=*mapping; + int32_t length=firstUnit&MAPPING_LENGTH_MASK; + uint8_t leadCC, trailCC; + trailCC=(uint8_t)(firstUnit>>8); + if(firstUnit&MAPPING_HAS_CCC_LCCC_WORD) { + leadCC=(uint8_t)(*(mapping-1)>>8); + } else { + leadCC=0; + } + return buffer.append((const UChar *)mapping+1, length, leadCC, trailCC, errorCode); } const uint8_t * Normalizer2Impl::decomposeShort(const uint8_t *src, const uint8_t *limit, - UBool stopAtCompBoundary, ReorderingBuffer &buffer, - UErrorCode &errorCode) const { + UBool stopAtCompBoundary, UBool onlyContiguous, + ReorderingBuffer &buffer, UErrorCode &errorCode) const { if (U_FAILURE(errorCode)) { return nullptr; } - // UTF-8 version of decomposeShort() + findNextCompBoundary() together while (src < limit) { - const uint8_t *nextSrc = src; + const uint8_t *prevSrc = src; uint16_t norm16; - UTRIE2_U8_NEXT16(normTrie, nextSrc, limit, norm16); + UTRIE2_U8_NEXT16(normTrie, src, limit, norm16); // Get the decomposition and the lead and trail cc's. - // Only loops for 1:1 algorithmic mappings. UChar32 c = U_SENTINEL; - for (;;) { - if (stopAtCompBoundary && isCompYesAndZeroCC(norm16)) { - return src; - } - // norm16!=0 guarantees that [src, nextSrc[ is valid UTF-8. - // We do not see invalid UTF-8 here because - // its norm16==0 is normalization-inert, - // so it gets copied unchanged in the fast path, - // and we stop the slow path where invalid UTF-8 begins. - U_ASSERT(norm16 != 0); - if (isDecompYes(norm16)) { - if (c < 0) { - c = codePointFromValidUTF8(src, nextSrc); - } - // does not decompose + if (norm16 >= limitNoNo) { + if (isMaybeOrNonZeroCC(norm16)) { + // No boundaries around this character. + c = codePointFromValidUTF8(prevSrc, src); if (!buffer.append(c, getCCFromYesOrMaybe(norm16), errorCode)) { return nullptr; } - break; - } else if (isHangul(norm16)) { - // Hangul syllable: decompose algorithmically - if (c < 0) { - c = codePointFromValidUTF8(src, nextSrc); - } - char16_t jamos[3]; - if (!buffer.appendZeroCC(jamos, jamos+Hangul::decompose(c, jamos), errorCode)) { - return nullptr; - } - break; - } else if (isDecompNoAlgorithmic(norm16)) { - if (c < 0) { - c = codePointFromValidUTF8(src, nextSrc); - } - c = mapAlgorithmic(c, norm16); - norm16 = getNorm16(c); + continue; + } + // Maps to an isCompYesAndZeroCC. + if (stopAtCompBoundary) { + return prevSrc; + } + c = codePointFromValidUTF8(prevSrc, src); + c = mapAlgorithmic(c, norm16); + norm16 = getNorm16(c); + } else if (stopAtCompBoundary && norm16 < minNoNoCompNoMaybeCC) { + return prevSrc; + } + // norm16!=INERT guarantees that [prevSrc, src[ is valid UTF-8. + // We do not see invalid UTF-8 here because + // its norm16==INERT is normalization-inert, + // so it gets copied unchanged in the fast path, + // and we stop the slow path where invalid UTF-8 begins. + U_ASSERT(norm16 != INERT); + if (norm16 < minYesNo) { + if (c < 0) { + c = codePointFromValidUTF8(prevSrc, src); + } + // does not decompose + if (!buffer.append(c, 0, errorCode)) { + return nullptr; + } + } else if (isHangulLV(norm16) || isHangulLVT(norm16)) { + // Hangul syllable: decompose algorithmically + if (c < 0) { + c = codePointFromValidUTF8(prevSrc, src); + } + char16_t jamos[3]; + if (!buffer.appendZeroCC(jamos, jamos+Hangul::decompose(c, jamos), errorCode)) { + return nullptr; + } + } else { + // The character decomposes, get everything from the variable-length extra data. + const uint16_t *mapping = getMapping(norm16); + uint16_t firstUnit = *mapping; + int32_t length = firstUnit & MAPPING_LENGTH_MASK; + uint8_t trailCC = (uint8_t)(firstUnit >> 8); + uint8_t leadCC; + if (firstUnit & MAPPING_HAS_CCC_LCCC_WORD) { + leadCC = (uint8_t)(*(mapping-1) >> 8); } else { - // The character decomposes, get everything from the variable-length extra data. - const uint16_t *mapping = getMapping(norm16); - uint16_t firstUnit = *mapping; - int32_t length = firstUnit & MAPPING_LENGTH_MASK; - uint8_t leadCC; - if (firstUnit & MAPPING_HAS_CCC_LCCC_WORD) { - leadCC = (uint8_t)(*(mapping-1) >> 8); - } else { - leadCC = 0; - } - if (stopAtCompBoundary && length != 0 && leadCC == 0) { - int32_t i = 1; // skip over the firstUnit - U16_NEXT_UNSAFE(mapping, i, c); - if (isCompYesAndZeroCC(getNorm16(c))) { - return src; - } - } - uint8_t trailCC = (uint8_t)(firstUnit >> 8); - if (!buffer.append((const char16_t *)mapping+1, length, leadCC, trailCC, errorCode)) { - return nullptr; - } - break; + leadCC = 0; + } + if (!buffer.append((const char16_t *)mapping+1, length, leadCC, trailCC, errorCode)) { + return nullptr; } } - src = nextSrc; + if (stopAtCompBoundary && norm16HasCompBoundaryAfter(norm16, onlyContiguous)) { + return src; + } } return src; } const UChar * Normalizer2Impl::getDecomposition(UChar32 c, UChar buffer[4], int32_t &length) const { - const UChar *decomp=NULL; uint16_t norm16; - for(;;) { - if(c>7)&1)-1; - uint16_t rm0=*rawMapping; - if(rm0<=MAPPING_LENGTH_MASK) { - length=rm0; - return (const UChar *)rawMapping-rm0; - } else { - // Copy the normal mapping and replace its first two code units with rm0. - buffer[0]=(UChar)rm0; - u_memcpy(buffer+1, (const UChar *)mapping+1+2, mLength-2); - length=mLength-1; - return buffer; - } + } + // c decomposes, get everything from the variable-length extra data + const uint16_t *mapping=getMapping(norm16); + uint16_t firstUnit=*mapping; + int32_t mLength=firstUnit&MAPPING_LENGTH_MASK; // length of normal mapping + if(firstUnit&MAPPING_HAS_RAW_MAPPING) { + // Read the raw mapping from before the firstUnit and before the optional ccc/lccc word. + // Bit 7=MAPPING_HAS_CCC_LCCC_WORD + const uint16_t *rawMapping=mapping-((firstUnit>>7)&1)-1; + uint16_t rm0=*rawMapping; + if(rm0<=MAPPING_LENGTH_MASK) { + length=rm0; + return (const UChar *)rawMapping-rm0; } else { - length=mLength; - return (const UChar *)mapping+1; + // Copy the normal mapping and replace its first two code units with rm0. + buffer[0]=(UChar)rm0; + u_memcpy(buffer+1, (const UChar *)mapping+1+2, mLength-2); + length=mLength-1; + return buffer; } + } else { + length=mLength; + return (const UChar *)mapping+1; } } @@ -996,43 +1016,60 @@ void Normalizer2Impl::decomposeAndAppend(const UChar *src, const UChar *limit, } } -// Note: hasDecompBoundary() could be implemented as aliases to -// hasFCDBoundaryBefore() and hasFCDBoundaryAfter() -// at the cost of building the FCD trie for a decomposition normalizer. -UBool Normalizer2Impl::hasDecompBoundary(UChar32 c, UBool before) const { - for(;;) { - if(cMIN_NORMAL_MAYBE_YES) { - return FALSE; // ccc!=0 - } else if(isDecompNoAlgorithmic(norm16)) { - c=mapAlgorithmic(c, norm16); - } else { - // c decomposes, get everything from the variable-length extra data - const uint16_t *mapping=getMapping(norm16); - uint16_t firstUnit=*mapping; - if((firstUnit&MAPPING_LENGTH_MASK)==0) { - return FALSE; - } - if(!before) { - // decomp after-boundary: same as hasFCDBoundaryAfter(), - // fcd16<=1 || trailCC==0 - if(firstUnit>0x1ff) { - return FALSE; // trailCC>1 - } - if(firstUnit<=0xff) { - return TRUE; // trailCC==0 - } - // if(trailCC==1) test leadCC==0, same as checking for before-boundary - } - // TRUE if leadCC==0 (hasFCDBoundaryBefore()) - return (firstUnit&MAPPING_HAS_CCC_LCCC_WORD)==0 || (*(mapping-1)&0xff00)==0; - } +UBool Normalizer2Impl::hasDecompBoundaryBefore(UChar32 c) const { + return c < minLcccCP || (c <= 0xffff && !singleLeadMightHaveNonZeroFCD16(c)) || + norm16HasDecompBoundaryBefore(getNorm16(c)); +} + +UBool Normalizer2Impl::norm16HasDecompBoundaryBefore(uint16_t norm16) const { + if (norm16 < minNoNoCompNoMaybeCC) { + return TRUE; } + if (norm16 >= limitNoNo) { + return norm16 <= MIN_NORMAL_MAYBE_YES || norm16 == JAMO_VT; + } + // c decomposes, get everything from the variable-length extra data + const uint16_t *mapping=getMapping(norm16); + uint16_t firstUnit=*mapping; + // TRUE if leadCC==0 (hasFCDBoundaryBefore()) + return (firstUnit&MAPPING_HAS_CCC_LCCC_WORD)==0 || (*(mapping-1)&0xff00)==0; +} + +UBool Normalizer2Impl::hasDecompBoundaryAfter(UChar32 c) const { + if (c < minDecompNoCP) { + return TRUE; + } + if (c <= 0xffff && !singleLeadMightHaveNonZeroFCD16(c)) { + return TRUE; + } + return norm16HasDecompBoundaryAfter(getNorm16(c)); +} + +UBool Normalizer2Impl::norm16HasDecompBoundaryAfter(uint16_t norm16) const { + if(norm16 <= minYesNo || isHangulLVT(norm16)) { + return TRUE; + } + if (norm16 >= limitNoNo) { + if (isMaybeOrNonZeroCC(norm16)) { + return norm16 <= MIN_NORMAL_MAYBE_YES || norm16 == JAMO_VT; + } + // Maps to an isCompYesAndZeroCC. + return (norm16 & DELTA_TCCC_MASK) <= DELTA_TCCC_1; + } + // c decomposes, get everything from the variable-length extra data + const uint16_t *mapping=getMapping(norm16); + uint16_t firstUnit=*mapping; + // decomp after-boundary: same as hasFCDBoundaryAfter(), + // fcd16<=1 || trailCC==0 + if(firstUnit>0x1ff) { + return FALSE; // trailCC>1 + } + if(firstUnit<=0xff) { + return TRUE; // trailCC==0 + } + // if(trailCC==1) test leadCC==0, same as checking for before-boundary + // TRUE if leadCC==0 (hasFCDBoundaryBefore()) + return (firstUnit&MAPPING_HAS_CCC_LCCC_WORD)==0 || (*(mapping-1)&0xff00)==0; } /* @@ -1310,6 +1347,7 @@ Normalizer2Impl::composePair(UChar32 a, UChar32 b) const { if(isInert(norm16)) { return U_SENTINEL; } else if(norm16minYesNo) { // composite 'a' has both mapping & compositions list list+= // mapping pointer - 1+ // +1 to skip the first unit with the mapping lenth + 1+ // +1 to skip the first unit with the mapping length (*list&MAPPING_LENGTH_MASK); // + mapping length } } } else if(norm16=minNoNo. + // The current character is either a "noNo" (has a mapping) + // or a "maybeYes" (combines backward) + // or a "yesYes" with ccc!=0. + // It is not a Hangul syllable or Jamo L because those have "yes" properties. - src+=U16_LENGTH(c); - /* - * isCompYesAndZeroCC(norm16) is false, that is, norm16>=minNoNo. - * c is either a "noNo" (has a mapping) or a "maybeYes" (combines backward) - * or has ccc!=0. - * Check for Jamo V/T, then for regular characters. - * c is not a Hangul syllable or Jamo L because those have "yes" properties. - */ - if(isJamoVT(norm16) && prevBoundary!=prevSrc) { + // Medium-fast path: Handle cases that do not require full decomposition and recomposition. + if (!isMaybeOrNonZeroCC(norm16)) { // minNoNo <= norm16 < minMaybeYes + if (!doCompose) { + return FALSE; + } + // Fast path for mapping a character that is immediately surrounded by boundaries. + // In this case, we need not decompose around the current character. + if (isDecompNoAlgorithmic(norm16)) { + // Maps to a single isCompYesAndZeroCC character + // which also implies hasCompBoundaryBefore. + if (norm16HasCompBoundaryAfter(norm16, onlyContiguous) || + hasCompBoundaryBefore(src, limit)) { + if (prevBoundary != prevSrc && !buffer.appendZeroCC(prevBoundary, prevSrc, errorCode)) { + break; + } + if(!buffer.append(mapAlgorithmic(c, norm16), 0, errorCode)) { + break; + } + prevBoundary = src; + continue; + } + } else if (norm16 < minNoNoCompBoundaryBefore) { + // The mapping is comp-normalized which also implies hasCompBoundaryBefore. + if (norm16HasCompBoundaryAfter(norm16, onlyContiguous) || + hasCompBoundaryBefore(src, limit)) { + if (prevBoundary != prevSrc && !buffer.appendZeroCC(prevBoundary, prevSrc, errorCode)) { + break; + } + const UChar *mapping = reinterpret_cast(getMapping(norm16)); + int32_t length = *mapping++ & MAPPING_LENGTH_MASK; + if(!buffer.appendZeroCC(mapping, mapping + length, errorCode)) { + break; + } + prevBoundary = src; + continue; + } + } else if (norm16 >= minNoNoEmpty) { + // The current character maps to nothing. + // Simply omit it from the output if there is a boundary before _or_ after it. + // The character itself implies no boundaries. + if (hasCompBoundaryBefore(src, limit) || + hasCompBoundaryAfter(prevBoundary, prevSrc, onlyContiguous)) { + if (prevBoundary != prevSrc && !buffer.appendZeroCC(prevBoundary, prevSrc, errorCode)) { + break; + } + prevBoundary = src; + continue; + } + } + // Other "noNo" type, or need to examine more text around this character: + // Fall through to the slow path. + } else if (isJamoVT(norm16) && prevBoundary != prevSrc) { UChar prev=*(prevSrc-1); - UBool needToDecompose=FALSE; if(c= 0) { + UChar32 syllable = Hangul::HANGUL_BASE + + (l*Hangul::JAMO_V_COUNT + (c-Hangul::JAMO_V_BASE)) * + Hangul::JAMO_T_COUNT + t; + --prevSrc; // Replace the Jamo L as well. + if (prevBoundary != prevSrc && !buffer.appendZeroCC(prevBoundary, prevSrc, errorCode)) { + break; + } + if(!buffer.appendBMP((UChar)syllable, 0, errorCode)) { + break; + } + prevBoundary = src; continue; } // If we see L+V+x where x!=T then we drop to the slow path, // decompose and recompose. // This is to deal with NFKC finding normal L and V but a - // compatibility variant of a T. We need to either fully compose that - // combination here (which would complicate the code and may not work - // with strange custom data) or use the slow path -- or else our replacing - // two input characters (L+V) with one output character (LV syllable) - // would violate the invariant that [prevBoundary..prevSrc[ has the same - // length as what we appended to the buffer since prevBoundary. - needToDecompose=TRUE; + // compatibility variant of a T. + // We need to either fully compose that combination here + // (which would complicate the code and may not work with strange custom data) + // or use the slow path. } - } else if(Hangul::isHangulWithoutJamoT(prev)) { - // c is a Jamo Trailing consonant, + } else if (Hangul::isHangulLV(prev)) { + // The current character is a Jamo Trailing consonant, // compose with previous Hangul LV that does not contain a Jamo T. - if(!doCompose) { + if (!doCompose) { return FALSE; } - buffer.setLastChar((UChar)(prev+c-Hangul::JAMO_T_BASE)); - prevBoundary=src; - continue; - } - if(!needToDecompose) { - // The Jamo V/T did not compose into a Hangul syllable. - if(doCompose) { - if(!buffer.appendBMP((UChar)c, 0, errorCode)) { - break; - } - } else { - prevCC=0; - } - continue; - } - } - /* - * Source buffer pointers: - * - * all done quick check current char not yet - * "yes" but (c) processed - * may combine - * forward - * [-------------[-------------[-------------[-------------[ - * | | | | | - * orig. src prevBoundary prevSrc src limit - * - * - * Destination buffer pointers inside the ReorderingBuffer: - * - * all done might take not filled yet - * characters for - * reordering - * [-------------[-------------[-------------[ - * | | | | - * start reorderStart limit | - * +remainingCap.+ - */ - if(norm16>=MIN_YES_YES_WITH_CC) { - uint8_t cc=(uint8_t)norm16; // cc!=0 - if( onlyContiguous && // FCC - (doCompose ? buffer.getLastCC() : prevCC)==0 && - prevBoundarycc - ) { - // Fails FCD test, need to decompose and contiguously recompose. - if(!doCompose) { - return FALSE; - } - } else if(doCompose) { - if(!buffer.append(c, cc, errorCode)) { + UChar32 syllable = prev + c - Hangul::JAMO_T_BASE; + --prevSrc; // Replace the Hangul LV as well. + if (prevBoundary != prevSrc && !buffer.appendZeroCC(prevBoundary, prevSrc, errorCode)) { break; } + if(!buffer.appendBMP((UChar)syllable, 0, errorCode)) { + break; + } + prevBoundary = src; continue; - } else if(prevCC<=cc) { - prevCC=cc; - continue; - } else { - return FALSE; } - } else if(!doCompose && !isMaybeOrNonZeroCC(norm16)) { - return FALSE; + // No matching context, or may need to decompose surrounding text first: + // Fall through to the slow path. + } else if (norm16 > JAMO_VT) { // norm16 >= MIN_YES_YES_WITH_CC + // One or more combining marks that do not combine-back: + // Check for canonical order, copy unchanged if ok and + // if followed by a character with a boundary-before. + uint8_t cc = getCCFromNormalYesOrMaybe(norm16); // cc!=0 + if (onlyContiguous /* FCC */ && getPreviousTrailCC(prevBoundary, prevSrc) > cc) { + // Fails FCD test, need to decompose and contiguously recompose. + if (!doCompose) { + return FALSE; + } + } else { + // If !onlyContiguous (not FCC), then we ignore the tccc of + // the previous character which passed the quick check "yes && ccc==0" test. + const UChar *nextSrc; + uint16_t n16; + for (;;) { + if (src == limit) { + if (doCompose) { + buffer.appendZeroCC(prevBoundary, limit, errorCode); + } + return TRUE; + } + uint8_t prevCC = cc; + nextSrc = src; + UTRIE2_U16_NEXT16(normTrie, nextSrc, limit, c, n16); + if (n16 >= MIN_YES_YES_WITH_CC) { + cc = getCCFromNormalYesOrMaybe(n16); + if (prevCC > cc) { + if (!doCompose) { + return FALSE; + } + break; + } + } else { + break; + } + src = nextSrc; + } + // src is after the last in-order combining mark. + // If there is a boundary here, then we continue with no change. + if (norm16HasCompBoundaryBefore(n16)) { + if (isCompYesAndZeroCC(n16)) { + src = nextSrc; + } + continue; + } + // Use the slow path. There is no boundary in [prevSrc, src[. + } } - /* - * Find appropriate boundaries around this character, - * decompose the source text from between the boundaries, - * and recompose it. - * - * We may need to remove the last few characters from the ReorderingBuffer - * to account for source text that was copied or appended - * but needs to take part in the recomposition. - */ - - /* - * Find the last composition boundary in [prevBoundary..src[. - * It is either the decomposition of the current character (at prevSrc), - * or prevBoundary. - */ - if(hasCompBoundaryBefore(c, norm16)) { - prevBoundary=prevSrc; - } else if(doCompose) { - buffer.removeSuffix((int32_t)(prevSrc-prevBoundary)); + // Slow path: Find the nearest boundaries around the current character, + // decompose and recompose. + if (prevBoundary != prevSrc && !norm16HasCompBoundaryBefore(norm16)) { + const UChar *p = prevSrc; + UTRIE2_U16_PREV16(normTrie, prevBoundary, p, c, norm16); + if (!norm16HasCompBoundaryAfter(norm16, onlyContiguous)) { + prevSrc = p; + } } - - // Find the next composition boundary in [src..limit[ - - // modifies src to point to the next starter. - src=(UChar *)findNextCompBoundary(src, limit); - - // Decompose [prevBoundary..src[ into the buffer and then recompose that part of it. - int32_t recomposeStartIndex=buffer.length(); - if(!decomposeShort(prevBoundary, src, buffer, errorCode)) { + if (doCompose && prevBoundary != prevSrc && !buffer.appendZeroCC(prevBoundary, prevSrc, errorCode)) { break; } + int32_t recomposeStartIndex=buffer.length(); + // We know there is not a boundary here. + decomposeShort(prevSrc, src, FALSE /* !stopAtCompBoundary */, onlyContiguous, + buffer, errorCode); + // Decompose until the next boundary. + src = decomposeShort(src, limit, TRUE /* stopAtCompBoundary */, onlyContiguous, + buffer, errorCode); + if (U_FAILURE(errorCode)) { + break; + } + if ((src - prevSrc) > INT32_MAX) { // guard before buffer.equals() + errorCode = U_INDEX_OUTOFBOUNDS_ERROR; + return TRUE; + } recompose(buffer, recomposeStartIndex, onlyContiguous); if(!doCompose) { - if(!buffer.equals(prevBoundary, src)) { + if(!buffer.equals(prevSrc, src)) { return FALSE; } buffer.remove(); - prevCC=0; } - - // Move to the next starter. We never need to look back before this point again. prevBoundary=src; } return TRUE; @@ -1619,30 +1674,28 @@ const UChar * Normalizer2Impl::composeQuickCheck(const UChar *src, const UChar *limit, UBool onlyContiguous, UNormalizationCheckResult *pQCResult) const { - /* - * prevBoundary points to the last character before the current one - * that has a composition boundary before it with ccc==0 and quick check "yes". - */ const UChar *prevBoundary=src; UChar32 minNoMaybeCP=minCompNoMaybeCP; if(limit==NULL) { UErrorCode errorCode=U_ZERO_ERROR; src=copyLowPrefixFromNulTerminated(src, minNoMaybeCP, NULL, errorCode); - if(prevBoundary=minNoNo. + // The current character is either a "noNo" (has a mapping) + // or a "maybeYes" (combines backward) + // or a "yesYes" with ccc!=0. + // It is not a Hangul syllable or Jamo L because those have "yes" properties. + + uint16_t prevNorm16 = INERT; + if (prevBoundary != prevSrc) { + if (norm16HasCompBoundaryBefore(norm16)) { + prevBoundary = prevSrc; + } else { + const UChar *p = prevSrc; + uint16_t n16; + UTRIE2_U16_PREV16(normTrie, prevBoundary, p, c, n16); + if (norm16HasCompBoundaryAfter(n16, onlyContiguous)) { + prevBoundary = prevSrc; + } else { + prevBoundary = p; + prevNorm16 = n16; + } } - prevCC=0; - // The start of the current character (c). - prevSrc=src; } - src+=U16_LENGTH(c); - /* - * isCompYesAndZeroCC(norm16) is false, that is, norm16>=minNoNo. - * c is either a "noNo" (has a mapping) or a "maybeYes" (combines backward) - * or has ccc!=0. - */ if(isMaybeOrNonZeroCC(norm16)) { uint8_t cc=getCCFromYesOrMaybe(norm16); - if( onlyContiguous && // FCC - cc!=0 && - prevCC==0 && - prevBoundarycc - ) { - // Fails FCD test. - } else if(prevCC<=cc || cc==0) { - prevCC=cc; - if(norm16 cc) { + // The [prevBoundary..prevSrc[ character + // passed the quick check "yes && ccc==0" test + // but is out of canonical order with the current combining mark. + } else { + // If !onlyContiguous (not FCC), then we ignore the tccc of + // the previous character which passed the quick check "yes && ccc==0" test. + const UChar *nextSrc; + for (;;) { + if (norm16 < MIN_YES_YES_WITH_CC) { + if (pQCResult != nullptr) { + *pQCResult = UNORM_MAYBE; + } else { + return prevBoundary; + } } + if (src == limit) { + return src; + } + uint8_t prevCC = cc; + nextSrc = src; + UTRIE2_U16_NEXT16(normTrie, nextSrc, limit, c, norm16); + if (isMaybeOrNonZeroCC(norm16)) { + cc = getCCFromYesOrMaybe(norm16); + if (!(prevCC <= cc || cc == 0)) { + break; + } + } else { + break; + } + src = nextSrc; + } + // src is after the last in-order combining mark. + if (isCompYesAndZeroCC(norm16)) { + prevBoundary = src; + src = nextSrc; + continue; } - continue; } } if(pQCResult!=NULL) { @@ -1732,10 +1806,10 @@ void Normalizer2Impl::composeAndAppend(const UChar *src, const UChar *limit, ReorderingBuffer &buffer, UErrorCode &errorCode) const { if(!buffer.isEmpty()) { - const UChar *firstStarterInSrc=findNextCompBoundary(src, limit); + const UChar *firstStarterInSrc=findNextCompBoundary(src, limit, onlyContiguous); if(src!=firstStarterInSrc) { const UChar *lastStarterInDest=findPreviousCompBoundary(buffer.getStart(), - buffer.getLimit()); + buffer.getLimit(), onlyContiguous); int32_t destSuffixLength=(int32_t)(buffer.getLimit()-lastStarterInDest); UnicodeString middle(lastStarterInDest, destSuffixLength); buffer.removeSuffix(destSuffixLength); @@ -1760,162 +1834,37 @@ void Normalizer2Impl::composeAndAppend(const UChar *src, const UChar *limit, } } -namespace { - -const int32_t COMP_NO_CP = 0xfffffc00; // U_SENTINEL << 10 (negative) -const int32_t COMP_BOUNDARY_BEFORE = 0x200; -const int32_t COMP_BOUNDARY_AFTER = 0x100; - -} // namespace - -/** - * Returns composition properties as an int with bit fields. - * Bits 31..10: algorithmic-decomp cp if that is compYes, else U_SENTINEL - * Bit 9: has boundary before - * Bit 8: has boundary after - * Bits 7..0: tccc if decompNo, else 0 - */ -int32_t -Normalizer2Impl::getCompProps(const uint8_t *src, const uint8_t *limit, - uint16_t norm16, UBool onlyContiguous) const { - UChar32 c = U_SENTINEL; - for (;;) { - if (isInert(norm16)) { - return (c << 10) | COMP_BOUNDARY_BEFORE | COMP_BOUNDARY_AFTER; - } else if (norm16 <= minYesNo) { - int32_t props = COMP_BOUNDARY_BEFORE; - // Hangul: norm16==minYesNo - // Hangul LVT has a boundary after it. - // Hangul LV and non-inert yesYes characters combine forward. - if (isHangul(norm16)) { - // Do not modify c so that we don't confuse the fast path - // for algorithmic decompositions surrounded by boundaries. - UChar syllable; - if (c >= 0) { - syllable = (UChar)c; - } else { - // One branch of codePointFromValidUTF8(src, limit). - U_ASSERT((limit - src) == 3); - syllable = (UChar)((*src<<12) | ((src[1]&0x3f)<<6) | (src[2]&0x3f)); - } - if (!Hangul::isHangulWithoutJamoT(syllable)) { - props |= COMP_BOUNDARY_AFTER; - } - } - return (c << 10) | props; - } else if (norm16 >= minMaybeYes) { - if (norm16 >= MIN_YES_YES_WITH_CC) { - return (c << 10); - } else { - // Do not return c>=0 for a compMaybe character. - return COMP_NO_CP; - } - } else if (isDecompNoAlgorithmic(norm16)) { - if (c < 0) { - c = codePointFromValidUTF8(src, limit); - } - c = mapAlgorithmic(c, norm16); - norm16 = getNorm16(c); - } else { - // c decomposes, get everything from the variable-length extra data. - const uint16_t *mapping = getMapping(norm16); - uint16_t firstUnit = *mapping; - int32_t props = firstUnit >> 8; // tccc - if (norm16 < minNoNo) { - props |= (c << 10) | COMP_BOUNDARY_BEFORE; - } else { - // Do not return c>=0 for a compNo character. - props |= COMP_NO_CP; - if ((firstUnit & MAPPING_LENGTH_MASK) != 0 && - ((firstUnit & MAPPING_HAS_CCC_LCCC_WORD) == 0 || - (*(mapping-1) & 0xff00) == 0)) { - // The decomposition is not empty, and lccc==0. - int32_t i = 1; // skip over the firstUnit - UChar32 firstCP; - U16_NEXT_UNSAFE(mapping, i, firstCP); - if (isCompYesAndZeroCC(getNorm16(firstCP))) { - props |= COMP_BOUNDARY_BEFORE; - } - } - } - // comp-boundary-after if - // not MAPPING_NO_COMP_BOUNDARY_AFTER - // (which is set if - // c is not deleted, and - // it and its decomposition do not combine forward, and it has a starter) - // and if FCC then trailCC<=1 - if ((firstUnit & MAPPING_NO_COMP_BOUNDARY_AFTER) == 0 && - (!onlyContiguous || firstUnit <= 0x1ff)) { - props |= COMP_BOUNDARY_AFTER; - } - return props; - } - } -} - UBool -Normalizer2Impl::composeUTF8(uint32_t options, +Normalizer2Impl::composeUTF8(uint32_t options, UBool onlyContiguous, const uint8_t *src, const uint8_t *limit, - UBool onlyContiguous, UBool doCompose, - ByteSink &sink, Edits *edits, UErrorCode &errorCode) const { + ByteSink *sink, Edits *edits, UErrorCode &errorCode) const { U_ASSERT(limit != nullptr); + UnicodeString s16; uint8_t minNoMaybeLead = leadByteForCP(minCompNoMaybeCP); + const uint8_t *prevBoundary = src; for (;;) { // Fast path: Scan over a sequence of characters below the minimum "no or maybe" code point, // or with (compYes && ccc==0) properties. - const uint8_t *prevSrc = src; - const uint8_t *nextSrc; + const uint8_t *prevSrc; uint16_t norm16 = 0; for (;;) { if (src == limit) { - if (src != prevSrc && doCompose) { - appendUnchanged(prevSrc, limit, sink, options, edits, errorCode); + if (prevBoundary != limit && sink != nullptr) { + appendUnchanged(prevBoundary, limit, *sink, options, edits, errorCode); } return TRUE; } if (*src < minNoMaybeLead) { ++src; } else { - nextSrc = src; - UTRIE2_U8_NEXT16(normTrie, nextSrc, limit, norm16); - if (isCompYesAndZeroCC(norm16)) { - src = nextSrc; - } else { + prevSrc = src; + UTRIE2_U8_NEXT16(normTrie, src, limit, norm16); + if (!isCompYesAndZeroCC(norm16)) { break; } } } - - // Copy this sequence. - // Omit the last character if there is not a boundary between it and the current one. - int32_t props = getCompProps(src, nextSrc, norm16, onlyContiguous); - int32_t prevProps = 0; - if (src != prevSrc) { - const uint8_t *p = src; - if ((props & COMP_BOUNDARY_BEFORE) == 0) { - uint16_t prevNorm16 = 0; - UTRIE2_U8_PREV16(normTrie, prevSrc, p, prevNorm16); - prevProps = getCompProps(p, src, prevNorm16, onlyContiguous); - if (prevProps & COMP_BOUNDARY_AFTER) { - p = src; - } - } - if (p != prevSrc) { - if (doCompose) { - if ((limit - prevSrc) <= INT32_MAX) { - // Allocation hint for the full remaining string, - // not just for what we are copying now. - giveByteSinkAllocationHint(sink, (int32_t)(limit - prevSrc)); - } - if (!appendUnchanged(prevSrc, p, sink, options, edits, errorCode)) { - break; - } - } - prevSrc = p; - } - } - // isCompYesAndZeroCC(norm16) is false, that is, norm16>=minNoNo. // The current character is either a "noNo" (has a mapping) // or a "maybeYes" (combines backward) @@ -1924,47 +1873,93 @@ Normalizer2Impl::composeUTF8(uint32_t options, // Medium-fast path: Handle cases that do not require full decomposition and recomposition. if (!isMaybeOrNonZeroCC(norm16)) { // minNoNo <= norm16 < minMaybeYes - if (!doCompose) { + if (sink == nullptr) { return FALSE; } // Fast path for mapping a character that is immediately surrounded by boundaries. - // In this case, we need not decompose around the current character - // So far, we only do this for algorithmic mappings to a compYes code point; - // props>=0 only when this is the case. - // Algorithmic mappings are common when the normalization data includes case folding. - // If we knew that a full decomposition is composition-normalized - // (does not partially recompose), - // or if we had the recomposition directly available in the data, - // then we could extend this fastpath to such mappings. - if (props >= 0 && // alg. decomp to compYes - prevSrc == src && // has boundary before - ((props & COMP_BOUNDARY_AFTER) || hasCompBoundaryBefore(nextSrc, limit))) { - appendCodePoint(src, nextSrc, props >> 10, sink, edits); - src = nextSrc; - continue; + // In this case, we need not decompose around the current character. + if (isDecompNoAlgorithmic(norm16)) { + // Maps to a single isCompYesAndZeroCC character + // which also implies hasCompBoundaryBefore. + if (norm16HasCompBoundaryAfter(norm16, onlyContiguous) || + hasCompBoundaryBefore(src, limit)) { + if (prevBoundary != prevSrc && + !appendUnchanged(prevBoundary, prevSrc, *sink, options, edits, errorCode)) { + break; + } + appendCodePointDelta(prevSrc, src, getAlgorithmicDelta(norm16), *sink, edits); + prevBoundary = src; + continue; + } + } else if (norm16 < minNoNoCompBoundaryBefore) { + // The mapping is comp-normalized which also implies hasCompBoundaryBefore. + if (norm16HasCompBoundaryAfter(norm16, onlyContiguous) || + hasCompBoundaryBefore(src, limit)) { + if (prevBoundary != prevSrc && + !appendUnchanged(prevBoundary, prevSrc, *sink, options, edits, errorCode)) { + break; + } + const uint16_t *mapping = getMapping(norm16); + int32_t length = *mapping++ & MAPPING_LENGTH_MASK; + if (!appendChange(prevSrc, src, (const UChar *)mapping, length, + *sink, edits, errorCode)) { + break; + } + prevBoundary = src; + continue; + } + } else if (norm16 >= minNoNoEmpty) { + // The current character maps to nothing. + // Simply omit it from the output if there is a boundary before _or_ after it. + // The character itself implies no boundaries. + if (hasCompBoundaryBefore(src, limit) || + hasCompBoundaryAfter(prevBoundary, prevSrc, onlyContiguous)) { + if (prevBoundary != prevSrc && + !appendUnchanged(prevBoundary, prevSrc, *sink, options, edits, errorCode)) { + break; + } + if (edits != nullptr) { + edits->addReplace((int32_t)(src - prevSrc), 0); + } + prevBoundary = src; + continue; + } } - } else if (isJamoVT(norm16) && prevSrc != src) { + // Other "noNo" type, or need to examine more text around this character: + // Fall through to the slow path. + } else if (isJamoVT(norm16)) { // Jamo L: E1 84 80..92 // Jamo V: E1 85 A1..B5 // Jamo T: E1 86 A8..E1 87 82 - U_ASSERT((nextSrc - src) == 3 && *src == 0xe1); - UChar32 prev; - if (src[1] == 0x85) { + U_ASSERT((src - prevSrc) == 3 && *prevSrc == 0xe1); + UChar32 prev = previousHangulOrJamo(prevBoundary, prevSrc); + if (prevSrc[1] == 0x85) { // The current character is a Jamo Vowel, // compose with previous Jamo L and following Jamo T. - if ((prev = getJamoLMinusBase(prevSrc, src)) >= 0) { - if (!doCompose) { + UChar32 l = prev - Hangul::JAMO_L_BASE; + if ((uint32_t)l < Hangul::JAMO_L_COUNT) { + if (sink == nullptr) { return FALSE; } - UChar32 syllable = Hangul::HANGUL_BASE + - (prev*Hangul::JAMO_V_COUNT + (src[2]-0xa1)) * - Hangul::JAMO_T_COUNT; - int32_t t = getJamoTMinusBase(nextSrc, limit); + int32_t t = getJamoTMinusBase(src, limit); if (t >= 0) { - nextSrc += 3; - syllable += t; // The next character was a Jamo T. - appendCodePoint(prevSrc, nextSrc, syllable, sink, edits); - src = nextSrc; + // The next character is a Jamo T. + src += 3; + } else if (hasCompBoundaryBefore(src, limit)) { + // No Jamo T follows, not even via decomposition. + t = 0; + } + if (t >= 0) { + UChar32 syllable = Hangul::HANGUL_BASE + + (l*Hangul::JAMO_V_COUNT + (prevSrc[2]-0xa1)) * + Hangul::JAMO_T_COUNT + t; + prevSrc -= 3; // Replace the Jamo L as well. + if (prevBoundary != prevSrc && + !appendUnchanged(prevBoundary, prevSrc, *sink, options, edits, errorCode)) { + break; + } + appendCodePoint(prevSrc, src, syllable, *sink, edits); + prevBoundary = src; continue; } // If we see L+V+x where x!=T then we drop to the slow path, @@ -1975,47 +1970,53 @@ Normalizer2Impl::composeUTF8(uint32_t options, // (which would complicate the code and may not work with strange custom data) // or use the slow path. } - } else if (Hangul::isHangulWithoutJamoT(prev = codePointFromValidUTF8(prevSrc, src))) { + } else if (Hangul::isHangulLV(prev)) { // The current character is a Jamo Trailing consonant, // compose with previous Hangul LV that does not contain a Jamo T. - if (!doCompose) { + if (sink == nullptr) { return FALSE; } - UChar32 syllable = prev + getJamoTMinusBase(src, nextSrc); - appendCodePoint(prevSrc, nextSrc, syllable, sink, edits); - src = nextSrc; + UChar32 syllable = prev + getJamoTMinusBase(prevSrc, src); + prevSrc -= 3; // Replace the Hangul LV as well. + if (prevBoundary != prevSrc && + !appendUnchanged(prevBoundary, prevSrc, *sink, options, edits, errorCode)) { + break; + } + appendCodePoint(prevSrc, src, syllable, *sink, edits); + prevBoundary = src; continue; } + // No matching context, or may need to decompose surrounding text first: + // Fall through to the slow path. } else if (norm16 > JAMO_VT) { // norm16 >= MIN_YES_YES_WITH_CC // One or more combining marks that do not combine-back: // Check for canonical order, copy unchanged if ok and // if followed by a character with a boundary-before. - uint8_t cc = (uint8_t)norm16; // cc!=0 - if (onlyContiguous /* FCC */ && (uint8_t)prevProps > cc) { + uint8_t cc = getCCFromNormalYesOrMaybe(norm16); // cc!=0 + if (onlyContiguous /* FCC */ && getPreviousTrailCC(prevBoundary, prevSrc) > cc) { // Fails FCD test, need to decompose and contiguously recompose. - if (!doCompose) { + if (sink == nullptr) { return FALSE; } } else { // If !onlyContiguous (not FCC), then we ignore the tccc of // the previous character which passed the quick check "yes && ccc==0" test. - const uint8_t *p = nextSrc; - const uint8_t *q; + const uint8_t *nextSrc; uint16_t n16; for (;;) { - if (p == limit) { - if (doCompose) { - appendUnchanged(prevSrc, limit, sink, options, edits, errorCode); + if (src == limit) { + if (sink != nullptr) { + appendUnchanged(prevBoundary, limit, *sink, options, edits, errorCode); } return TRUE; } uint8_t prevCC = cc; - q = p; - UTRIE2_U8_NEXT16(normTrie, q, limit, n16); + nextSrc = src; + UTRIE2_U8_NEXT16(normTrie, nextSrc, limit, n16); if (n16 >= MIN_YES_YES_WITH_CC) { - cc = (uint8_t)n16; + cc = getCCFromNormalYesOrMaybe(n16); if (prevCC > cc) { - if (!doCompose) { + if (sink == nullptr) { return FALSE; } break; @@ -2023,165 +2024,151 @@ Normalizer2Impl::composeUTF8(uint32_t options, } else { break; } - p = q; + src = nextSrc; } - // p is after the last in-order combining mark. - // If there is a boundary here, then we copy and continue. - // Copy some of hasCompBoundaryBefore() to postpone decoding the code point. - if (isCompYesAndZeroCC(n16) || - (!isMaybeOrNonZeroCC(n16) && - hasCompBoundaryBefore(codePointFromValidUTF8(p, q), n16))) { - if (doCompose && !appendUnchanged(prevSrc, p, sink, options, edits, errorCode)) { - return TRUE; + // src is after the last in-order combining mark. + // If there is a boundary here, then we continue with no change. + if (norm16HasCompBoundaryBefore(n16)) { + if (isCompYesAndZeroCC(n16)) { + src = nextSrc; } - src = p; continue; } - // Use the slow path. There is no boundary in [nextSrc, p[. - nextSrc = p; + // Use the slow path. There is no boundary in [prevSrc, src[. } } // Slow path: Find the nearest boundaries around the current character, // decompose and recompose. - // TODO: Inefficient create&destroy of the buffer because - // we want to avoid creating one if we do not need it. - // Try to make it cheaper, try to use a plain char16_t[] on the stack - // until it overflows. - // TODO: Port this newer code with Edits support, - // and maybe with Appendable style if it does not noticeably hurt UnicodeString performance, - // back to UTF-16. - // Should be able to remove some then-unnecessary code from ReorderingBuffer. - // Might not need findNextCompBoundary() and such any more. - UnicodeString s16; - ReorderingBuffer buffer(*this, s16); - // Decompose the previous (if any) and current characters. - // We know there is not a boundary here. - decomposeShort(prevSrc, nextSrc, FALSE /* !stopAtCompBoundary */, buffer, errorCode); - // Decompose until the next boundary. - src = decomposeShort(nextSrc, limit, TRUE /* stopAtCompBoundary */, buffer, errorCode); - if (src == nullptr) { // U_FAILURE + if (prevBoundary != prevSrc && !norm16HasCompBoundaryBefore(norm16)) { + const uint8_t *p = prevSrc; + UTRIE2_U8_PREV16(normTrie, prevBoundary, p, norm16); + if (!norm16HasCompBoundaryAfter(norm16, onlyContiguous)) { + prevSrc = p; + } + } + ReorderingBuffer buffer(*this, s16, errorCode); + if (U_FAILURE(errorCode)) { break; } - if ((src - prevSrc) > INT32_MAX) { + // We know there is not a boundary here. + decomposeShort(prevSrc, src, FALSE /* !stopAtCompBoundary */, onlyContiguous, + buffer, errorCode); + // Decompose until the next boundary. + src = decomposeShort(src, limit, TRUE /* stopAtCompBoundary */, onlyContiguous, + buffer, errorCode); + if (U_FAILURE(errorCode)) { + break; + } + if ((src - prevSrc) > INT32_MAX) { // guard before buffer.equals() errorCode = U_INDEX_OUTOFBOUNDS_ERROR; return TRUE; } recompose(buffer, 0, onlyContiguous); - if (buffer.equals(prevSrc, src)) { - if (doCompose && !appendUnchanged(prevSrc, src, sink, options, edits, errorCode)) { + if (!buffer.equals(prevSrc, src)) { + if (sink == nullptr) { + return FALSE; + } + if (prevBoundary != prevSrc && + !appendUnchanged(prevBoundary, prevSrc, *sink, options, edits, errorCode)) { break; } - } else if (doCompose) { if (!appendChange(prevSrc, src, buffer.getStart(), buffer.length(), - sink, edits, errorCode)) { + *sink, edits, errorCode)) { break; } - } else { - return TRUE; + prevBoundary = src; } } return TRUE; } -/** - * Does c have a composition boundary before it? - * True if its decomposition begins with a character that has - * ccc=0 && NFC_QC=Yes (isCompYesAndZeroCC()). - * As a shortcut, this is true if c itself has ccc=0 && NFC_QC=Yes - * (isCompYesAndZeroCC()) so we need not decompose. - */ -UBool Normalizer2Impl::hasCompBoundaryBefore(UChar32 c, uint16_t norm16) const { - for(;;) { - if(isCompYesAndZeroCC(norm16)) { - return TRUE; - } else if(isMaybeOrNonZeroCC(norm16)) { - return FALSE; - } else if(isDecompNoAlgorithmic(norm16)) { - c=mapAlgorithmic(c, norm16); - norm16=getNorm16(c); - } else { - // c decomposes, get everything from the variable-length extra data - const uint16_t *mapping=getMapping(norm16); - uint16_t firstUnit=*mapping; - if((firstUnit&MAPPING_LENGTH_MASK)==0) { - return FALSE; - } - if((firstUnit&MAPPING_HAS_CCC_LCCC_WORD) && (*(mapping-1)&0xff00)) { - return FALSE; // non-zero leadCC - } - int32_t i=1; // skip over the firstUnit - UChar32 c; - U16_NEXT_UNSAFE(mapping, i, c); - return isCompYesAndZeroCC(getNorm16(c)); - } - } -} - -UBool Normalizer2Impl::hasCompBoundaryAfter(UChar32 c, UBool onlyContiguous, UBool testInert) const { - for(;;) { - uint16_t norm16=getNorm16(c); - if(isInert(norm16)) { - return TRUE; - } else if(norm16= (testInert ? minNoNo : minMaybeYes)) { - return FALSE; - } else if(isDecompNoAlgorithmic(norm16)) { - c=mapAlgorithmic(c, norm16); - } else { - // c decomposes, get everything from the variable-length extra data. - // If testInert, then c must be a yesNo character which has lccc=0, - // otherwise it could be a noNo. - const uint16_t *mapping=getMapping(norm16); - uint16_t firstUnit=*mapping; - // TRUE if - // not MAPPING_NO_COMP_BOUNDARY_AFTER - // (which is set if - // c is not deleted, and - // it and its decomposition do not combine forward, and it has a starter) - // and if FCC then trailCC<=1 - return - (firstUnit&MAPPING_NO_COMP_BOUNDARY_AFTER)==0 && - (!onlyContiguous || firstUnit<=0x1ff); - } +UBool Normalizer2Impl::hasCompBoundaryBefore(const UChar *src, const UChar *limit) const { + if (src == limit || *src < minCompNoMaybeCP) { + return TRUE; } + UChar32 c; + uint16_t norm16; + UTRIE2_U16_NEXT16(normTrie, src, limit, c, norm16); + return norm16HasCompBoundaryBefore(norm16); } UBool Normalizer2Impl::hasCompBoundaryBefore(const uint8_t *src, const uint8_t *limit) const { if (src == limit) { - return FALSE; + return TRUE; } - const uint8_t *q = src; uint16_t norm16; - UTRIE2_U8_NEXT16(normTrie, q, limit, norm16); - // Copy some of hasCompBoundaryBefore() to postpone decoding the code point. - return isCompYesAndZeroCC(norm16) || - (!isMaybeOrNonZeroCC(norm16) && - hasCompBoundaryBefore(codePointFromValidUTF8(src, q), norm16)); + UTRIE2_U8_NEXT16(normTrie, src, limit, norm16); + return norm16HasCompBoundaryBefore(norm16); } -const UChar *Normalizer2Impl::findPreviousCompBoundary(const UChar *start, const UChar *p) const { +UBool Normalizer2Impl::hasCompBoundaryAfter(const UChar *start, const UChar *p, + UBool onlyContiguous) const { + if (start == p) { + return TRUE; + } + UChar32 c; + uint16_t norm16; + UTRIE2_U16_PREV16(normTrie, start, p, c, norm16); + return norm16HasCompBoundaryAfter(norm16, onlyContiguous); +} + +UBool Normalizer2Impl::hasCompBoundaryAfter(const uint8_t *start, const uint8_t *p, + UBool onlyContiguous) const { + if (start == p) { + return TRUE; + } + uint16_t norm16; + UTRIE2_U8_PREV16(normTrie, start, p, norm16); + return norm16HasCompBoundaryAfter(norm16, onlyContiguous); +} + +const UChar *Normalizer2Impl::findPreviousCompBoundary(const UChar *start, const UChar *p, + UBool onlyContiguous) const { BackwardUTrie2StringIterator iter(normTrie, start, p); - uint16_t norm16; - do { - norm16=iter.previous16(); - } while(!hasCompBoundaryBefore(iter.codePoint, norm16)); - // We could also test hasCompBoundaryAfter() and return iter.codePointLimit, - // but that's probably not worth the extra cost. - return iter.codePointStart; + for(;;) { + uint16_t norm16=iter.previous16(); + if (norm16HasCompBoundaryAfter(norm16, onlyContiguous)) { + return iter.codePointLimit; + } + if (hasCompBoundaryBefore(iter.codePoint, norm16)) { + return iter.codePointStart; + } + } } -const UChar *Normalizer2Impl::findNextCompBoundary(const UChar *p, const UChar *limit) const { +const UChar *Normalizer2Impl::findNextCompBoundary(const UChar *p, const UChar *limit, + UBool onlyContiguous) const { ForwardUTrie2StringIterator iter(normTrie, p, limit); - uint16_t norm16; - do { - norm16=iter.next16(); - } while(!hasCompBoundaryBefore(iter.codePoint, norm16)); - return iter.codePointStart; + for(;;) { + uint16_t norm16=iter.next16(); + if (hasCompBoundaryBefore(iter.codePoint, norm16)) { + return iter.codePointStart; + } + if (norm16HasCompBoundaryAfter(norm16, onlyContiguous)) { + return iter.codePointLimit; + } + } +} + +uint8_t Normalizer2Impl::getPreviousTrailCC(const UChar *start, const UChar *p) const { + if (start == p) { + return 0; + } + int32_t i = (int32_t)(p - start); + UChar32 c; + U16_PREV(start, 0, i, c); + return (uint8_t)getFCD16(c); +} + +uint8_t Normalizer2Impl::getPreviousTrailCC(const uint8_t *start, const uint8_t *p) const { + if (start == p) { + return 0; + } + int32_t i = (int32_t)(p - start); + UChar32 c; + U8_PREV(start, 0, i, c); + return (uint8_t)getFCD16(c); } // Note: normalizer2impl.cpp r30982 (2011-nov-27) @@ -2189,43 +2176,41 @@ const UChar *Normalizer2Impl::findNextCompBoundary(const UChar *p, const UChar * // That provided faster access to FCD data than getFCD16FromNormData() // but required synchronization and consumed some 10kB of heap memory // in any process that uses FCD (e.g., via collation). -// tccc180[] and smallFCD[] are intended to help with any loss of performance, -// at least for Latin & CJK. +// minDecompNoCP etc. and smallFCD[] are intended to help with any loss of performance, +// at least for ASCII & CJK. // Gets the FCD value from the regular normalization data. uint16_t Normalizer2Impl::getFCD16FromNormData(UChar32 c) const { - // Only loops for 1:1 algorithmic mappings. - for(;;) { - uint16_t norm16=getNorm16(c); - if(norm16<=minYesNo) { - // no decomposition or Hangul syllable, all zeros - return 0; - } else if(norm16>=MIN_NORMAL_MAYBE_YES) { + uint16_t norm16=getNorm16(c); + if (norm16 >= limitNoNo) { + if(norm16>=MIN_NORMAL_MAYBE_YES) { // combining mark - norm16&=0xff; + norm16=getCCFromNormalYesOrMaybe(norm16); return norm16|(norm16<<8); } else if(norm16>=minMaybeYes) { return 0; - } else if(isDecompNoAlgorithmic(norm16)) { - c=mapAlgorithmic(c, norm16); - } else { - // c decomposes, get everything from the variable-length extra data - const uint16_t *mapping=getMapping(norm16); - uint16_t firstUnit=*mapping; - if((firstUnit&MAPPING_LENGTH_MASK)==0) { - // A character that is deleted (maps to an empty string) must - // get the worst-case lccc and tccc values because arbitrary - // characters on both sides will become adjacent. - return 0x1ff; - } else { - norm16=firstUnit>>8; // tccc - if(firstUnit&MAPPING_HAS_CCC_LCCC_WORD) { - norm16|=*(mapping-1)&0xff00; // lccc - } - return norm16; + } else { // isDecompNoAlgorithmic(norm16) + uint16_t deltaTrailCC = norm16 & DELTA_TCCC_MASK; + if (deltaTrailCC <= DELTA_TCCC_1) { + return deltaTrailCC >> OFFSET_SHIFT; } + // Maps to an isCompYesAndZeroCC. + c=mapAlgorithmic(c, norm16); + norm16=getNorm16(c); } } + if(norm16<=minYesNo || isHangulLVT(norm16)) { + // no decomposition or Hangul syllable, all zeros + return 0; + } + // c decomposes, get everything from the variable-length extra data + const uint16_t *mapping=getMapping(norm16); + uint16_t firstUnit=*mapping; + norm16=firstUnit>>8; // tccc + if(firstUnit&MAPPING_HAS_CCC_LCCC_WORD) { + norm16|=*(mapping-1)&0xff00; // lccc + } + return norm16; } // Dual functionality: @@ -2240,7 +2225,7 @@ Normalizer2Impl::makeFCD(const UChar *src, const UChar *limit, const UChar *prevBoundary=src; int32_t prevFCD16=0; if(limit==NULL) { - src=copyLowPrefixFromNulTerminated(src, MIN_CCC_LCCC_CP, buffer, errorCode); + src=copyLowPrefixFromNulTerminated(src, minLcccCP, buffer, errorCode); if(U_FAILURE(errorCode)) { return src; } @@ -2269,7 +2254,7 @@ Normalizer2Impl::makeFCD(const UChar *src, const UChar *limit, for(;;) { // count code units with lccc==0 for(prevSrc=src; src!=limit;) { - if((c=*src)1) { - --prevBoundary; + if(prev1) { + --prevBoundary; + } } } else { const UChar *p=src-1; @@ -2364,7 +2353,8 @@ Normalizer2Impl::makeFCD(const UChar *src, const UChar *limit, * The source text does not fulfill the conditions for FCD. * Decompose and reorder a limited piece of the text. */ - if(!decomposeShort(prevBoundary, src, *buffer, errorCode)) { + decomposeShort(prevBoundary, src, FALSE, FALSE, *buffer, errorCode); + if (U_FAILURE(errorCode)) { break; } prevBoundary=src; @@ -2408,16 +2398,33 @@ void Normalizer2Impl::makeFCDAndAppend(const UChar *src, const UChar *limit, } const UChar *Normalizer2Impl::findPreviousFCDBoundary(const UChar *start, const UChar *p) const { - while(start

0xff) {} + while(startmakeCanonIterDataFromNorm16( - start, end, (uint16_t)value, *impl->fCanonIterData, errorCode); + InitCanonIterData::handleRange(impl, start, end, (uint16_t)value, errorCode); } return U_SUCCESS(errorCode); } +U_CDECL_END - -// UInitOnce instantiation function for CanonIterData - -static void U_CALLCONV -initCanonIterData(Normalizer2Impl *impl, UErrorCode &errorCode) { +void InitCanonIterData::doInit(Normalizer2Impl *impl, UErrorCode &errorCode) { U_ASSERT(impl->fCanonIterData == NULL); impl->fCanonIterData = new CanonIterData(errorCode); if (impl->fCanonIterData == NULL) { errorCode=U_MEMORY_ALLOCATION_ERROR; } if (U_SUCCESS(errorCode)) { - utrie2_enum(impl->getNormTrie(), NULL, enumCIDRangeHandler, impl); + utrie2_enum(impl->normTrie, NULL, enumCIDRangeHandler, impl); utrie2_freeze(impl->fCanonIterData->trie, UTRIE2_32_VALUE_BITS, &errorCode); } if (U_FAILURE(errorCode)) { @@ -2497,12 +2513,15 @@ initCanonIterData(Normalizer2Impl *impl, UErrorCode &errorCode) { } } -U_CDECL_END +void InitCanonIterData::handleRange( + Normalizer2Impl *impl, UChar32 start, UChar32 end, uint16_t value, UErrorCode &errorCode) { + impl->makeCanonIterDataFromNorm16(start, end, value, *impl->fCanonIterData, errorCode); +} -void Normalizer2Impl::makeCanonIterDataFromNorm16(UChar32 start, UChar32 end, uint16_t norm16, +void Normalizer2Impl::makeCanonIterDataFromNorm16(UChar32 start, UChar32 end, const uint16_t norm16, CanonIterData &newData, UErrorCode &errorCode) const { - if(norm16==0 || (minYesNo<=norm16 && norm16=minMaybeYes) { + if(isMaybeOrNonZeroCC(norm16)) { // not a segment starter if it occurs in a decomposition or has cc!=0 newValue|=CANON_NOT_SEGMENT_STARTER; if(norm16 minYesNo) { // c decomposes, get everything from the variable-length extra data const uint16_t *mapping=getMapping(norm16_2); uint16_t firstUnit=*mapping; @@ -2633,7 +2656,7 @@ unorm2_swap(const UDataSwapper *ds, uint8_t *outBytes; const int32_t *inIndexes; - int32_t indexes[Normalizer2Impl::IX_MIN_MAYBE_YES+1]; + int32_t indexes[Normalizer2Impl::IX_TOTAL_SIZE+1]; int32_t i, offset, nextOffset, size; @@ -2651,7 +2674,7 @@ unorm2_swap(const UDataSwapper *ds, pInfo->dataFormat[1]==0x72 && pInfo->dataFormat[2]==0x6d && pInfo->dataFormat[3]==0x32 && - (formatVersion0==1 || formatVersion0==2) + (1<=formatVersion0 && formatVersion0<=3) )) { udata_printError(ds, "unorm2_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as Normalizer2 data\n", pInfo->dataFormat[0], pInfo->dataFormat[1], @@ -2668,8 +2691,10 @@ unorm2_swap(const UDataSwapper *ds, int32_t minIndexesLength; if(formatVersion0==1) { minIndexesLength=Normalizer2Impl::IX_MIN_MAYBE_YES+1; - } else { + } else if(formatVersion0==2) { minIndexesLength=Normalizer2Impl::IX_MIN_YES_NO_MAPPINGS_ONLY+1; + } else { + minIndexesLength=Normalizer2Impl::IX_MIN_LCCC_CP+1; } if(length>=0) { @@ -2683,7 +2708,7 @@ unorm2_swap(const UDataSwapper *ds, } /* read the first few indexes */ - for(i=0; i<=Normalizer2Impl::IX_MIN_MAYBE_YES; ++i) { + for(i=0; i=MIN_NORMAL_MAYBE_YES) { - return (uint8_t)norm16; + return getCCFromNormalYesOrMaybe(norm16); } if(norm16> OFFSET_SHIFT); + } static uint8_t getCCFromYesOrMaybe(uint16_t norm16) { - return norm16>=MIN_NORMAL_MAYBE_YES ? (uint8_t)norm16 : 0; + return norm16>=MIN_NORMAL_MAYBE_YES ? getCCFromNormalYesOrMaybe(norm16) : 0; + } + uint8_t getCCFromYesOrMaybeCP(UChar32 c) const { + if (c < minCompNoMaybeCP) { return 0; } + return getCCFromYesOrMaybe(getNorm16(c)); } /** @@ -276,10 +295,8 @@ public: * @return The lccc(c) in bits 15..8 and tccc(c) in bits 7..0. */ uint16_t getFCD16(UChar32 c) const { - if(c<0) { + if(c1) for quick FCC boundary-after tests. + DELTA_TCCC_0=0, + DELTA_TCCC_1=2, + DELTA_TCCC_GT_1=4, + DELTA_TCCC_MASK=6, + DELTA_SHIFT=3, - enum { - MIN_YES_YES_WITH_CC=0xff01, - JAMO_VT=0xff00, - MIN_NORMAL_MAYBE_YES=0xfe00, - JAMO_L=1, MAX_DELTA=0x40 }; @@ -398,21 +419,32 @@ public: IX_MIN_COMP_NO_MAYBE_CP, // Norm16 value thresholds for quick check combinations and types of extra data. - IX_MIN_YES_NO, // Mappings & compositions in [minYesNo..minYesNoMappingsOnly[. + + // Mappings & compositions in [minYesNo..minYesNoMappingsOnly[. + IX_MIN_YES_NO, + // Mappings are comp-normalized. IX_MIN_NO_NO, IX_LIMIT_NO_NO, IX_MIN_MAYBE_YES, - IX_MIN_YES_NO_MAPPINGS_ONLY, // Mappings only in [minYesNoMappingsOnly..minNoNo[. + // Mappings only in [minYesNoMappingsOnly..minNoNo[. + IX_MIN_YES_NO_MAPPINGS_ONLY, + // Mappings are not comp-normalized but have a comp boundary before. + IX_MIN_NO_NO_COMP_BOUNDARY_BEFORE, + // Mappings do not have a comp boundary before. + IX_MIN_NO_NO_COMP_NO_MAYBE_CC, + // Mappings to the empty string. + IX_MIN_NO_NO_EMPTY, - IX_RESERVED15, + IX_MIN_LCCC_CP, + IX_RESERVED19, IX_COUNT }; enum { MAPPING_HAS_CCC_LCCC_WORD=0x80, MAPPING_HAS_RAW_MAPPING=0x40, - MAPPING_NO_COMP_BOUNDARY_AFTER=0x20, + // unused bit 0x20, MAPPING_LENGTH_MASK=0x1f }; @@ -462,10 +494,10 @@ public: ReorderingBuffer &buffer, UErrorCode &errorCode) const; - UBool composeUTF8(uint32_t options, + /** sink==nullptr: isNormalized() */ + UBool composeUTF8(uint32_t options, UBool onlyContiguous, const uint8_t *src, const uint8_t *limit, - UBool onlyContiguous, UBool doCompose, - ByteSink &sink, icu::Edits *edits, UErrorCode &errorCode) const; + ByteSink *sink, icu::Edits *edits, UErrorCode &errorCode) const; const UChar *makeFCD(const UChar *src, const UChar *limit, ReorderingBuffer *buffer, UErrorCode &errorCode) const; @@ -475,27 +507,42 @@ public: ReorderingBuffer &buffer, UErrorCode &errorCode) const; - UBool hasDecompBoundary(UChar32 c, UBool before) const; + UBool hasDecompBoundaryBefore(UChar32 c) const; + UBool norm16HasDecompBoundaryBefore(uint16_t norm16) const; + UBool hasDecompBoundaryAfter(UChar32 c) const; + UBool norm16HasDecompBoundaryAfter(uint16_t norm16) const; UBool isDecompInert(UChar32 c) const { return isDecompYesAndZeroCC(getNorm16(c)); } UBool hasCompBoundaryBefore(UChar32 c) const { - return c=minMaybeYes; } - static UBool isInert(uint16_t norm16) { return norm16==0; } - static UBool isJamoL(uint16_t norm16) { return norm16==1; } + static UBool isInert(uint16_t norm16) { return norm16==INERT; } + static UBool isJamoL(uint16_t norm16) { return norm16==JAMO_L; } static UBool isJamoVT(uint16_t norm16) { return norm16==JAMO_VT; } - UBool isHangul(uint16_t norm16) const { return norm16==minYesNo; } + uint16_t hangulLVT() const { return minYesNoMappingsOnly|HAS_COMP_BOUNDARY_AFTER; } + UBool isHangulLV(uint16_t norm16) const { return norm16==minYesNo; } + UBool isHangulLVT(uint16_t norm16) const { + return norm16==hangulLVT(); + } UBool isCompYesAndZeroCC(uint16_t norm16) const { return norm16=MIN_YES_YES_WITH_CC || norm16=MIN_YES_YES_WITH_CC ? (uint8_t)norm16 : 0; + // return norm16>=MIN_YES_YES_WITH_CC ? getCCFromNormalYesOrMaybe(norm16) : 0; // } uint8_t getCCFromNoNo(uint16_t norm16) const { const uint16_t *mapping=getMapping(norm16); @@ -535,30 +582,47 @@ private: } } // requires that the [cpStart..cpLimit[ character passes isCompYesAndZeroCC() - uint8_t getTrailCCFromCompYesAndZeroCC(const UChar *cpStart, const UChar *cpLimit) const; + uint8_t getTrailCCFromCompYesAndZeroCC(uint16_t norm16) const { + if(norm16<=minYesNo) { + return 0; // yesYes and Hangul LV have ccc=tccc=0 + } else { + // For Hangul LVT we harmlessly fetch a firstUnit with tccc=0 here. + return (uint8_t)(*getMapping(norm16)>>8); // tccc from yesNo + } + } + uint8_t getPreviousTrailCC(const UChar *start, const UChar *p) const; + uint8_t getPreviousTrailCC(const uint8_t *start, const uint8_t *p) const; // Requires algorithmic-NoNo. UChar32 mapAlgorithmic(UChar32 c, uint16_t norm16) const { - return c+norm16-(minMaybeYes-MAX_DELTA-1); + return c+(norm16>>DELTA_SHIFT)-centerNoNoDelta; + } + UChar32 getAlgorithmicDelta(uint16_t norm16) const { + return (norm16>>DELTA_SHIFT)-centerNoNoDelta; } // Requires minYesNo>OFFSET_SHIFT); } const uint16_t *getCompositionsListForDecompYes(uint16_t norm16) const { - if(norm16==0 || MIN_NORMAL_MAYBE_YES<=norm16) { + if(norm16>OFFSET_SHIFT); + } /** * @param c code point must have compositions * @return compositions list pointer @@ -573,55 +637,78 @@ private: UChar32 minNeedDataCP, ReorderingBuffer *buffer, UErrorCode &errorCode) const; - UBool decomposeShort(const UChar *src, const UChar *limit, - ReorderingBuffer &buffer, UErrorCode &errorCode) const; + const UChar *decomposeShort(const UChar *src, const UChar *limit, + UBool stopAtCompBoundary, UBool onlyContiguous, + ReorderingBuffer &buffer, UErrorCode &errorCode) const; UBool decompose(UChar32 c, uint16_t norm16, ReorderingBuffer &buffer, UErrorCode &errorCode) const; const uint8_t *decomposeShort(const uint8_t *src, const uint8_t *limit, - UBool stopAtCompBoundary, ReorderingBuffer &buffer, - UErrorCode &errorCode) const; + UBool stopAtCompBoundary, UBool onlyContiguous, + ReorderingBuffer &buffer, UErrorCode &errorCode) const; static int32_t combine(const uint16_t *list, UChar32 trail); void addComposites(const uint16_t *list, UnicodeSet &set) const; void recompose(ReorderingBuffer &buffer, int32_t recomposeStartIndex, UBool onlyContiguous) const; - int32_t getCompProps(const uint8_t *src, const uint8_t *limit, - uint16_t norm16, UBool onlyContiguous) const; - - UBool hasCompBoundaryBefore(UChar32 c, uint16_t norm16) const; + UBool hasCompBoundaryBefore(UChar32 c, uint16_t norm16) const { + return creset(); } destLength=stringCaseMapper(caseLocale, options, UCASEMAP_BREAK_ITERATOR diff --git a/icu4c/source/common/unicode/normalizer2.h b/icu4c/source/common/unicode/normalizer2.h index f0d77978804..f71ccb8b839 100644 --- a/icu4c/source/common/unicode/normalizer2.h +++ b/icu4c/source/common/unicode/normalizer2.h @@ -240,7 +240,7 @@ public: * pass the U_SUCCESS() test, or else the function returns * immediately. Check for U_FAILURE() on output or use with * function chaining. (See User Guide for details.) - * @internal ICU 60 technology preview, may be changed or removed in the future + * @draft ICU 60 */ virtual void normalizeUTF8(uint32_t options, StringPiece src, ByteSink &sink, @@ -510,7 +510,35 @@ public: virtual UnicodeString & normalize(const UnicodeString &src, UnicodeString &dest, - UErrorCode &errorCode) const; + UErrorCode &errorCode) const override; + + /** + * Normalizes a UTF-8 string and optionally records how source substrings + * relate to changed and unchanged result substrings. + * + * Currently implemented completely only for "compose" modes, + * such as for NFC, NFKC, and NFKC_Casefold + * (UNORM2_COMPOSE and UNORM2_COMPOSE_CONTIGUOUS). + * Otherwise currently converts to & from UTF-16 and does not support edits. + * + * @param options Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT. + * @param src Source UTF-8 string. + * @param sink A ByteSink to which the normalized UTF-8 result string is written. + * sink.Flush() is called at the end. + * @param edits Records edits for index mapping, working with styled text, + * and getting only changes (if any). + * The Edits contents is undefined if any error occurs. + * This function calls edits->reset() first. edits can be nullptr. + * @param errorCode Standard ICU error code. Its input value must + * pass the U_SUCCESS() test, or else the function returns + * immediately. Check for U_FAILURE() on output or use with + * function chaining. (See User Guide for details.) + * @draft ICU 60 + */ + virtual void + normalizeUTF8(uint32_t options, StringPiece src, ByteSink &sink, + Edits *edits, UErrorCode &errorCode) const override; + /** * Appends the normalized form of the second string to the first string * (merging them at the boundary) and returns the first string. @@ -528,7 +556,7 @@ public: virtual UnicodeString & normalizeSecondAndAppend(UnicodeString &first, const UnicodeString &second, - UErrorCode &errorCode) const; + UErrorCode &errorCode) const override; /** * Appends the second string to the first string * (merging them at the boundary) and returns the first string. @@ -546,7 +574,7 @@ public: virtual UnicodeString & append(UnicodeString &first, const UnicodeString &second, - UErrorCode &errorCode) const; + UErrorCode &errorCode) const override; /** * Gets the decomposition mapping of c. @@ -560,7 +588,7 @@ public: * @stable ICU 4.6 */ virtual UBool - getDecomposition(UChar32 c, UnicodeString &decomposition) const; + getDecomposition(UChar32 c, UnicodeString &decomposition) const override; /** * Gets the raw decomposition mapping of c. @@ -574,7 +602,7 @@ public: * @stable ICU 49 */ virtual UBool - getRawDecomposition(UChar32 c, UnicodeString &decomposition) const; + getRawDecomposition(UChar32 c, UnicodeString &decomposition) const override; /** * Performs pairwise composition of a & b and returns the composite if there is one. @@ -587,7 +615,7 @@ public: * @stable ICU 49 */ virtual UChar32 - composePair(UChar32 a, UChar32 b) const; + composePair(UChar32 a, UChar32 b) const override; /** * Gets the combining class of c. @@ -598,7 +626,7 @@ public: * @stable ICU 49 */ virtual uint8_t - getCombiningClass(UChar32 c) const; + getCombiningClass(UChar32 c) const override; /** * Tests if the string is normalized. @@ -612,7 +640,7 @@ public: * @stable ICU 4.4 */ virtual UBool - isNormalized(const UnicodeString &s, UErrorCode &errorCode) const; + isNormalized(const UnicodeString &s, UErrorCode &errorCode) const override; /** * Tests if the string is normalized. * For details see the Normalizer2 base class documentation. @@ -625,7 +653,7 @@ public: * @stable ICU 4.4 */ virtual UNormalizationCheckResult - quickCheck(const UnicodeString &s, UErrorCode &errorCode) const; + quickCheck(const UnicodeString &s, UErrorCode &errorCode) const override; /** * Returns the end of the normalized substring of the input string. * For details see the Normalizer2 base class documentation. @@ -638,7 +666,7 @@ public: * @stable ICU 4.4 */ virtual int32_t - spanQuickCheckYes(const UnicodeString &s, UErrorCode &errorCode) const; + spanQuickCheckYes(const UnicodeString &s, UErrorCode &errorCode) const override; /** * Tests if the character always has a normalization boundary before it, @@ -648,7 +676,7 @@ public: * @return TRUE if c has a normalization boundary before it * @stable ICU 4.4 */ - virtual UBool hasBoundaryBefore(UChar32 c) const; + virtual UBool hasBoundaryBefore(UChar32 c) const override; /** * Tests if the character always has a normalization boundary after it, @@ -658,7 +686,7 @@ public: * @return TRUE if c has a normalization boundary after it * @stable ICU 4.4 */ - virtual UBool hasBoundaryAfter(UChar32 c) const; + virtual UBool hasBoundaryAfter(UChar32 c) const override; /** * Tests if the character is normalization-inert. @@ -667,7 +695,7 @@ public: * @return TRUE if c is normalization-inert * @stable ICU 4.4 */ - virtual UBool isInert(UChar32 c) const; + virtual UBool isInert(UChar32 c) const override; private: UnicodeString & normalize(const UnicodeString &src, @@ -675,6 +703,12 @@ private: USetSpanCondition spanCondition, UErrorCode &errorCode) const; + void + normalizeUTF8(uint32_t options, const char *src, int32_t length, + ByteSink &sink, Edits *edits, + USetSpanCondition spanCondition, + UErrorCode &errorCode) const; + UnicodeString & normalizeSecondAndAppend(UnicodeString &first, const UnicodeString &second, diff --git a/icu4c/source/common/unicode/stringoptions.h b/icu4c/source/common/unicode/stringoptions.h index 270b9de691c..d8b29fd40d8 100644 --- a/icu4c/source/common/unicode/stringoptions.h +++ b/icu4c/source/common/unicode/stringoptions.h @@ -182,6 +182,7 @@ // ucasemap_imp.h #define U_TITLECASE_ITERATOR_MASK 0xe0 // ucasemap_imp.h #define U_TITLECASE_ADJUSTMENT_MASK 0x600 // ustr_imp.h #define _STRNCMP_STYLE 0x1000 +// ustr_imp.h #define U_EDITS_NO_RESET 0x2000 // unormcmp.cpp #define _COMPARE_EQUIV 0x80000 #endif // __STRINGOPTIONS_H__ diff --git a/icu4c/source/common/ustr_imp.h b/icu4c/source/common/ustr_imp.h index 9815915ff52..3c2d8574f8d 100644 --- a/icu4c/source/common/ustr_imp.h +++ b/icu4c/source/common/ustr_imp.h @@ -25,6 +25,11 @@ */ #define _STRNCMP_STYLE 0x1000 +/** + * Internal option for string transformation functions to not first reset the Edits object. + */ +#define U_EDITS_NO_RESET 0x2000 + /** * Compare two strings in code point order or code unit order. * Works in strcmp style (both lengths -1), diff --git a/icu4c/source/common/ustrcase.cpp b/icu4c/source/common/ustrcase.cpp index 6fffb90a389..bd910cf0dc5 100644 --- a/icu4c/source/common/ustrcase.cpp +++ b/icu4c/source/common/ustrcase.cpp @@ -1103,7 +1103,7 @@ ustrcase_map(int32_t caseLocale, uint32_t options, UCASEMAP_BREAK_ITERATOR_PARAM return 0; } - if(edits!=NULL) { + if (edits != nullptr && (options & U_EDITS_NO_RESET) == 0) { edits->reset(); } destLength=stringCaseMapper(caseLocale, options, UCASEMAP_BREAK_ITERATOR diff --git a/icu4c/source/common/utrie2.cpp b/icu4c/source/common/utrie2.cpp index cec7224d90f..8f9183bafad 100644 --- a/icu4c/source/common/utrie2.cpp +++ b/icu4c/source/common/utrie2.cpp @@ -746,7 +746,7 @@ uint16_t BackwardUTrie2StringIterator::previous16() { codePointLimit=codePointStart; if(start>=codePointStart) { codePoint=U_SENTINEL; - return 0; + return trie->errorValue; } uint16_t result; UTRIE2_U16_PREV16(trie, start, codePointStart, codePoint, result); @@ -757,7 +757,7 @@ uint16_t ForwardUTrie2StringIterator::next16() { codePointStart=codePointLimit; if(codePointLimit==limit) { codePoint=U_SENTINEL; - return 0; + return trie->errorValue; } uint16_t result; UTRIE2_U16_NEXT16(trie, codePointLimit, limit, codePoint, result); diff --git a/icu4c/source/data/in/nfc.nrm b/icu4c/source/data/in/nfc.nrm index 76168750f2347be654d19b08aaec47b2ca8d3be4..d92f277c25df9f5f9f054daf0f81b35be0d328a5 100644 GIT binary patch delta 15522 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 diff --git a/icu4c/source/data/in/nfkc.nrm b/icu4c/source/data/in/nfkc.nrm index c4b7e7228448588f615cff3e7f19b6f7e973b575..1289141ba583b7bcf8c3fa5697e93c6f9b9dce25 100644 GIT binary patch delta 26394 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%0D8#?{7k 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�_N5erNrTbP^W88hEtOa)_t|79tWB9xIF`9UdGs&!2_|jBY=(0j=GSH>ARN zKMnQh@Mt2slSH%|^CL0Uz=BAJhYL{^Q1pOWVKrqCBOM&lpoG%VnC>JIzmr6BryI|p zk(idj+C)MdDy?*+swM|hkJFuGU_2d+>?B7)V~XzvV{Hz;4fv4`ekAa8q66w7(}?aQ z5$(o&E28#+4=2Oip1d(Km5u|096$jgp+i)va-?HH+C~hs@7_p-1nohi@lLdpM0_{q zpT;2^jpFSXe!m=2UP38t6vA!k0fZtMCmBPMnk?yK^>%hJGM=xdBWlV|2Fb7 zz!UbmPcuna6zmT_jfH6%xg!y1$&OH<`W=0-FtOdr-JrQ!CZ-BZ)tG|Zo(_L0nr^S# ziCRs-bP1-rcOngEF#m9;%HFa|1o?%#((R{qwRF>oT&z{>hBS#WpO5)`%=0nN$GiaZ z0?cP(J`?jC%yTfGh50PZ3o$Rmya@63<)3AP?c<**V19<~)&uR?oeOmJ?o^=1c4q?} zz>?h0Ewv<}bW=cUDpf;T4tWKnX>P~@No2Sot5k~0GhA}y2g+0JQ3`qcwa;U1Bq4+d zqE-S&DsrT9hc>yRRk=f6?vNwvs2%bFrBX+#bkq|&@-mm410|?F`MDDh;;zLO2LL{9+`WLFeop$)f%;GMW*Y z`*gOp9CSQs@z232;m^Y<&0m01x_>TCN&h^YGW^9j9p+z((+GbFPTl;aICb}z;gsnw z$7#I30;ep0B~Cs3RXFwZFT<%9*I$hpZ~tg!*DQ$PPoocjA$;WWUW`DHS6 zVQxH}=Hh96rY}QjaGIJ2&&3;n^8ptCz6rPxa53OpfJ*@123!jG4&XAt<>YTbCB!12 zD*;ylz7Mz>a1Ee)0&LunZUOuR5Pmr%J_XzXxC`(zz}Idm8BB2U2O4Auzv zd4>i&yr#fBleE#`eFO05oy&Ss3O{Jj$PJJ}@5v8IseRU>*l6ih^mFKRkV3r4S0II0 zlQSWOSlb5{1>1RxgTh{eJj9or11X$3$^D=e{aSDTb;ZZ9uM+-NfA~QkQxel*n7U!= zjwuUMPfWcq^}*B^Q$I}oF%1AZ3=VNt|E>Onf0sW44tAscJ^jan4Nu_SgFh35jx7v0 z5WmMg7R7xFXWxTE$9LTK9O66NZ$bW^{nDDy@HKFT*$8zG!8u3Cbmk6n7u)q~g*hL> z5#)0yWx%Gs0sbPCg`5=`4IadycKh%0V_W)N0hrh+#tzcIMM=Q0Ryxj=+fRQWg!gHl z>)7f4fYQ@YZ!ff24Yj|6cBmJ-fRkhHF!u!F?bFu9<{}BQv>W_TzyazlIAEdk*LkRW z4qH12C3nC&tVT>!j!GBXv)7mS{|N1nT+T!slCE8!F1dkgd;}Ern96MiO?SATyGgH} zcB^+g3F!$)Q`}^*F4w!Iy13JbvoHKqY(MpBoI6!oZkOzewST@V$TI=jp%=!9Zc_W0 zz0o$gTLSDnFtLc?Ax_u(i*UNZeqmpZefs`2Fx6MgJwf|_0OdtG;Q#;t delta 25559 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 diff --git a/icu4c/source/data/in/nfkc_cf.nrm b/icu4c/source/data/in/nfkc_cf.nrm index 9d91ad32ab40ca5b42b683da21a458e8064b6eb2..c6b1e1a8351d810ca381af56fd0a272a91052a1a 100644 GIT binary patch literal 51928 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

  • M8`HsU?R+d*wcdnbuA0o!zNp19A!KLnqEufW24m^F*o zQ7CeqQt$X_Vq+Op!A?4u2eyD$z-!<%Xv4GJ5sU+y!ErEbqE`7W&ro8X{;OD~!WV-J z7V=j@y0Bld7t02a)1P{wKMY;~bHRPs?whQVf0rIQ&uIGxqp%cQcQdUHF5t0(r*S24 z*ztItu#L6sn1mUv=;J{--;)pV_K;sGF}}vK1dN!<*==tI=|082Q76!D8Y3CJ3@(B7 z_sZjC>i^lj>`>f7ihO%F)LTcKk<;0Q!7>}Z2JEzurL=E}*P=;YUlVWWeXetxw+sKb z+1L9JOaUF(qZ$CFfd{~n8S=V;Udc!6#k^1j@_tOaS1IHODSbsq)l6yQ>D$}9r>M<7 zW|<;JPekRkOu-BrkG_8QN zM|kZh@4PvT6HqsR&n);3cu5U!0ALCD0CfBbZv#JdopP^`7z0dN!M@EPZw>jjxnChK zkz%>G13Ho&AD#o^q!mlMg6Bx@Z$_`9#YTF0#JXWFeF2^Tv100l@9p08#2oqnPk?FN zY319!=Zx;9{Fi@5s|}?7^VkoZ=Q?+I^GWXxZyjM@U~@y#RPTKcvJU}zU>W7rlIqd< zeC~$W_ko`W9C9S&QG6#p#OUEEYJ|HF(~clNtnrg!qo{<`?=<~WqLn8aquR%xX5+x@@^r<^^2(m*a*6UH^Jwi9DD!{f>VoK zXAJ!(I-OP<&+#Vi)eeEp+Cpb($DHMF-i`TydP4dsxtOL!CCB+Z64cFCg~YUbJHqG+eqPes~GWv zv8?8u61)rk2@VZ*ok}m4T#KLQGXNYK!d@$w@`7giL!|PLA(B$bajMsfXLG8zoP6)N zl@wm&6L<~p_MpQWzH|1R)89BD?sul8OmZG>#;y^!rS-c4!FMO8yQK}fGm4}=Z#6-&$C-n_w($Y)crhrBy~Se?ssx#KzVZK z6G?eai2L|=K^sygCUrm0NlD$$b8=Gm^Q=tjex6g3x}Rq?Iq9}&1HB_jZL`g6YL)6v z>M12k*Bo1Or-XKB5u6rm8Jrw^ zH6HTb#|nwXL)uylr!K@<*NWh(`Vc3AD}oocgg6yk5uCq0#Hrwl;QodXr-Cbj?RJGY z8C(&p+a2Oma78e(H$?gs!DWphP6k&5GY*D08C(&pITYe_a7A$U;SeW;D}pVLg*YW# z5gdIY#7W_bV84TB>v%6V-|az%5?vrmTPR_kXtoJ#W7E4QLx^G&S8{vfBYCD~l zkgw#P&fP=^Wl7TwSA}oFPx1j$*~EFb-Eg&_Y?nDRw;Ek%`RX~fc2>FADL&;by`I?r zl4D6(r}K1%Zx`kMv&E98yRy=^l4cVtxk#EM-EiH`>A6Jhd|9dPCUw6A4Y`fE{Hg}F z?bJ2Q=|7e3NN$WXe`+=VRNxW(ef_=M!?{spmHtn79>-I+ZP(IXI*WK5Pw6Vvanh5# zmH&+@Nh#}Wq)s>b?V8Y(>&K*|8@qcb$vQkw5=TAsCQ`(t1Gz_&vQAE(qzpT#Z8S}O zSBbYe_fzv#>E5O#qMSl}j+W8M##4mo=I>?XCM@q;Ooc0SHUGKw5_QwrLiL3-zm}JC z&soog)6QAHN>eZBDe^7SbShCPM$#ntt#}+sv&&`5t@2$4A43&WvTA#oR#g65pvu?R zbTj%&?(RV7qJCrL7+k-v(mfDn&uAn&MhWReQW}($8k5q#q_jUN9ZpK6Nhv!i^-N09 zq*RuadMBkmNr_+ni6n1-{F*lT^r}W~*g%_O^(Pl=kg)X|7#*FVQT(oFb>)Ea0kIZUaBaU9% znv*C&Ruo_(s0W+D7O)lk7Q7BBzyvT6OahZZC71%Hf@$DhFdf_nW`HU%6I6p)U^bWo zYQRr}PTIn>)f|3anD!i38*9Hg`(=2+nd*-oYpkq{O^Q{HY1@(s)o~_vc5mAB?(T2C uJTUuhRQ(k@wU0Z_KhvCReEt8Eu5#X~JX`yJ$uY&Tdi-xudYp3C)c-d+Bl&y) literal 51864 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

    h89rXg@bkOt2Mdd!zYhHj)Z2!7TTt&^ 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 diff --git a/icu4c/source/data/in/uts46.nrm b/icu4c/source/data/in/uts46.nrm index 7270a67b41d09430c64d307e1a10207eb484a4f8..ee765dec403d717c4118aebc1094c6d165d85216 100644 GIT binary patch literal 61068 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 Dm@tXp literal 61060 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 diff --git a/icu4c/source/test/cintltst/cnormtst.c b/icu4c/source/test/cintltst/cnormtst.c index 2ee0cc93eca..18412f71a67 100644 --- a/icu4c/source/test/cintltst/cnormtst.c +++ b/icu4c/source/test/cintltst/cnormtst.c @@ -159,6 +159,7 @@ void addNormTest(TestNode** root) } static const char* const modeStrings[]={ + "?", "UNORM_NONE", "UNORM_NFD", "UNORM_NFKD", @@ -183,7 +184,7 @@ static void TestNormCases(UNormalizationMode mode, length2= unorm_normalize(source, -1, mode, 0, NULL, 0, &status2); if(neededLen!=length2) { log_err("ERROR in unorm_normalize(%s)[%d]: " - "preflight length/NUL %d!=%d preflight length/srcLength\n", + "preflight length/srcLength %d!=%d preflight length/NUL\n", modeStrings[mode], (int)x, (int)neededLen, (int)length2); } if(status==U_BUFFER_OVERFLOW_ERROR) @@ -192,14 +193,14 @@ static void TestNormCases(UNormalizationMode mode, } length2=unorm_normalize(source, u_strlen(source), mode, 0, result, UPRV_LENGTHOF(result), &status); if(U_FAILURE(status) || neededLen!=length2) { - log_data_err("ERROR in unorm_normalize(%s/NUL) at %s: %s - (Are you missing data?)\n", + log_data_err("ERROR in unorm_normalize(%s/srcLength) at %s: %s - (Are you missing data?)\n", modeStrings[mode], austrdup(source), myErrorName(status)); } else { assertEqual(result, cases[x][expIndex], x); } length2=unorm_normalize(source, -1, mode, 0, result, UPRV_LENGTHOF(result), &status); if(U_FAILURE(status) || neededLen!=length2) { - log_data_err("ERROR in unorm_normalize(%s/srcLength) at %s: %s - (Are you missing data?)\n", + log_data_err("ERROR in unorm_normalize(%s/NUL) at %s: %s - (Are you missing data?)\n", modeStrings[mode], austrdup(source), myErrorName(status)); } else { assertEqual(result, cases[x][expIndex], x); diff --git a/icu4c/source/test/intltest/normconf.cpp b/icu4c/source/test/intltest/normconf.cpp index e6619ea58a4..50d4a6fec05 100644 --- a/icu4c/source/test/intltest/normconf.cpp +++ b/icu4c/source/test/intltest/normconf.cpp @@ -406,11 +406,11 @@ UBool NormalizerConformanceTest::checkConformance(const UnicodeString* field, } static const char *const kModeStrings[UNORM_MODE_COUNT] = { - "?", "D", "KD", "C", "KC", "FCD" + "?", "none", "D", "KD", "C", "KC", "FCD" }; static const char *const kMessages[UNORM_MODE_COUNT] = { - "?!=?", "c3!=D(c%d)", "c5!=KC(c%d)", "c2!=C(c%d)", "c4!=KC(c%d)", "FCD" + "?!=?", "?!=?", "c3!=D(c%d)", "c5!=KC(c%d)", "c2!=C(c%d)", "c4!=KC(c%d)", "FCD" }; UBool NormalizerConformanceTest::checkNorm(UNormalizationMode mode, int32_t options, @@ -450,6 +450,7 @@ UBool NormalizerConformanceTest::checkNorm(UNormalizationMode mode, int32_t opti std::string exp8; exp.toUTF8String(exp8); std::string out8; + out8.reserve(exp8.length()); Edits edits; Edits *editsPtr = (mode == UNORM_NFC || mode == UNORM_NFKC) ? &edits : nullptr; StringByteSink sink(&out8); diff --git a/icu4c/source/test/intltest/tstnorm.cpp b/icu4c/source/test/intltest/tstnorm.cpp index db6719434ff..25ebdc19b08 100644 --- a/icu4c/source/test/intltest/tstnorm.cpp +++ b/icu4c/source/test/intltest/tstnorm.cpp @@ -55,6 +55,9 @@ void BasicNormalizerTest::runIndexedTest(int32_t index, UBool exec, #endif TESTCASE_AUTO(TestFilteredNormalizer2Coverage); TESTCASE_AUTO(TestNormalizeUTF8WithEdits); + TESTCASE_AUTO(TestLowMappingToEmpty_D); + TESTCASE_AUTO(TestLowMappingToEmpty_FCD); + TESTCASE_AUTO(TestNormalizeIllFormedText); TESTCASE_AUTO_END; } @@ -1374,6 +1377,10 @@ initExpectedSkippables(UnicodeSet skipSets[UNORM_MODE_COUNT], UErrorCode &errorC delete [] combineBackCharsAndCc; } +static const char *const kModeStrings[UNORM_MODE_COUNT] = { + "?", "none", "D", "KD", "C", "KC", "FCD" +}; + void BasicNormalizerTest::TestSkippable() { UnicodeSet diff, skipSets[UNORM_MODE_COUNT], expectSets[UNORM_MODE_COUNT]; @@ -1395,7 +1402,8 @@ BasicNormalizerTest::TestSkippable() { for(int32_t i=UNORM_NONE; i sink(&result); @@ -1544,9 +1552,10 @@ BasicNormalizerTest::TestNormalizeUTF8WithEdits() { { TRUE, 1, 1 }, // A→a { TRUE, 2, 2 }, // Ä→ä { TRUE, 3, 2 }, // A\u0308→ä - { TRUE, 5, 5 }, // A\u0308\u0323→ạ\u0308 + { TRUE, 7, 5 }, // A\u0308\u00ad\u0323→ạ\u0308 removes the soft hyphen { TRUE, 4, 5 }, // Ä\u0323→ ạ\u0308 { FALSE, 1, 1 }, // comma + { TRUE, 2, 0 }, // U+00AD soft hyphen maps to empty { TRUE, 6, 3 }, // \u1100\u1161→ 가 { TRUE, 6, 3 }, // 가\u11A8→ 각 { TRUE, 6, 3 }, // 가\u3133→ 갃 @@ -1568,6 +1577,138 @@ BasicNormalizerTest::TestNormalizeUTF8WithEdits() { edits.getFineIterator(), edits.getFineIterator(), expectedChanges, UPRV_LENGTHOF(expectedChanges), TRUE, errorCode); + + // With filter: The normalization code does not see the "A" substrings. + UnicodeSet filter(u"[^A]", errorCode); + FilteredNormalizer2 fn2(*nfkc_cf, filter); + expected = u8" AäA\u0308A\u0323\u0308ạ\u0308,가각갃 "; + result.clear(); + edits.reset(); + fn2.normalizeUTF8(0, src, sink, &edits, errorCode); + assertSuccess("filtered normalizeUTF8", errorCode.get()); + assertEquals("filtered normalizeUTF8", expected.c_str(), result.c_str()); + static const EditChange filteredChanges[] = { + { FALSE, 3, 3 }, // 2 spaces + A + { TRUE, 2, 2 }, // Ä→ä + { FALSE, 4, 4 }, // A\u0308A + { TRUE, 6, 4 }, // \u0308\u00ad\u0323→\u0323\u0308 removes the soft hyphen + { TRUE, 4, 5 }, // Ä\u0323→ ạ\u0308 + { FALSE, 1, 1 }, // comma + { TRUE, 2, 0 }, // U+00AD soft hyphen maps to empty + { TRUE, 6, 3 }, // \u1100\u1161→ 가 + { TRUE, 6, 3 }, // 가\u11A8→ 각 + { TRUE, 6, 3 }, // 가\u3133→ 갃 + { FALSE, 2, 2 } // 2 spaces + }; + TestUtility::checkEditsIter(*this, u"filtered normalizeUTF8", + edits.getFineIterator(), edits.getFineIterator(), + filteredChanges, UPRV_LENGTHOF(filteredChanges), + TRUE, errorCode); + + // Omit unchanged text. + // Note that the result is not normalized because the inner normalizer + // does not see text across filter spans. + expected = u8"ä\u0323\u0308ạ\u0308가각갃"; + result.clear(); + edits.reset(); + fn2.normalizeUTF8(U_OMIT_UNCHANGED_TEXT, src, sink, &edits, errorCode); + assertSuccess("filtered normalizeUTF8 omit unchanged", errorCode.get()); + assertEquals("filtered normalizeUTF8 omit unchanged", expected.c_str(), result.c_str()); + TestUtility::checkEditsIter(*this, u"filtered normalizeUTF8 omit unchanged", + edits.getFineIterator(), edits.getFineIterator(), + filteredChanges, UPRV_LENGTHOF(filteredChanges), + TRUE, errorCode); +} + +void +BasicNormalizerTest::TestLowMappingToEmpty_D() { + IcuTestErrorCode errorCode(*this, "TestLowMappingToEmpty_D"); + const Normalizer2 *n2 = Normalizer2::getInstance( + nullptr, "nfkc_cf", UNORM2_DECOMPOSE, errorCode); + if (errorCode.logDataIfFailureAndReset("Normalizer2::getInstance() call failed")) { + return; + } + checkLowMappingToEmpty(*n2); + + UnicodeString sh(u'\u00AD'); + assertFalse("soft hyphen is not normalized", n2->isNormalized(sh, errorCode)); + UnicodeString result = n2->normalize(sh, errorCode); + assertTrue("soft hyphen normalizes to empty", result.isEmpty()); + assertEquals("soft hyphen QC=No", UNORM_NO, n2->quickCheck(sh, errorCode)); + assertEquals("soft hyphen spanQuickCheckYes", 0, n2->spanQuickCheckYes(sh, errorCode)); + + UnicodeString s(u"\u00ADÄ\u00AD\u0323"); + result = n2->normalize(s, errorCode); + assertEquals("normalize string with soft hyphens", u"a\u0323\u0308", result); +} + +void +BasicNormalizerTest::TestLowMappingToEmpty_FCD() { + IcuTestErrorCode errorCode(*this, "TestLowMappingToEmpty_FCD"); + const Normalizer2 *n2 = Normalizer2::getInstance( + nullptr, "nfkc_cf", UNORM2_FCD, errorCode); + if (errorCode.logDataIfFailureAndReset("Normalizer2::getInstance() call failed")) { + return; + } + checkLowMappingToEmpty(*n2); + + UnicodeString sh(u'\u00AD'); + assertTrue("soft hyphen is FCD", n2->isNormalized(sh, errorCode)); + + UnicodeString s(u"\u00ADÄ\u00AD\u0323"); + UnicodeString result = n2->normalize(s, errorCode); + assertEquals("normalize string with soft hyphens", u"\u00ADa\u0323\u0308", result); +} + +void +BasicNormalizerTest::checkLowMappingToEmpty(const Normalizer2 &n2) { + UnicodeString mapping; + assertTrue("getDecomposition(soft hyphen)", n2.getDecomposition(0xad, mapping)); + assertTrue("soft hyphen maps to empty", mapping.isEmpty()); + assertFalse("soft hyphen has no boundary before", n2.hasBoundaryBefore(0xad)); + assertFalse("soft hyphen has no boundary after", n2.hasBoundaryAfter(0xad)); + assertFalse("soft hyphen is not inert", n2.isInert(0xad)); +} + +void +BasicNormalizerTest::TestNormalizeIllFormedText() { + IcuTestErrorCode errorCode(*this, "TestNormalizeIllFormedText"); + const Normalizer2 *nfkc_cf = Normalizer2::getNFKCCasefoldInstance(errorCode); + if(errorCode.logDataIfFailureAndReset("Normalizer2::getNFKCCasefoldInstance() call failed")) { + return; + } + // Normalization behavior for ill-formed text is not defined. + // ICU currently treats ill-formed sequences as normalization-inert + // and copies them unchanged. + UnicodeString src(u" A"); + src.append((char16_t)0xD800).append(u"ÄA\u0308").append((char16_t)0xD900). + append(u"A\u0308\u00ad\u0323").append((char16_t)0xDBFF). + append(u"Ä\u0323,\u00ad").append((char16_t)0xDC00). + append(u"\u1100\u1161가\u11A8가\u3133 ").append((char16_t)0xDFFF); + UnicodeString expected(u" a"); + expected.append((char16_t)0xD800).append(u"ää").append((char16_t)0xD900). + append(u"ạ\u0308").append((char16_t)0xDBFF). + append(u"ạ\u0308,").append((char16_t)0xDC00). + append(u"가각갃 ").append((char16_t)0xDFFF); + UnicodeString result = nfkc_cf->normalize(src, errorCode); + assertSuccess("normalize", errorCode.get()); + assertEquals("normalize", expected, result); + + std::string src8(u8" A"); + src8.append("\x80").append(u8"ÄA\u0308").append("\xC0\x80"). + append(u8"A\u0308\u00ad\u0323").append("\xED\xA0\x80"). + append(u8"Ä\u0323,\u00ad").append("\xF4\x90\x80\x80"). + append(u8"\u1100\u1161가\u11A8가\u3133 ").append("\xF0"); + std::string expected8(u8" a"); + expected8.append("\x80").append(u8"ää").append("\xC0\x80"). + append(u8"ạ\u0308").append("\xED\xA0\x80"). + append(u8"ạ\u0308,").append("\xF4\x90\x80\x80"). + append(u8"가각갃 ").append("\xF0"); + std::string result8; + StringByteSink sink(&result8); + nfkc_cf->normalizeUTF8(0, src8, sink, nullptr, errorCode); + assertSuccess("normalizeUTF8", errorCode.get()); + assertEquals("normalizeUTF8", expected8.c_str(), result8.c_str()); } #endif /* #if !UCONFIG_NO_NORMALIZATION */ diff --git a/icu4c/source/test/intltest/tstnorm.h b/icu4c/source/test/intltest/tstnorm.h index 0153acf4e55..d98aafd7094 100644 --- a/icu4c/source/test/intltest/tstnorm.h +++ b/icu4c/source/test/intltest/tstnorm.h @@ -48,6 +48,9 @@ public: void TestCustomFCC(); void TestFilteredNormalizer2Coverage(); void TestNormalizeUTF8WithEdits(); + void TestLowMappingToEmpty_D(); + void TestLowMappingToEmpty_FCD(); + void TestNormalizeIllFormedText(); private: UnicodeString canonTests[24][3]; @@ -83,6 +86,7 @@ private: static UnicodeString hex(UChar ch); static UnicodeString hex(const UnicodeString& str); + void checkLowMappingToEmpty(const Normalizer2 &n2); }; #endif /* #if !UCONFIG_NO_NORMALIZATION */ diff --git a/icu4c/source/tools/gennorm2/extradata.cpp b/icu4c/source/tools/gennorm2/extradata.cpp index b98889e8611..ae074949d3d 100644 --- a/icu4c/source/tools/gennorm2/extradata.cpp +++ b/icu4c/source/tools/gennorm2/extradata.cpp @@ -26,19 +26,20 @@ U_NAMESPACE_BEGIN ExtraData::ExtraData(Norms &n, UBool fast) : Norms::Enumerator(n), yesYesCompositions(1000, (UChar32)0xffff, 2), // 0=inert, 1=Jamo L, 2=start of compositions - yesNoMappingsAndCompositions(1000, (UChar32)0, 1), // 0=Hangul, 1=start of normal data - optimizeFast(fast) {} + yesNoMappingsAndCompositions(1000, (UChar32)0, 1), // 0=Hangul LV, 1=start of normal data + yesNoMappingsOnly(1000, (UChar32)0, 1), // 0=Hangul LVT, 1=start of normal data + optimizeFast(fast) { + // Hangul LV algorithmically decomposes to two Jamo. + // Some code may harmlessly read this firstUnit. + yesNoMappingsAndCompositions.setCharAt(0, 2); + // Hangul LVT algorithmically decomposes to three Jamo. + // Some code may harmlessly read this firstUnit. + yesNoMappingsOnly.setCharAt(0, 3); +} int32_t ExtraData::writeMapping(UChar32 c, const Norm &norm, UnicodeString &dataString) { UnicodeString &m=*norm.mapping; int32_t length=m.length(); - if(length>Normalizer2Impl::MAPPING_LENGTH_MASK) { - fprintf(stderr, - "gennorm2 error: " - "mapping for U+%04lX longer than maximum of %d\n", - (long)c, Normalizer2Impl::MAPPING_LENGTH_MASK); - exit(U_INVALID_FORMAT_ERROR); - } // Write the mapping & raw mapping extraData. int32_t firstUnit=length|(norm.trailCC<<8); int32_t preMappingLength=0; @@ -81,9 +82,6 @@ int32_t ExtraData::writeMapping(UChar32 c, const Norm &norm, UnicodeString &data ++preMappingLength; firstUnit|=Normalizer2Impl::MAPPING_HAS_CCC_LCCC_WORD; } - if(norm.hasNoCompBoundaryAfter) { - firstUnit|=Normalizer2Impl::MAPPING_NO_COMP_BOUNDARY_AFTER; - } dataString.append((UChar)firstUnit); dataString.append(m); return preMappingLength; @@ -109,6 +107,22 @@ int32_t ExtraData::writeNoNoMapping(UChar32 c, const Norm &norm, return offset; } +UBool ExtraData::setNoNoDelta(UChar32 c, Norm &norm) const { + // Try a compact, algorithmic encoding to a single compYesAndZeroCC code point. + // Do not map from ASCII to non-ASCII. + if(norm.mappingCP>=0 && + !(c<=0x7f && norm.mappingCP>0x7f) && + norms.getNormRef(norm.mappingCP).type=0 && - (!norm.hasNoCompBoundaryAfter || 1!=norm.mapping->countChar32())) { - int32_t delta=norm.mappingCP-c; - if(-Normalizer2Impl::MAX_DELTA<=delta && delta<=Normalizer2Impl::MAX_DELTA) { - norm.type=Norm::NO_NO_DELTA; - norm.offset=delta; - break; - } - } + case Norm::NO_NO_COMP_YES: + if(!optimizeFast && setNoNoDelta(c, norm)) { + break; } - // TODO: minMappingNotCompYes, minMappingNoCompBoundaryBefore - norm.offset=writeNoNoMapping(c, norm, noNoMappings, previousNoNoMappings); + norm.offset=writeNoNoMapping(c, norm, noNoMappingsCompYes, previousNoNoMappingsCompYes); + break; + case Norm::NO_NO_COMP_BOUNDARY_BEFORE: + if(!optimizeFast && setNoNoDelta(c, norm)) { + break; + } + norm.offset=writeNoNoMapping( + c, norm, noNoMappingsCompBoundaryBefore, previousNoNoMappingsCompBoundaryBefore); + break; + case Norm::NO_NO_COMP_NO_MAYBE_CC: + norm.offset=writeNoNoMapping( + c, norm, noNoMappingsCompNoMaybeCC, previousNoNoMappingsCompNoMaybeCC); + break; + case Norm::NO_NO_EMPTY: + // There can be multiple extra data entries for mappings to the empty string + // if they have different raw mappings. + norm.offset=writeNoNoMapping(c, norm, noNoMappingsEmpty, previousNoNoMappingsEmpty); break; case Norm::MAYBE_YES_COMBINES_FWD: norm.offset=maybeYesCompositions.length(); diff --git a/icu4c/source/tools/gennorm2/extradata.h b/icu4c/source/tools/gennorm2/extradata.h index cec9d9a94fb..0a8e73087d5 100644 --- a/icu4c/source/tools/gennorm2/extradata.h +++ b/icu4c/source/tools/gennorm2/extradata.h @@ -36,7 +36,10 @@ public: UnicodeString yesYesCompositions; UnicodeString yesNoMappingsAndCompositions; UnicodeString yesNoMappingsOnly; - UnicodeString noNoMappings; + UnicodeString noNoMappingsCompYes; + UnicodeString noNoMappingsCompBoundaryBefore; + UnicodeString noNoMappingsCompNoMaybeCC; + UnicodeString noNoMappingsEmpty; private: /** @@ -48,12 +51,16 @@ private: int32_t writeMapping(UChar32 c, const Norm &norm, UnicodeString &dataString); int32_t writeNoNoMapping(UChar32 c, const Norm &norm, UnicodeString &dataString, Hashtable &previousMappings); + UBool setNoNoDelta(UChar32 c, Norm &norm) const; /** Requires norm.compositions!=nullptr. */ void writeCompositions(UChar32 c, const Norm &norm, UnicodeString &dataString); void writeExtraData(UChar32 c, Norm &norm); UBool optimizeFast; - Hashtable previousNoNoMappings; // If constructed in runtime code, pass in UErrorCode. + Hashtable previousNoNoMappingsCompYes; // If constructed in runtime code, pass in UErrorCode. + Hashtable previousNoNoMappingsCompBoundaryBefore; + Hashtable previousNoNoMappingsCompNoMaybeCC; + Hashtable previousNoNoMappingsEmpty; }; U_NAMESPACE_END diff --git a/icu4c/source/tools/gennorm2/n2builder.cpp b/icu4c/source/tools/gennorm2/n2builder.cpp index 374e91c4884..9bad2d550e1 100644 --- a/icu4c/source/tools/gennorm2/n2builder.cpp +++ b/icu4c/source/tools/gennorm2/n2builder.cpp @@ -56,8 +56,8 @@ static UDataInfo dataInfo={ 0, { 0x4e, 0x72, 0x6d, 0x32 }, /* dataFormat="Nrm2" */ - { 2, 0, 0, 0 }, /* formatVersion */ - { 5, 2, 0, 0 } /* dataVersion (Unicode version) */ + { 3, 0, 0, 0 }, /* formatVersion */ + { 10, 0, 0, 0 } /* dataVersion (Unicode version) */ }; U_NAMESPACE_BEGIN @@ -65,8 +65,7 @@ U_NAMESPACE_BEGIN class HangulIterator { public: struct Range { - UChar32 start, limit; - uint16_t norm16; + UChar32 start, end; }; HangulIterator() : rangeIndex(0) {} @@ -77,18 +76,17 @@ public: return NULL; } } - void reset() { rangeIndex=0; } private: static const Range ranges[4]; int32_t rangeIndex; }; const HangulIterator::Range HangulIterator::ranges[4]={ - { Hangul::JAMO_L_BASE, Hangul::JAMO_L_BASE+Hangul::JAMO_L_COUNT, 1 }, - { Hangul::JAMO_V_BASE, Hangul::JAMO_V_BASE+Hangul::JAMO_V_COUNT, Normalizer2Impl::JAMO_VT }, + { Hangul::JAMO_L_BASE, Hangul::JAMO_L_END }, + { Hangul::JAMO_V_BASE, Hangul::JAMO_V_END }, // JAMO_T_BASE+1: not U+11A7 - { Hangul::JAMO_T_BASE+1, Hangul::JAMO_T_BASE+Hangul::JAMO_T_COUNT, Normalizer2Impl::JAMO_VT }, - { Hangul::HANGUL_BASE, Hangul::HANGUL_BASE+Hangul::HANGUL_COUNT, 0 }, // will become minYesNo + { Hangul::JAMO_T_BASE+1, Hangul::JAMO_T_END }, + { Hangul::HANGUL_BASE, Hangul::HANGUL_END }, }; Normalizer2DataBuilder::Normalizer2DataBuilder(UErrorCode &errorCode) : @@ -200,58 +198,109 @@ void Normalizer2DataBuilder::setRoundTripMapping(UChar32 c, const UnicodeString } void Normalizer2DataBuilder::removeMapping(UChar32 c) { - Norm *p=checkNormForMapping(norms.getNorm(c), c); - if(p!=NULL) { - p->mappingType=Norm::REMOVED; - } + // createNorm(c), not getNorm(c), to record a non-mapping and detect conflicting data. + Norm *p=checkNormForMapping(norms.createNorm(c), c); + p->mappingType=Norm::REMOVED; } -UBool Normalizer2DataBuilder::hasNoCompBoundaryAfter(const BuilderReorderingBuffer &buffer) { +UBool Normalizer2DataBuilder::mappingHasCompBoundaryAfter(const BuilderReorderingBuffer &buffer) const { if(buffer.isEmpty()) { - return TRUE; // Maps-to-empty-string is no boundary of any kind. + return FALSE; // Maps-to-empty-string is no boundary of any kind. } int32_t lastStarterIndex=buffer.lastStarterIndex(); if(lastStarterIndex<0) { - return TRUE; // no starter + return FALSE; // no starter } UChar32 starter=buffer.charAt(lastStarterIndex); + if(lastStarterIndex==0 && norms.combinesBack(starter)) { + // The last starter is at the beginning of the mapping and combines backward. + return FALSE; + } if(Hangul::isJamoL(starter) || (Hangul::isJamoV(starter) && 0compositions==nullptr) { - return FALSE; // The last starter does not combine forward. + + // Multiple starters can combine into one. + // Look for the first of the last sequence of starters, excluding Jamos. + int32_t i=lastStarterIndex; + UChar32 c; + while(0compositions==nullptr)) { + return TRUE; // The last starter does not combine forward. } - // Compose as far as possible, and see if further compositions are possible. uint8_t prevCC=0; - for(int32_t combMarkIndex=lastStarterIndex+1; combMarkIndexlastStarterIndex && norms.combinesWithCCBetween(*starterNorm, prevCC, cc)) { // The starter combines with a mark that reorders before the current one. - return TRUE; + return FALSE; } - if(prevCCcombine(buffer.charAt(combMarkIndex)))>=0) { - // The starter combines with this mark into a composite replacement starter. + UChar32 c=buffer.charAt(i); + if(starterNorm!=nullptr && (prevCCcombine(c))>=0) { + // The starter combines with c into a composite replacement starter. starterNorm=norms.getNorm(starter); - if(starterNorm==nullptr || starterNorm->compositions==nullptr) { - return FALSE; // The composite does not combine further. + if(i>=lastStarterIndex && + (starterNorm==nullptr || starterNorm->compositions==nullptr)) { + return TRUE; // The composite does not combine further. } // Keep prevCC because we "removed" the combining mark. + } else if(cc==0) { + starterNorm=norms.getNorm(c); + if(i==lastStarterIndex && + (starterNorm==nullptr || starterNorm->compositions==nullptr)) { + return TRUE; // The new starter does not combine forward. + } + prevCC=0; } else { prevCC=cc; } } if(prevCC==0) { - return TRUE; // forward-combining starter at the very end + return FALSE; // forward-combining starter at the very end } if(norms.combinesWithCCBetween(*starterNorm, prevCC, 256)) { // The starter combines with another mark. - return TRUE; + return FALSE; + } + return TRUE; +} + +UBool Normalizer2DataBuilder::mappingRecomposes(const BuilderReorderingBuffer &buffer) const { + if(buffer.lastStarterIndex()<0) { + return FALSE; // no starter + } + const Norm *starterNorm=nullptr; + uint8_t prevCC=0; + for(int32_t i=0; icombine(c)>=0) { + return TRUE; // normal composite + } else if(cc==0) { + if(Hangul::isJamoL(c)) { + if((i+1)length()>Normalizer2Impl::MAPPING_LENGTH_MASK) { + norm.error="mapping longer than maximum of 31"; + return; + } // Ensure canonical order. BuilderReorderingBuffer buffer; if(norm.rawMapping!=nullptr) { @@ -272,20 +325,20 @@ void Normalizer2DataBuilder::postProcess(Norm &norm) { } norms.reorder(*norm.mapping, buffer); if(buffer.isEmpty()) { - norm.leadCC=norm.trailCC=0; + // A character that is deleted (maps to an empty string) must + // get the worst-case lccc and tccc values because arbitrary + // characters on both sides will become adjacent. + norm.leadCC=1; + norm.trailCC=0xff; } else { norm.leadCC=buffer.ccAt(0); norm.trailCC=buffer.ccAt(buffer.length()-1); } - // Set the hasNoCompBoundaryAfter flag for use by the last code branch - // in Normalizer2Impl::hasCompBoundaryAfter(). - // For details see the comments on hasNoCompBoundaryAfter(buffer). - if(norm.compositions!=nullptr) { - norm.hasNoCompBoundaryAfter=TRUE; - } else { - norm.hasNoCompBoundaryAfter=hasNoCompBoundaryAfter(buffer); - } + norm.hasCompBoundaryBefore= + !buffer.isEmpty() && norm.leadCC==0 && !norms.combinesBack(buffer.charAt(0)); + norm.hasCompBoundaryAfter= + norm.compositions==nullptr && mappingHasCompBoundaryAfter(buffer); if(norm.combinesBack) { norm.error="combines-back and decomposes, not possible in Unicode normalization"; @@ -299,13 +352,25 @@ void Normalizer2DataBuilder::postProcess(Norm &norm) { if(norm.compositions!=NULL) { norm.error="combines-forward and has a one-way mapping, " "not possible in Unicode normalization"; + } else if(buffer.isEmpty()) { + norm.type=Norm::NO_NO_EMPTY; + } else if(!norm.hasCompBoundaryBefore) { + norm.type=Norm::NO_NO_COMP_NO_MAYBE_CC; + } else if(mappingRecomposes(buffer)) { + norm.type=Norm::NO_NO_COMP_BOUNDARY_BEFORE; } else { - norm.type=Norm::NO_NO; + // The mapping is comp-normalized. + norm.type=Norm::NO_NO_COMP_YES; } } } else { // no mapping norm.leadCC=norm.trailCC=norm.cc; + norm.hasCompBoundaryBefore= + norm.cc==0 && !norm.combinesBack; + norm.hasCompBoundaryAfter= + norm.cc==0 && !norm.combinesBack && norm.compositions==nullptr; + if(norm.combinesBack) { if(norm.compositions!=nullptr) { // Earlier code checked ccc=0. @@ -339,13 +404,6 @@ void Normalizer2DataBuilder::setSmallFCD(UChar32 c) { } void Normalizer2DataBuilder::writeNorm16(UChar32 start, UChar32 end, Norm &norm) { - if(start=Norm::NO_NO; + UBool isCompNoMaybe= norm.type>=Norm::NO_NO_COMP_YES; if(isCompNoMaybe && startstart; climit; ++c) { - if(utrie2_get32(norm16Trie, c)!=0) { + for(UChar32 c=range->start; c<=range->end; ++c) { + if(utrie2_get32(norm16Trie, c)>Normalizer2Impl::INERT) { fprintf(stderr, "gennorm2 error: " "illegal mapping/composition/ccc data for Hangul or Jamo U+%04lX\n", @@ -419,32 +503,62 @@ void Normalizer2DataBuilder::setHangulData() { } // Set data for algorithmic runtime handling. IcuToolErrorCode errorCode("gennorm2/setHangulData()"); - hi.reset(); - while((range=hi.nextRange())!=NULL) { - uint16_t norm16=range->norm16; - if(norm16==0) { - norm16=(uint16_t)indexes[Normalizer2Impl::IX_MIN_YES_NO]; // Hangul LV/LVT encoded as minYesNo - if(range->startstart; - } - } else { - if(range->startstart; - } - } - utrie2_setRange32(norm16Trie, range->start, range->limit-1, norm16, TRUE, errorCode); - errorCode.assertSuccess(); + + // Jamo V/T are maybeYes + if(Hangul::JAMO_V_BASE*pMaxValue) { - *pMaxValue=value; + Norm16Summary *p=(Norm16Summary *)context; + if(value>p->maxNorm16) { + p->maxNorm16=value; } + p->andedNorm16&=value; return TRUE; } @@ -452,7 +566,7 @@ U_CDECL_END void Normalizer2DataBuilder::processData() { IcuToolErrorCode errorCode("gennorm2/processData()"); - norm16Trie=utrie2_open(0, 0, errorCode); + norm16Trie=utrie2_open(Normalizer2Impl::INERT, Normalizer2Impl::INERT, errorCode); errorCode.assertSuccess(); // Build composition lists before recursive decomposition, @@ -479,26 +593,37 @@ void Normalizer2DataBuilder::processData() { norms.enumRanges(extra); extraData=extra.yesYesCompositions; - indexes[Normalizer2Impl::IX_MIN_YES_NO]=extraData.length(); + indexes[Normalizer2Impl::IX_MIN_YES_NO]=extraData.length()*2; extraData.append(extra.yesNoMappingsAndCompositions); - indexes[Normalizer2Impl::IX_MIN_YES_NO_MAPPINGS_ONLY]=extraData.length(); + indexes[Normalizer2Impl::IX_MIN_YES_NO_MAPPINGS_ONLY]=extraData.length()*2; extraData.append(extra.yesNoMappingsOnly); - // TODO: minMappingNotCompYes, minMappingNoCompBoundaryBefore - indexes[Normalizer2Impl::IX_MIN_NO_NO]=extraData.length(); - extraData.append(extra.noNoMappings); - indexes[Normalizer2Impl::IX_LIMIT_NO_NO]=extraData.length(); + indexes[Normalizer2Impl::IX_MIN_NO_NO]=extraData.length()*2; + extraData.append(extra.noNoMappingsCompYes); + indexes[Normalizer2Impl::IX_MIN_NO_NO_COMP_BOUNDARY_BEFORE]=extraData.length()*2; + extraData.append(extra.noNoMappingsCompBoundaryBefore); + indexes[Normalizer2Impl::IX_MIN_NO_NO_COMP_NO_MAYBE_CC]=extraData.length()*2; + extraData.append(extra.noNoMappingsCompNoMaybeCC); + indexes[Normalizer2Impl::IX_MIN_NO_NO_EMPTY]=extraData.length()*2; + extraData.append(extra.noNoMappingsEmpty); + indexes[Normalizer2Impl::IX_LIMIT_NO_NO]=extraData.length()*2; + // Pad the maybeYesCompositions length to a multiple of 4, + // so that NO_NO_DELTA bits 2..1 can be used without subtracting the center. + while(extra.maybeYesCompositions.length()&3) { + extra.maybeYesCompositions.append((UChar)0); + } extraData.insert(0, extra.maybeYesCompositions); indexes[Normalizer2Impl::IX_MIN_MAYBE_YES]= Normalizer2Impl::MIN_NORMAL_MAYBE_YES- - extra.maybeYesCompositions.length(); + extra.maybeYesCompositions.length()*2; // Pad to even length for 4-byte alignment of following data. if(extraData.length()&1) { extraData.append((UChar)0); } - int32_t minNoNoDelta=getCenterNoNoDelta()-Normalizer2Impl::MAX_DELTA; + int32_t minNoNoDelta=getMinNoNoDelta(); + U_ASSERT((minNoNoDelta&7)==0); if(indexes[Normalizer2Impl::IX_LIMIT_NO_NO]>minNoNoDelta) { fprintf(stderr, "gennorm2 error: " @@ -509,6 +634,7 @@ void Normalizer2DataBuilder::processData() { // writeNorm16() and setHangulData() reduce these as needed. indexes[Normalizer2Impl::IX_MIN_DECOMP_NO_CP]=0x110000; indexes[Normalizer2Impl::IX_MIN_COMP_NO_MAYBE_CP]=0x110000; + indexes[Normalizer2Impl::IX_MIN_LCCC_CP]=0x110000; // Map each code point to its norm16 value, // including the properties that fit directly, @@ -529,17 +655,21 @@ void Normalizer2DataBuilder::processData() { // inner loops if necessary. // However, that seems like overkill for an optimization for supplementary characters. for(UChar lead=0xd800; lead<0xdc00; ++lead) { - uint32_t maxValue=utrie2_get32(norm16Trie, lead); - utrie2_enumForLeadSurrogate(norm16Trie, lead, NULL, enumRangeMaxValue, &maxValue); - if( maxValue>=(uint32_t)indexes[Normalizer2Impl::IX_LIMIT_NO_NO] && - maxValue>(uint32_t)indexes[Normalizer2Impl::IX_MIN_NO_NO] - ) { + uint32_t surrogateCPNorm16=utrie2_get32(norm16Trie, lead); + Norm16Summary summary={ surrogateCPNorm16, surrogateCPNorm16 }; + utrie2_enumForLeadSurrogate(norm16Trie, lead, NULL, enumRangeMaxValue, &summary); + uint32_t norm16=summary.maxNorm16; + if(norm16>=(uint32_t)indexes[Normalizer2Impl::IX_LIMIT_NO_NO] && + norm16>(uint32_t)indexes[Normalizer2Impl::IX_MIN_NO_NO]) { // Set noNo ("worst" value) if it got into "less-bad" maybeYes or ccc!=0. // Otherwise it might end up at something like JAMO_VT which stays in // the inner decomposition quick check loop. - maxValue=(uint32_t)indexes[Normalizer2Impl::IX_LIMIT_NO_NO]-1; + norm16=(uint32_t)indexes[Normalizer2Impl::IX_LIMIT_NO_NO]-1; } - utrie2_set32ForLeadSurrogateCodeUnit(norm16Trie, lead, maxValue, errorCode); + norm16= + (norm16&~Normalizer2Impl::HAS_COMP_BOUNDARY_AFTER)| + (summary.andedNorm16&Normalizer2Impl::HAS_COMP_BOUNDARY_AFTER); + utrie2_set32ForLeadSurrogateCodeUnit(norm16Trie, lead, norm16, errorCode); } // Adjust supplementary minimum code points to break quick check loops at their lead surrogates. @@ -554,6 +684,10 @@ void Normalizer2DataBuilder::processData() { if(minCP>=0x10000) { indexes[Normalizer2Impl::IX_MIN_COMP_NO_MAYBE_CP]=U16_LEAD(minCP); } + minCP=indexes[Normalizer2Impl::IX_MIN_LCCC_CP]; + if(minCP>=0x10000) { + indexes[Normalizer2Impl::IX_MIN_LCCC_CP]=U16_LEAD(minCP); + } utrie2_freeze(norm16Trie, UTRIE2_16_VALUE_BITS, errorCode); norm16TrieLength=utrie2_serialize(norm16Trie, NULL, 0, errorCode); @@ -583,11 +717,15 @@ void Normalizer2DataBuilder::processData() { printf("size of binary data file contents: %5ld bytes\n", (long)totalSize); printf("minDecompNoCodePoint: U+%04lX\n", (long)indexes[Normalizer2Impl::IX_MIN_DECOMP_NO_CP]); printf("minCompNoMaybeCodePoint: U+%04lX\n", (long)indexes[Normalizer2Impl::IX_MIN_COMP_NO_MAYBE_CP]); - printf("minYesNo: 0x%04x\n", (int)indexes[Normalizer2Impl::IX_MIN_YES_NO]); + printf("minLcccCodePoint: U+%04lX\n", (long)indexes[Normalizer2Impl::IX_MIN_LCCC_CP]); + printf("minYesNo: (with compositions) 0x%04x\n", (int)indexes[Normalizer2Impl::IX_MIN_YES_NO]); printf("minYesNoMappingsOnly: 0x%04x\n", (int)indexes[Normalizer2Impl::IX_MIN_YES_NO_MAPPINGS_ONLY]); - // TODO: minMappingNotCompYes, minMappingNoCompBoundaryBefore - printf("minNoNo: 0x%04x\n", (int)indexes[Normalizer2Impl::IX_MIN_NO_NO]); + printf("minNoNo: (comp-normalized) 0x%04x\n", (int)indexes[Normalizer2Impl::IX_MIN_NO_NO]); + printf("minNoNoCompBoundaryBefore: 0x%04x\n", (int)indexes[Normalizer2Impl::IX_MIN_NO_NO_COMP_BOUNDARY_BEFORE]); + printf("minNoNoCompNoMaybeCC: 0x%04x\n", (int)indexes[Normalizer2Impl::IX_MIN_NO_NO_COMP_NO_MAYBE_CC]); + printf("minNoNoEmpty: 0x%04x\n", (int)indexes[Normalizer2Impl::IX_MIN_NO_NO_EMPTY]); printf("limitNoNo: 0x%04x\n", (int)indexes[Normalizer2Impl::IX_LIMIT_NO_NO]); + printf("minNoNoDelta: 0x%04x\n", (int)minNoNoDelta); printf("minMaybeYes: 0x%04x\n", (int)indexes[Normalizer2Impl::IX_MIN_MAYBE_YES]); } diff --git a/icu4c/source/tools/gennorm2/n2builder.h b/icu4c/source/tools/gennorm2/n2builder.h index 1fca0b70571..c1421599dac 100644 --- a/icu4c/source/tools/gennorm2/n2builder.h +++ b/icu4c/source/tools/gennorm2/n2builder.h @@ -73,22 +73,21 @@ private: Norm *checkNormForMapping(Norm *p, UChar32 c); // check for permitted overrides /** - * Computes the MAPPING_NO_COMP_BOUNDARY_AFTER flag for a character's mapping - * (especially for a "YesNo" which has a round-trip mapping). - * This flag is used in Normalizer2Impl::hasCompBoundaryAfter(). - * * A starter character with a mapping does not have a composition boundary after it * if the character itself combines-forward (which is tested by the caller of this function), * or it is deleted (mapped to the empty string), * or its mapping contains no starter, * or the last starter combines-forward. */ - UBool hasNoCompBoundaryAfter(const BuilderReorderingBuffer &buffer); + UBool mappingHasCompBoundaryAfter(const BuilderReorderingBuffer &buffer) const; + /** Returns TRUE if the mapping by itself recomposes, that is, it is not comp-normalized. */ + UBool mappingRecomposes(const BuilderReorderingBuffer &buffer) const; void postProcess(Norm &norm); void setSmallFCD(UChar32 c); - int32_t getCenterNoNoDelta() { - return indexes[Normalizer2Impl::IX_MIN_MAYBE_YES]-Normalizer2Impl::MAX_DELTA-1; + int32_t getMinNoNoDelta() const { + return indexes[Normalizer2Impl::IX_MIN_MAYBE_YES]- + ((2*Normalizer2Impl::MAX_DELTA+1)<Normalizer2Impl::MAPPING_LENGTH_MASK) { - return; // writeMapping() will complain about it and print the code point. - } + U_ASSERT(length<=Normalizer2Impl::MAPPING_LENGTH_MASK); const char16_t *s=mapping.getBuffer(); int32_t i=0; UChar32 c; diff --git a/icu4c/source/tools/gennorm2/norms.h b/icu4c/source/tools/gennorm2/norms.h index 052298ed7ed..d41e9329967 100644 --- a/icu4c/source/tools/gennorm2/norms.h +++ b/icu4c/source/tools/gennorm2/norms.h @@ -89,7 +89,7 @@ struct Norm { UVector32 *compositions; // (trail, composite) pairs uint8_t cc, leadCC, trailCC; UBool combinesBack; - UBool hasNoCompBoundaryAfter; + UBool hasCompBoundaryBefore, hasCompBoundaryAfter; /** * Overall type of normalization properties. @@ -112,9 +112,14 @@ struct Norm { YES_NO_COMBINES_FWD, /** Starter with a round-trip mapping but no compositions. */ YES_NO_MAPPING_ONLY, - // TODO: minMappingNotCompYes, minMappingNoCompBoundaryBefore - /** Has a one-way mapping. */ - NO_NO, + /** Has a one-way mapping which is comp-normalized. */ + NO_NO_COMP_YES, + /** Has a one-way mapping which is not comp-normalized but has a comp boundary before. */ + NO_NO_COMP_BOUNDARY_BEFORE, + /** Has a one-way mapping which does not have a comp boundary before. */ + NO_NO_COMP_NO_MAYBE_CC, + /** Has a one-way mapping to the empty string. */ + NO_NO_EMPTY, /** Has an algorithmic one-way mapping to a single code point. */ NO_NO_DELTA, /** @@ -149,11 +154,15 @@ public: Norm *allocNorm(); /** Returns an existing Norm unit, or nullptr if c has no data. */ Norm *getNorm(UChar32 c); + const Norm *getNorm(UChar32 c) const; /** Returns a Norm unit, creating a new one if necessary. */ Norm *createNorm(UChar32 c); /** Returns an existing Norm unit, or an immutable empty object if c has no data. */ const Norm &getNormRef(UChar32 c) const; uint8_t getCC(UChar32 c) const { return getNormRef(c).cc; } + UBool combinesBack(UChar32 c) const { + return Hangul::isJamoV(c) || Hangul::isJamoT(c) || getNormRef(c).combinesBack; + } void reorder(UnicodeString &mapping, BuilderReorderingBuffer &buffer) const; diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/Norm2AllModes.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/Norm2AllModes.java index a3ac7a3d513..8ae6ca919dd 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/Norm2AllModes.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/Norm2AllModes.java @@ -185,9 +185,9 @@ public final class Norm2AllModes { return impl.isDecompYes(impl.getNorm16(c)) ? 1 : 0; } @Override - public boolean hasBoundaryBefore(int c) { return impl.hasDecompBoundary(c, true); } + public boolean hasBoundaryBefore(int c) { return impl.hasDecompBoundaryBefore(c); } @Override - public boolean hasBoundaryAfter(int c) { return impl.hasDecompBoundary(c, false); } + public boolean hasBoundaryAfter(int c) { return impl.hasDecompBoundaryAfter(c); } @Override public boolean isInert(int c) { return impl.isDecompInert(c); } } @@ -238,11 +238,11 @@ public final class Norm2AllModes { public boolean hasBoundaryBefore(int c) { return impl.hasCompBoundaryBefore(c); } @Override public boolean hasBoundaryAfter(int c) { - return impl.hasCompBoundaryAfter(c, onlyContiguous, false); + return impl.hasCompBoundaryAfter(c, onlyContiguous); } @Override public boolean isInert(int c) { - return impl.hasCompBoundaryAfter(c, onlyContiguous, true); + return impl.isCompInert(c, onlyContiguous); } private final boolean onlyContiguous; diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/Normalizer2Impl.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/Normalizer2Impl.java index e0670b96124..9cb231590b1 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/Normalizer2Impl.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/Normalizer2Impl.java @@ -19,6 +19,12 @@ import com.ibm.icu.text.UnicodeSet; import com.ibm.icu.util.ICUUncheckedIOException; import com.ibm.icu.util.VersionInfo; +/** + * Low-level implementation of the Unicode Normalization Algorithm. + * For the data structure and details see the documentation at the end of + * C++ normalizer2impl.h and in the design doc at + * http://site.icu-project.org/design/normalization/custom + */ public final class Normalizer2Impl { public static final class Hangul { /* Korean Hangul and Jamo constants */ @@ -47,9 +53,9 @@ public final class Normalizer2Impl { public static boolean isHangul(int c) { return HANGUL_BASE<=c && c>DELTA_SHIFT)-MAX_DELTA-1; // Read the normTrie. int offset=inIndexes[IX_NORM_TRIE_OFFSET]; @@ -462,7 +470,7 @@ public final class Normalizer2Impl { int numChars=(nextOffset-offset)/2; if(numChars!=0) { maybeYesCompositions=ICUBinary.getString(bytes, numChars, 0); - extraData=maybeYesCompositions.substring(MIN_NORMAL_MAYBE_YES-minMaybeYes); + extraData=maybeYesCompositions.substring((MIN_NORMAL_MAYBE_YES-minMaybeYes)>>OFFSET_SHIFT); } // smallFCD: new in formatVersion 2 @@ -470,23 +478,6 @@ public final class Normalizer2Impl { smallFCD=new byte[0x100]; bytes.get(smallFCD); - // Build tccc180[]. - // gennorm2 enforces lccc=0 for c>=1) { - if((c&0xff)==0) { - bits=smallFCD[c>>8]; // one byte per 0x100 code points - } - if((bits&1)!=0) { - for(int i=0; i<0x20; ++i, ++c) { - tccc180[c]=getFCD16FromNormData(c)&0xff; - } - } else { - c+=0x20; - } - } - return this; } catch(IOException e) { throw new ICUUncheckedIOException(e); @@ -497,14 +488,9 @@ public final class Normalizer2Impl { } private void enumLcccRange(int start, int end, int norm16, UnicodeSet set) { - if(isAlgorithmicNoNo(norm16)) { - // Range of code points with same-norm16-value algorithmic decompositions. - // They might have different non-zero FCD16 values. - do { - int fcd16=getFCD16(start); - if(fcd16>0xff) { set.add(start); } - } while(++start<=end); - } else { + if (norm16 > MIN_NORMAL_MAYBE_YES && norm16 != JAMO_VT) { + set.add(start, end); + } else if (minNoNoCompNoMaybeCC <= norm16 && norm16 < limitNoNo) { int fcd16=getFCD16(start); if(fcd16>0xff) { set.add(start, end); } } @@ -513,7 +499,7 @@ public final class Normalizer2Impl { private void enumNorm16PropertyStartsRange(int start, int end, int value, UnicodeSet set) { /* add the start code point to the USet */ set.add(start); - if(start!=end && isAlgorithmicNoNo(value)) { + if(start!=end && isAlgorithmicNoNo(value) && (value & DELTA_TCCC_MASK) > DELTA_TCCC_1) { // Range of code points with same-norm16-value algorithmic decompositions. // They might have different non-zero FCD16 values. int prevFCD16=getFCD16(start); @@ -528,7 +514,6 @@ public final class Normalizer2Impl { } public void addLcccChars(UnicodeSet set) { - /* add the start code point of each same-value range of each trie */ Iterator trieIterator=normTrie.iterator(); Trie2.Range range; while(trieIterator.hasNext() && !(range=trieIterator.next()).leadSurrogate) { @@ -572,15 +557,13 @@ public final class Normalizer2Impl { // low-level properties ------------------------------------------------ *** - public Trie2_16 getNormTrie() { return normTrie; } - // Note: Normalizer2Impl.java r30983 (2011-nov-27) // still had getFCDTrie() which built and cached an FCD trie. // That provided faster access to FCD data than getFCD16FromNormData() // but required synchronization and consumed some 10kB of heap memory // in any process that uses FCD (e.g., via collation). - // tccc180[] and smallFCD[] are intended to help with any loss of performance, - // at least for Latin & CJK. + // minDecompNoCP etc. and smallFCD[] are intended to help with any loss of performance, + // at least for ASCII & CJK. /** * Builds the canonical-iterator data for this instance. @@ -597,7 +580,7 @@ public final class Normalizer2Impl { Trie2.Range range; while(trieIterator.hasNext() && !(range=trieIterator.next()).leadSurrogate) { final int norm16=range.value; - if(norm16==0 || (minYesNo<=norm16 && norm16=minMaybeYes) { + if(isMaybeOrNonZeroCC(norm16)) { // not a segment starter if it occurs in a decomposition or has cc!=0 newValue|=CANON_NOT_SEGMENT_STARTER; if(norm16 minYesNo) { // c decomposes, get everything from the variable-length extra data - int firstUnit=extraData.charAt(norm16_2); + int mapping=norm16_2>>OFFSET_SHIFT; + int firstUnit=extraData.charAt(mapping); int length=firstUnit&MAPPING_LENGTH_MASK; if((firstUnit&MAPPING_HAS_CCC_LCCC_WORD)!=0) { - if(c==c2 && (extraData.charAt(norm16_2-1)&0xff)!=0) { + if(c==c2 && (extraData.charAt(mapping-1)&0xff)!=0) { newValue|=CANON_NOT_SEGMENT_STARTER; // original c has cc!=0 } } // Skip empty mappings (no characters in the decomposition). if(length!=0) { - ++norm16_2; // skip over the firstUnit + ++mapping; // skip over the firstUnit // add c to first code point's start set - int limit=norm16_2+length; - c2=extraData.codePointAt(norm16_2); + int limit=mapping+length; + c2=extraData.codePointAt(mapping); addToStartSet(newData, c, c2); // Set CANON_NOT_SEGMENT_STARTER for each remaining code point of a // one-way mapping. A 2-way mapping is possible here after // intermediate algorithmic mapping. if(norm16_2>=minNoNo) { - while((norm16_2+=Character.charCount(c2))=MIN_NORMAL_MAYBE_YES) { - return norm16&0xff; + return getCCFromNormalYesOrMaybe(norm16); } if(norm16> OFFSET_SHIFT) & 0xff; + } public static int getCCFromYesOrMaybe(int norm16) { - return norm16>=MIN_NORMAL_MAYBE_YES ? norm16&0xff : 0; + return norm16>=MIN_NORMAL_MAYBE_YES ? getCCFromNormalYesOrMaybe(norm16) : 0; + } + public int getCCFromYesOrMaybeCP(int c) { + if (c < minCompNoMaybeCP) { return 0; } + return getCCFromYesOrMaybe(getNorm16(c)); } /** @@ -703,17 +698,13 @@ public final class Normalizer2Impl { * @return The lccc(c) in bits 15..8 and tccc(c) in bits 7..0. */ public int getFCD16(int c) { - if(c<0) { + if(c=MIN_NORMAL_MAYBE_YES) { + int norm16=getNorm16(c); + if (norm16 >= limitNoNo) { + if(norm16>=MIN_NORMAL_MAYBE_YES) { // combining mark - norm16&=0xff; + norm16=getCCFromNormalYesOrMaybe(norm16); return norm16|(norm16<<8); } else if(norm16>=minMaybeYes) { return 0; - } else if(isDecompNoAlgorithmic(norm16)) { - c=mapAlgorithmic(c, norm16); - } else { - // c decomposes, get everything from the variable-length extra data - int firstUnit=extraData.charAt(norm16); - if((firstUnit&MAPPING_LENGTH_MASK)==0) { - // A character that is deleted (maps to an empty string) must - // get the worst-case lccc and tccc values because arbitrary - // characters on both sides will become adjacent. - return 0x1ff; - } else { - int fcd16=firstUnit>>8; // tccc - if((firstUnit&MAPPING_HAS_CCC_LCCC_WORD)!=0) { - fcd16|=extraData.charAt(norm16-1)&0xff00; // lccc - } - return fcd16; + } else { // isDecompNoAlgorithmic(norm16) + int deltaTrailCC = norm16 & DELTA_TCCC_MASK; + if (deltaTrailCC <= DELTA_TCCC_1) { + return deltaTrailCC >> OFFSET_SHIFT; } + // Maps to an isCompYesAndZeroCC. + c=mapAlgorithmic(c, norm16); + norm16=getNorm16(c); } } + if(norm16<=minYesNo || isHangulLVT(norm16)) { + // no decomposition or Hangul syllable, all zeros + return 0; + } + // c decomposes, get everything from the variable-length extra data + int mapping=norm16>>OFFSET_SHIFT; + int firstUnit=extraData.charAt(mapping); + int fcd16=firstUnit>>8; // tccc + if((firstUnit&MAPPING_HAS_CCC_LCCC_WORD)!=0) { + fcd16|=extraData.charAt(mapping-1)&0xff00; // lccc + } + return fcd16; } /** @@ -763,30 +753,34 @@ public final class Normalizer2Impl { * @return c's decomposition, if it has one; returns null if it does not have a decomposition */ public String getDecomposition(int c) { - int decomp=-1; int norm16; - for(;;) { - if(c>OFFSET_SHIFT; + int length=extraData.charAt(mapping++)&MAPPING_LENGTH_MASK; + return extraData.substring(mapping, mapping+length); } /** @@ -795,40 +789,38 @@ public final class Normalizer2Impl { * @return c's raw decomposition, if it has one; returns null if it does not have a decomposition */ public String getRawDecomposition(int c) { - // We do not loop in this method because an algorithmic mapping itself - // becomes a final result rather than having to be decomposed recursively. int norm16; if(c>7)&1)-1; - char rm0=extraData.charAt(rawMapping); - if(rm0<=MAPPING_LENGTH_MASK) { - return extraData.substring(rawMapping-rm0, rawMapping); - } else { - // Copy the normal mapping and replace its first two code units with rm0. - StringBuilder buffer=new StringBuilder(mLength-1).append(rm0); - norm16+=1+2; // skip over the firstUnit and the first two mapping code units - return buffer.append(extraData, norm16, norm16+mLength-2).toString(); - } + } + // c decomposes, get everything from the variable-length extra data + int mapping=norm16>>OFFSET_SHIFT; + int firstUnit=extraData.charAt(mapping); + int mLength=firstUnit&MAPPING_LENGTH_MASK; // length of normal mapping + if((firstUnit&MAPPING_HAS_RAW_MAPPING)!=0) { + // Read the raw mapping from before the firstUnit and before the optional ccc/lccc word. + // Bit 7=MAPPING_HAS_CCC_LCCC_WORD + int rawMapping=mapping-((firstUnit>>7)&1)-1; + char rm0=extraData.charAt(rawMapping); + if(rm0<=MAPPING_LENGTH_MASK) { + return extraData.substring(rawMapping-rm0, rawMapping); } else { - norm16+=1; // skip over the firstUnit - return extraData.substring(norm16, norm16+mLength); + // Copy the normal mapping and replace its first two code units with rm0. + StringBuilder buffer=new StringBuilder(mLength-1).append(rm0); + mapping+=1+2; // skip over the firstUnit and the first two mapping code units + return buffer.append(extraData, mapping, mapping+mLength-2).toString(); } + } else { + mapping+=1; // skip over the firstUnit + return extraData.substring(mapping, mapping+mLength); } } @@ -876,12 +868,25 @@ public final class Normalizer2Impl { return true; } - public static final int MIN_CCC_LCCC_CP=0x300; + // Fixed norm16 values. + public static final int MIN_YES_YES_WITH_CC=0xfe02; + public static final int JAMO_VT=0xfe00; + public static final int MIN_NORMAL_MAYBE_YES=0xfc00; + public static final int JAMO_L=2; // offset=1 hasCompBoundaryAfter=FALSE + public static final int INERT=1; // offset=0 hasCompBoundaryAfter=TRUE + + // norm16 bit 0 is comp-boundary-after. + public static final int HAS_COMP_BOUNDARY_AFTER=1; + public static final int OFFSET_SHIFT=1; + + // For algorithmic one-way mappings, norm16 bits 2..1 indicate the + // tccc (0, 1, >1) for quick FCC boundary-after tests. + public static final int DELTA_TCCC_0=0; + public static final int DELTA_TCCC_1=2; + public static final int DELTA_TCCC_GT_1=4; + public static final int DELTA_TCCC_MASK=6; + public static final int DELTA_SHIFT=3; - public static final int MIN_YES_YES_WITH_CC=0xff01; - public static final int JAMO_VT=0xff00; - public static final int MIN_NORMAL_MAYBE_YES=0xfe00; - public static final int JAMO_L=1; public static final int MAX_DELTA=0x40; // Byte offsets from the start of the data, after the generic header. @@ -898,18 +903,26 @@ public final class Normalizer2Impl { // Norm16 value thresholds for quick check combinations and types of extra data. // Mappings & compositions in [minYesNo..minYesNoMappingsOnly[. public static final int IX_MIN_YES_NO=10; + // Mappings are comp-normalized. public static final int IX_MIN_NO_NO=11; public static final int IX_LIMIT_NO_NO=12; public static final int IX_MIN_MAYBE_YES=13; // Mappings only in [minYesNoMappingsOnly..minNoNo[. public static final int IX_MIN_YES_NO_MAPPINGS_ONLY=14; + // Mappings are not comp-normalized but have a comp boundary before. + public static final int IX_MIN_NO_NO_COMP_BOUNDARY_BEFORE=15; + // Mappings do not have a comp boundary before. + public static final int IX_MIN_NO_NO_COMP_NO_MAYBE_CC=16; + // Mappings to the empty string. + public static final int IX_MIN_NO_NO_EMPTY=17; - public static final int IX_COUNT=16; + public static final int IX_MIN_LCCC_CP=18; + public static final int IX_COUNT=20; public static final int MAPPING_HAS_CCC_LCCC_WORD=0x80; public static final int MAPPING_HAS_RAW_MAPPING=0x40; - public static final int MAPPING_NO_COMP_BOUNDARY_AFTER=0x20; + // unused bit 0x20; public static final int MAPPING_LENGTH_MASK=0x1f; public static final int COMP_1_LAST_TUPLE=0x8000; @@ -1044,6 +1057,7 @@ public final class Normalizer2Impl { buffer.append(s, 0, src, firstCC, prevCC); buffer.append(s, src, limit); } + // Very similar to composeQuickCheck(): Make the same changes in both places if relevant. // doCompose: normalize // !doCompose: isNormalized (buffer must be empty and initialized) @@ -1051,241 +1065,240 @@ public final class Normalizer2Impl { boolean onlyContiguous, boolean doCompose, ReorderingBuffer buffer) { + int prevBoundary=src; int minNoMaybeCP=minCompNoMaybeCP; - /* - * prevBoundary points to the last character before the current one - * that has a composition boundary before it with ccc==0 and quick check "yes". - * Keeping track of prevBoundary saves us looking for a composition boundary - * when we find a "no" or "maybe". - * - * When we back out from prevSrc back to prevBoundary, - * then we also remove those same characters (which had been simply copied - * or canonically-order-inserted) from the ReorderingBuffer. - * Therefore, at all times, the [prevBoundary..prevSrc[ source units - * must correspond 1:1 to destination units at the end of the destination buffer. - */ - int prevBoundary=src; - int prevSrc; - int c=0; - int norm16=0; - - // only for isNormalized - int prevCC=0; - - for(;;) { - // count code units below the minimum or with irrelevant data for the quick check - for(prevSrc=src; src!=limit;) { + for (;;) { + // Fast path: Scan over a sequence of characters below the minimum "no or maybe" code point, + // or with (compYes && ccc==0) properties. + int prevSrc; + int c = 0; + int norm16 = 0; + for (;;) { + if (src == limit) { + if (prevBoundary != limit && doCompose) { + buffer.append(s, prevBoundary, limit); + } + return true; + } if( (c=s.charAt(src))=minNoNo. + // The current character is either a "noNo" (has a mapping) + // or a "maybeYes" (combines backward) + // or a "yesYes" with ccc!=0. + // It is not a Hangul syllable or Jamo L because those have "yes" properties. - src+=Character.charCount(c); - /* - * isCompYesAndZeroCC(norm16) is false, that is, norm16>=minNoNo. - * c is either a "noNo" (has a mapping) or a "maybeYes" (combines backward) - * or has ccc!=0. - * Check for Jamo V/T, then for regular characters. - * c is not a Hangul syllable or Jamo L because those have "yes" properties. - */ - if(isJamoVT(norm16) && prevBoundary!=prevSrc) { + // Medium-fast path: Handle cases that do not require full decomposition and recomposition. + if (!isMaybeOrNonZeroCC(norm16)) { // minNoNo <= norm16 < minMaybeYes + if (!doCompose) { + return false; + } + // Fast path for mapping a character that is immediately surrounded by boundaries. + // In this case, we need not decompose around the current character. + if (isDecompNoAlgorithmic(norm16)) { + // Maps to a single isCompYesAndZeroCC character + // which also implies hasCompBoundaryBefore. + if (norm16HasCompBoundaryAfter(norm16, onlyContiguous) || + hasCompBoundaryBefore(s, src, limit)) { + if (prevBoundary != prevSrc) { + buffer.append(s, prevBoundary, prevSrc); + } + buffer.append(mapAlgorithmic(c, norm16), 0); + prevBoundary = src; + continue; + } + } else if (norm16 < minNoNoCompBoundaryBefore) { + // The mapping is comp-normalized which also implies hasCompBoundaryBefore. + if (norm16HasCompBoundaryAfter(norm16, onlyContiguous) || + hasCompBoundaryBefore(s, src, limit)) { + if (prevBoundary != prevSrc) { + buffer.append(s, prevBoundary, prevSrc); + } + int mapping = norm16 >> OFFSET_SHIFT; + int length = extraData.charAt(mapping++) & MAPPING_LENGTH_MASK; + buffer.append(extraData, mapping, mapping + length); + prevBoundary = src; + continue; + } + } else if (norm16 >= minNoNoEmpty) { + // The current character maps to nothing. + // Simply omit it from the output if there is a boundary before _or_ after it. + // The character itself implies no boundaries. + if (hasCompBoundaryBefore(s, src, limit) || + hasCompBoundaryAfter(s, prevBoundary, prevSrc, onlyContiguous)) { + if (prevBoundary != prevSrc) { + buffer.append(s, prevBoundary, prevSrc); + } + prevBoundary = src; + continue; + } + } + // Other "noNo" type, or need to examine more text around this character: + // Fall through to the slow path. + } else if (isJamoVT(norm16) && prevBoundary != prevSrc) { char prev=s.charAt(prevSrc-1); - boolean needToDecompose=false; if(c= 0) { + int syllable = Hangul.HANGUL_BASE + + (l*Hangul.JAMO_V_COUNT + (c-Hangul.JAMO_V_BASE)) * + Hangul.JAMO_T_COUNT + t; + --prevSrc; // Replace the Jamo L as well. + if (prevBoundary != prevSrc) { + buffer.append(s, prevBoundary, prevSrc); + } + buffer.append((char)syllable); + prevBoundary = src; continue; } // If we see L+V+x where x!=T then we drop to the slow path, // decompose and recompose. // This is to deal with NFKC finding normal L and V but a - // compatibility variant of a T. We need to either fully compose that - // combination here (which would complicate the code and may not work - // with strange custom data) or use the slow path -- or else our replacing - // two input characters (L+V) with one output character (LV syllable) - // would violate the invariant that [prevBoundary..prevSrc[ has the same - // length as what we appended to the buffer since prevBoundary. - needToDecompose=true; + // compatibility variant of a T. + // We need to either fully compose that combination here + // (which would complicate the code and may not work with strange custom data) + // or use the slow path. } - } else if(Hangul.isHangulWithoutJamoT(prev)) { - // c is a Jamo Trailing consonant, + } else if (Hangul.isHangulLV(prev)) { + // The current character is a Jamo Trailing consonant, // compose with previous Hangul LV that does not contain a Jamo T. - if(!doCompose) { + if (!doCompose) { return false; } - buffer.setLastChar((char)(prev+c-Hangul.JAMO_T_BASE)); - prevBoundary=src; - continue; - } - if(!needToDecompose) { - // The Jamo V/T did not compose into a Hangul syllable. - if(doCompose) { - buffer.append((char)c); - } else { - prevCC=0; + int syllable = prev + c - Hangul.JAMO_T_BASE; + --prevSrc; // Replace the Hangul LV as well. + if (prevBoundary != prevSrc) { + buffer.append(s, prevBoundary, prevSrc); } + buffer.append((char)syllable); + prevBoundary = src; continue; } - } - /* - * Source buffer pointers: - * - * all done quick check current char not yet - * "yes" but (c) processed - * may combine - * forward - * [-------------[-------------[-------------[-------------[ - * | | | | | - * orig. src prevBoundary prevSrc src limit - * - * - * Destination buffer pointers inside the ReorderingBuffer: - * - * all done might take not filled yet - * characters for - * reordering - * [-------------[-------------[-------------[ - * | | | | - * start reorderStart limit | - * +remainingCap.+ - */ - if(norm16>=MIN_YES_YES_WITH_CC) { - int cc=norm16&0xff; // cc!=0 - if( onlyContiguous && // FCC - (doCompose ? buffer.getLastCC() : prevCC)==0 && - prevBoundarycc - ) { + // No matching context, or may need to decompose surrounding text first: + // Fall through to the slow path. + } else if (norm16 > JAMO_VT) { // norm16 >= MIN_YES_YES_WITH_CC + // One or more combining marks that do not combine-back: + // Check for canonical order, copy unchanged if ok and + // if followed by a character with a boundary-before. + int cc = getCCFromNormalYesOrMaybe(norm16); // cc!=0 + if (onlyContiguous /* FCC */ && getPreviousTrailCC(s, prevBoundary, prevSrc) > cc) { // Fails FCD test, need to decompose and contiguously recompose. - if(!doCompose) { + if (!doCompose) { return false; } - } else if(doCompose) { - buffer.append(c, cc); - continue; - } else if(prevCC<=cc) { - prevCC=cc; - continue; } else { - return false; + // If !onlyContiguous (not FCC), then we ignore the tccc of + // the previous character which passed the quick check "yes && ccc==0" test. + int n16; + for (;;) { + if (src == limit) { + if (doCompose) { + buffer.append(s, prevBoundary, limit); + } + return true; + } + int prevCC = cc; + c = Character.codePointAt(s, src); + n16 = normTrie.get(c); + if (n16 >= MIN_YES_YES_WITH_CC) { + cc = getCCFromNormalYesOrMaybe(n16); + if (prevCC > cc) { + if (!doCompose) { + return false; + } + break; + } + } else { + break; + } + src += Character.charCount(c); + } + // p is after the last in-order combining mark. + // If there is a boundary here, then we continue with no change. + if (norm16HasCompBoundaryBefore(n16)) { + if (isCompYesAndZeroCC(n16)) { + src += Character.charCount(c); + } + continue; + } + // Use the slow path. There is no boundary in [prevSrc, src[. } - } else if(!doCompose && !isMaybeOrNonZeroCC(norm16)) { - return false; } - /* - * Find appropriate boundaries around this character, - * decompose the source text from between the boundaries, - * and recompose it. - * - * We may need to remove the last few characters from the ReorderingBuffer - * to account for source text that was copied or appended - * but needs to take part in the recomposition. - */ - - /* - * Find the last composition boundary in [prevBoundary..src[. - * It is either the decomposition of the current character (at prevSrc), - * or prevBoundary. - */ - if(hasCompBoundaryBefore(c, norm16)) { - prevBoundary=prevSrc; - } else if(doCompose) { - buffer.removeSuffix(prevSrc-prevBoundary); + // Slow path: Find the nearest boundaries around the current character, + // decompose and recompose. + if (prevBoundary != prevSrc && !norm16HasCompBoundaryBefore(norm16)) { + c = Character.codePointBefore(s, prevSrc); + norm16 = normTrie.get(c); + if (!norm16HasCompBoundaryAfter(norm16, onlyContiguous)) { + prevSrc -= Character.charCount(c); + } + } + if (doCompose && prevBoundary != prevSrc) { + buffer.append(s, prevBoundary, prevSrc); } - - // Find the next composition boundary in [src..limit[ - - // modifies src to point to the next starter. - src=findNextCompBoundary(s, src, limit); - - // Decompose [prevBoundary..src[ into the buffer and then recompose that part of it. int recomposeStartIndex=buffer.length(); - decomposeShort(s, prevBoundary, src, buffer); + // We know there is not a boundary here. + decomposeShort(s, prevSrc, src, false /* !stopAtCompBoundary */, onlyContiguous, + buffer); + // Decompose until the next boundary. + src = decomposeShort(s, src, limit, true /* stopAtCompBoundary */, onlyContiguous, + buffer); recompose(buffer, recomposeStartIndex, onlyContiguous); if(!doCompose) { - if(!buffer.equals(s, prevBoundary, src)) { + if(!buffer.equals(s, prevSrc, src)) { return false; } buffer.remove(); - prevCC=0; } - - // Move to the next starter. We never need to look back before this point again. prevBoundary=src; } - return true; } + /** * Very similar to compose(): Make the same changes in both places if relevant. * doSpan: spanQuickCheckYes (ignore bit 0 of the return value) @@ -1297,21 +1310,16 @@ public final class Normalizer2Impl { public int composeQuickCheck(CharSequence s, int src, int limit, boolean onlyContiguous, boolean doSpan) { int qcResult=0; + int prevBoundary=src; int minNoMaybeCP=minCompNoMaybeCP; - /* - * prevBoundary points to the last character before the current one - * that has a composition boundary before it with ccc==0 and quick check "yes". - */ - int prevBoundary=src; - int prevSrc; - int c=0; - int norm16=0; - int prevCC=0; - for(;;) { - // count code units below the minimum or with irrelevant data for the quick check - for(prevSrc=src;;) { + // Fast path: Scan over a sequence of characters below the minimum "no or maybe" code point, + // or with (compYes && ccc==0) properties. + int prevSrc; + int c = 0; + int norm16 = 0; + for (;;) { if(src==limit) { return (src<<1)|qcResult; // "yes" or "maybe" } @@ -1319,72 +1327,88 @@ public final class Normalizer2Impl { isCompYesAndZeroCC(norm16=normTrie.getFromU16SingleLead((char)c)) ) { ++src; - } else if(!UTF16.isSurrogate((char)c)) { - break; } else { - char c2; - if(UTF16Plus.isSurrogateLead(c)) { - if((src+1)!=limit && Character.isLowSurrogate(c2=s.charAt(src+1))) { - c=Character.toCodePoint((char)c, c2); - } - } else /* trail surrogate */ { - if(prevSrc=minNoNo. + // The current character is either a "noNo" (has a mapping) + // or a "maybeYes" (combines backward) + // or a "yesYes" with ccc!=0. + // It is not a Hangul syllable or Jamo L because those have "yes" properties. + + int prevNorm16 = INERT; + if (prevBoundary != prevSrc) { + prevBoundary = prevSrc; + if (!norm16HasCompBoundaryBefore(norm16)) { + c = Character.codePointBefore(s, prevSrc); + int n16 = getNorm16(c); + if (!norm16HasCompBoundaryAfter(n16, onlyContiguous)) { + prevBoundary -= Character.charCount(c); + prevNorm16 = n16; + } } - prevCC=0; - // The start of the current character (c). - prevSrc=src; } - src+=Character.charCount(c); - /* - * isCompYesAndZeroCC(norm16) is false, that is, norm16>=minNoNo. - * c is either a "noNo" (has a mapping) or a "maybeYes" (combines backward) - * or has ccc!=0. - */ if(isMaybeOrNonZeroCC(norm16)) { int cc=getCCFromYesOrMaybe(norm16); - if( onlyContiguous && // FCC - cc!=0 && - prevCC==0 && - prevBoundarycc - ) { - // Fails FCD test. - } else if(prevCC<=cc || cc==0) { - prevCC=cc; - if(norm16 cc) { + // The [prevBoundary..prevSrc[ character + // passed the quick check "yes && ccc==0" test + // but is out of canonical order with the current combining mark. + } else { + // If !onlyContiguous (not FCC), then we ignore the tccc of + // the previous character which passed the quick check "yes && ccc==0" test. + for (;;) { + if (norm16 < MIN_YES_YES_WITH_CC) { + if (!doSpan) { + qcResult = 1; + } else { + return prevBoundary << 1; // spanYes does not care to know it's "maybe" + } } + if (src == limit) { + return (src<<1) | qcResult; // "yes" or "maybe" + } + int prevCC = cc; + c = Character.codePointAt(s, src); + norm16 = getNorm16(c); + if (isMaybeOrNonZeroCC(norm16)) { + cc = getCCFromYesOrMaybe(norm16); + if (!(prevCC <= cc || cc == 0)) { + break; + } + } else { + break; + } + src += Character.charCount(c); + } + // src is after the last in-order combining mark. + if (isCompYesAndZeroCC(norm16)) { + prevBoundary = src; + src += Character.charCount(c); + continue; } - continue; } } return prevBoundary<<1; // "no" @@ -1396,10 +1420,10 @@ public final class Normalizer2Impl { ReorderingBuffer buffer) { int src=0, limit=s.length(); if(!buffer.isEmpty()) { - int firstStarterInSrc=findNextCompBoundary(s, 0, limit); + int firstStarterInSrc=findNextCompBoundary(s, 0, limit, onlyContiguous); if(0!=firstStarterInSrc) { int lastStarterInDest=findPreviousCompBoundary(buffer.getStringBuilder(), - buffer.length()); + buffer.length(), onlyContiguous); StringBuilder middle=new StringBuilder((buffer.length()-lastStarterInDest)+ firstStarterInSrc+16); middle.append(buffer.getStringBuilder(), lastStarterInDest, buffer.length()); @@ -1436,7 +1460,7 @@ public final class Normalizer2Impl { for(;;) { // count code units with lccc==0 for(prevSrc=src; src!=limit;) { - if((c=s.charAt(src))1) { - --prevBoundary; + if(prev1) { + --prevBoundary; + } } } else { int p=src-1; @@ -1539,7 +1567,7 @@ public final class Normalizer2Impl { * The source text does not fulfill the conditions for FCD. * Decompose and reorder a limited piece of the text. */ - decomposeShort(s, prevBoundary, src, buffer); + decomposeShort(s, prevBoundary, src, false, false, buffer); prevBoundary=src; prevFCD16=0; } @@ -1569,93 +1597,87 @@ public final class Normalizer2Impl { } } - // Note: hasDecompBoundary() could be implemented as aliases to - // hasFCDBoundaryBefore() and hasFCDBoundaryAfter() - // at the cost of building the FCD trie for a decomposition normalizer. - public boolean hasDecompBoundary(int c, boolean before) { - for(;;) { - if(cMIN_NORMAL_MAYBE_YES) { - return false; // ccc!=0 - } else if(isDecompNoAlgorithmic(norm16)) { - c=mapAlgorithmic(c, norm16); - } else { - // c decomposes, get everything from the variable-length extra data - int firstUnit=extraData.charAt(norm16); - if((firstUnit&MAPPING_LENGTH_MASK)==0) { - return false; - } - if(!before) { - // decomp after-boundary: same as hasFCDBoundaryAfter(), - // fcd16<=1 || trailCC==0 - if(firstUnit>0x1ff) { - return false; // trailCC>1 - } - if(firstUnit<=0xff) { - return true; // trailCC==0 - } - // if(trailCC==1) test leadCC==0, same as checking for before-boundary - } - // true if leadCC==0 (hasFCDBoundaryBefore()) - return (firstUnit&MAPPING_HAS_CCC_LCCC_WORD)==0 || (extraData.charAt(norm16-1)&0xff00)==0; - } + public boolean hasDecompBoundaryBefore(int c) { + return c < minLcccCP || (c <= 0xffff && !singleLeadMightHaveNonZeroFCD16(c)) || + norm16HasDecompBoundaryBefore(getNorm16(c)); + } + public boolean norm16HasDecompBoundaryBefore(int norm16) { + if (norm16 < minNoNoCompNoMaybeCC) { + return true; } + if (norm16 >= limitNoNo) { + return norm16 <= MIN_NORMAL_MAYBE_YES || norm16 == JAMO_VT; + } + // c decomposes, get everything from the variable-length extra data + int mapping=norm16>>OFFSET_SHIFT; + int firstUnit=extraData.charAt(mapping); + // true if leadCC==0 (hasFCDBoundaryBefore()) + return (firstUnit&MAPPING_HAS_CCC_LCCC_WORD)==0 || (extraData.charAt(mapping-1)&0xff00)==0; + } + public boolean hasDecompBoundaryAfter(int c) { + if (c < minDecompNoCP) { + return true; + } + if (c <= 0xffff && !singleLeadMightHaveNonZeroFCD16(c)) { + return true; + } + return norm16HasDecompBoundaryAfter(getNorm16(c)); + } + public boolean norm16HasDecompBoundaryAfter(int norm16) { + if(norm16 <= minYesNo || isHangulLVT(norm16)) { + return true; + } + if (norm16 >= limitNoNo) { + if (isMaybeOrNonZeroCC(norm16)) { + return norm16 <= MIN_NORMAL_MAYBE_YES || norm16 == JAMO_VT; + } + // Maps to an isCompYesAndZeroCC. + return (norm16 & DELTA_TCCC_MASK) <= DELTA_TCCC_1; + } + // c decomposes, get everything from the variable-length extra data + int mapping=norm16>>OFFSET_SHIFT; + int firstUnit=extraData.charAt(mapping); + // decomp after-boundary: same as hasFCDBoundaryAfter(), + // fcd16<=1 || trailCC==0 + if(firstUnit>0x1ff) { + return false; // trailCC>1 + } + if(firstUnit<=0xff) { + return true; // trailCC==0 + } + // if(trailCC==1) test leadCC==0, same as checking for before-boundary + // true if leadCC==0 (hasFCDBoundaryBefore()) + return (firstUnit&MAPPING_HAS_CCC_LCCC_WORD)==0 || (extraData.charAt(mapping-1)&0xff00)==0; } public boolean isDecompInert(int c) { return isDecompYesAndZeroCC(getNorm16(c)); } public boolean hasCompBoundaryBefore(int c) { - return c= (testInert ? minNoNo : minMaybeYes)) { - return false; - } else if(isDecompNoAlgorithmic(norm16)) { - c=mapAlgorithmic(c, norm16); - } else { - // c decomposes, get everything from the variable-length extra data. - // If testInert, then c must be a yesNo character which has lccc=0, - // otherwise it could be a noNo. - int firstUnit=extraData.charAt(norm16); - // true if - // not MAPPING_NO_COMP_BOUNDARY_AFTER - // (which is set if - // c is not deleted, and - // it and its decomposition do not combine forward, and it has a starter) - // and if FCC then trailCC<=1 - return - (firstUnit&MAPPING_NO_COMP_BOUNDARY_AFTER)==0 && - (!onlyContiguous || firstUnit<=0x1ff); - } - } + public boolean hasCompBoundaryAfter(int c, boolean onlyContiguous) { + return norm16HasCompBoundaryAfter(getNorm16(c), onlyContiguous); + } + public boolean isCompInert(int c, boolean onlyContiguous) { + int norm16=getNorm16(c); + return isCompYesAndZeroCC(norm16) && + (norm16 & HAS_COMP_BOUNDARY_AFTER) != 0 && + (!onlyContiguous || isInert(norm16) || extraData.charAt(norm16>>OFFSET_SHIFT) <= 0x1ff); } - public boolean hasFCDBoundaryBefore(int c) { return c=minMaybeYes; } - private static boolean isInert(int norm16) { return norm16==0; } - private static boolean isJamoL(int norm16) { return norm16==1; } + private static boolean isInert(int norm16) { return norm16==INERT; } + private static boolean isJamoL(int norm16) { return norm16==JAMO_L; } private static boolean isJamoVT(int norm16) { return norm16==JAMO_VT; } - private boolean isHangul(int norm16) { return norm16==minYesNo; } + private int hangulLVT() { return minYesNoMappingsOnly|HAS_COMP_BOUNDARY_AFTER; } + private boolean isHangulLV(int norm16) { return norm16==minYesNo; } + private boolean isHangulLVT(int norm16) { + return norm16==hangulLVT(); + } private boolean isCompYesAndZeroCC(int norm16) { return norm16=MIN_YES_YES_WITH_CC || norm16=MIN_YES_YES_WITH_CC ? (uint8_t)norm16 : 0; + // return norm16>=MIN_YES_YES_WITH_CC ? getCCFromNormalYesOrMaybe(norm16) : 0; // } private int getCCFromNoNo(int norm16) { - if((extraData.charAt(norm16)&MAPPING_HAS_CCC_LCCC_WORD)!=0) { - return extraData.charAt(norm16-1)&0xff; + int mapping=norm16>>OFFSET_SHIFT; + if((extraData.charAt(mapping)&MAPPING_HAS_CCC_LCCC_WORD)!=0) { + return extraData.charAt(mapping-1)&0xff; } else { return 0; } } - // requires that the [cpStart..cpLimit[ character passes isCompYesAndZeroCC() - int getTrailCCFromCompYesAndZeroCC(CharSequence s, int cpStart, int cpLimit) { - int c; - if(cpStart==(cpLimit-1)) { - c=s.charAt(cpStart); + int getTrailCCFromCompYesAndZeroCC(int norm16) { + if(norm16<=minYesNo) { + return 0; // yesYes and Hangul LV have ccc=tccc=0 } else { - c=Character.codePointAt(s, cpStart); - } - int prevNorm16=getNorm16(c); - if(prevNorm16<=minYesNo) { - return 0; // yesYes and Hangul LV/LVT have ccc=tccc=0 - } else { - return extraData.charAt(prevNorm16)>>8; // tccc from yesNo + // For Hangul LVT we harmlessly fetch a firstUnit with tccc=0 here. + return extraData.charAt(norm16>>OFFSET_SHIFT)>>8; // tccc from yesNo } } // Requires algorithmic-NoNo. private int mapAlgorithmic(int c, int norm16) { - return c+norm16-(minMaybeYes-MAX_DELTA-1); + return c+(norm16>>DELTA_SHIFT)-centerNoNoDelta; } // Requires minYesNo>OFFSET_SHIFT); } /** * @return index into maybeYesCompositions, or -1 */ private int getCompositionsListForDecompYes(int norm16) { - if(norm16==0 || MIN_NORMAL_MAYBE_YES<=norm16) { + if(norm16>OFFSET_SHIFT; } } /** * @return index into maybeYesCompositions */ private int getCompositionsListForComposite(int norm16) { - // composite has both mapping & compositions list - int firstUnit=extraData.charAt(norm16); - return (MIN_NORMAL_MAYBE_YES-minMaybeYes)+norm16+ // mapping in maybeYesCompositions - 1+ // +1 to skip the first unit with the mapping lenth + // A composite has both mapping & compositions list. + int list=((MIN_NORMAL_MAYBE_YES-minMaybeYes)+norm16)>>OFFSET_SHIFT; + int firstUnit=maybeYesCompositions.charAt(list); + return list+ // mapping in maybeYesCompositions + 1+ // +1 to skip the first unit with the mapping length (firstUnit&MAPPING_LENGTH_MASK); // + mapping length } + private int getCompositionsListForMaybe(int norm16) { + // minMaybeYes<=norm16>OFFSET_SHIFT; + } /** * @param c code point must have compositions * @return index into maybeYesCompositions @@ -1758,44 +1779,58 @@ public final class Normalizer2Impl { // is unlikely to be amortized. // Called by the compose() and makeFCD() implementations. // Public in Java for collation implementation code. - public void decomposeShort(CharSequence s, int src, int limit, - ReorderingBuffer buffer) { + private int decomposeShort( + CharSequence s, int src, int limit, + boolean stopAtCompBoundary, boolean onlyContiguous, + ReorderingBuffer buffer) { while(src>8; - if((firstUnit&MAPPING_HAS_CCC_LCCC_WORD)!=0) { - leadCC=extraData.charAt(norm16-1)>>8; - } else { - leadCC=0; - } - ++norm16; // skip over the firstUnit - buffer.append(extraData, norm16, norm16+length, leadCC, trailCC); + if (stopAtCompBoundary && c < minCompNoMaybeCP) { + return src; } - return; + int norm16 = getNorm16(c); + if (stopAtCompBoundary && norm16HasCompBoundaryBefore(norm16)) { + return src; + } + src+=Character.charCount(c); + decompose(c, norm16, buffer); + if (stopAtCompBoundary && norm16HasCompBoundaryAfter(norm16, onlyContiguous)) { + return src; + } + } + return src; + } + private void decompose(int c, int norm16, ReorderingBuffer buffer) { + // get the decomposition and the lead and trail cc's + if (norm16 >= limitNoNo) { + if (isMaybeOrNonZeroCC(norm16)) { + buffer.append(c, getCCFromYesOrMaybe(norm16)); + return; + } + // Maps to an isCompYesAndZeroCC. + c=mapAlgorithmic(c, norm16); + norm16=getNorm16(c); + } + if (norm16 < minYesNo) { + // c does not decompose + buffer.append(c, 0); + } else if(isHangulLV(norm16) || isHangulLVT(norm16)) { + // Hangul syllable: decompose algorithmically + Hangul.decompose(c, buffer); + } else { + // c decomposes, get everything from the variable-length extra data + int mapping=norm16>>OFFSET_SHIFT; + int firstUnit=extraData.charAt(mapping); + int length=firstUnit&MAPPING_LENGTH_MASK; + int leadCC, trailCC; + trailCC=firstUnit>>8; + if((firstUnit&MAPPING_HAS_CCC_LCCC_WORD)!=0) { + leadCC=extraData.charAt(mapping-1)>>8; + } else { + leadCC=0; + } + ++mapping; // skip over the firstUnit + buffer.append(extraData, mapping, mapping+length, leadCC, trailCC); } } @@ -2052,6 +2087,7 @@ public final class Normalizer2Impl { if(isInert(norm16)) { return -1; } else if(norm16>OFFSET_SHIFT; if(norm16>minYesNo) { // composite 'a' has both mapping & compositions list list+= // mapping pointer - 1+ // +1 to skip the first unit with the mapping lenth - (extraData.charAt(list)&MAPPING_LENGTH_MASK); // + mapping length + 1+ // +1 to skip the first unit with the mapping length + (maybeYesCompositions.charAt(list)&MAPPING_LENGTH_MASK); // + mapping length } - // Turn the offset-into-extraData into an offset-into-maybeYesCompositions. - list+=MIN_NORMAL_MAYBE_YES-minMaybeYes; } } else if(norm16> OFFSET_SHIFT) <= 0x1ff); + } + + private int findPreviousCompBoundary(CharSequence s, int p, boolean onlyContiguous) { while(p>0) { int c=Character.codePointBefore(s, p); - p-=Character.charCount(c); - if(hasCompBoundaryBefore(c)) { + int norm16 = getNorm16(c); + if (norm16HasCompBoundaryAfter(norm16, onlyContiguous)) { + break; + } + p-=Character.charCount(c); + if(hasCompBoundaryBefore(c, norm16)) { break; } - // We could also test hasCompBoundaryAfter() and return iter.codePointLimit, - // but that's probably not worth the extra cost. } return p; } - private int findNextCompBoundary(CharSequence s, int p, int limit) { + private int findNextCompBoundary(CharSequence s, int p, int limit, boolean onlyContiguous) { while(p0) { int c=Character.codePointBefore(s, p); + int norm16; + if (c < minDecompNoCP || norm16HasDecompBoundaryAfter(norm16 = getNorm16(c))) { + break; + } p-=Character.charCount(c); - if(c canonStartSets; diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/Normalizer2.java b/icu4j/main/classes/core/src/com/ibm/icu/text/Normalizer2.java index e2e40de4df4..be113062cb6 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/text/Normalizer2.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/text/Normalizer2.java @@ -223,8 +223,10 @@ public abstract class Normalizer2 { if(spanLength==src.length()) { return (String)src; } - StringBuilder sb=new StringBuilder(src.length()).append(src, 0, spanLength); - return normalizeSecondAndAppend(sb, src.subSequence(spanLength, src.length())).toString(); + if (spanLength != 0) { + StringBuilder sb=new StringBuilder(src.length()).append(src, 0, spanLength); + return normalizeSecondAndAppend(sb, src.subSequence(spanLength, src.length())).toString(); + } } return normalize(src, new StringBuilder(src.length())).toString(); } diff --git a/icu4j/main/shared/data/icudata.jar b/icu4j/main/shared/data/icudata.jar index f95484640df..9f756def957 100755 --- a/icu4j/main/shared/data/icudata.jar +++ b/icu4j/main/shared/data/icudata.jar @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a9b7099447b42325988ae448908ba0e690cf9c8259667c49019cc15d3a0fb760 -size 12224152 +oid sha256:d4b1866a85ceb079d912a3283e5ec6a7d6988df8c0e56e98fd67def82c35dcf3 +size 12225515 diff --git a/icu4j/main/shared/data/testdata.jar b/icu4j/main/shared/data/testdata.jar index 7530a122feb..b328d872ff9 100755 --- a/icu4j/main/shared/data/testdata.jar +++ b/icu4j/main/shared/data/testdata.jar @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a7bc00733ee580f117cfecc6c1790df5c495dea56dddd2472f6253c4baafd664 -size 812715 +oid sha256:fd856769e94b963fb8a0b63148c63349198ef0c0ec3729173170ccbfd94c4999 +size 812769 diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/normalizer/BasicTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/normalizer/BasicTest.java index d88f3caa346..f146ba959fb 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/normalizer/BasicTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/normalizer/BasicTest.java @@ -183,8 +183,8 @@ public class BasicTest extends TestFmwk { @Test public void TestCanonCompose() throws Exception{ Normalizer norm = new Normalizer("", Normalizer.NFC,0); - iterateTest(norm, canonTests, 2); staticTest(Normalizer.NFC, canonTests, 2); + iterateTest(norm, canonTests, 2); composeTest(Normalizer.NFC, canonTests, 2); } @@ -2412,6 +2412,10 @@ public class BasicTest extends TestFmwk { return skipSets; } + private static String[] kModeStrings = { + "D", "C", "KD", "KC" + }; + @Test public void TestSkippable() { UnicodeSet[] skipSets = new UnicodeSet[] { @@ -2440,7 +2444,8 @@ public class BasicTest extends TestFmwk { } for(int i=0; i1){ if(Normalizer.compare(UTF16.charAt(s1,0),s2,Normalizer.COMPARE_IGNORE_CASE)!=0){ errln("Normalizer.compare(int,String) failed for s1: " +Utility.hex(s1) + " s2: " + Utility.hex(s2)); - } + } } if(s1.length()>1 && s2.length()>1){ // TODO: Re-enable this tests after UTC fixes UAX 21 if(Normalizer.compare(s1.toCharArray(),s2.toCharArray(),Normalizer.COMPARE_IGNORE_CASE)!=0){ errln("Normalizer.compare(char[],char[]) failed for s1: " +Utility.hex(s1) + " s2: " + Utility.hex(s2)); - } - } + } + } } private void cross(String s1, String s2,Normalizer.Mode mode){ String result = Normalizer.normalize(s1,mode); if(!result.equals(s2)){ - errln("cross test failed s1: " + Utility.hex(s1) + " s2: " + errln("cross test failed s1: " + Utility.hex(s1) + " s2: " +Utility.hex(s2)); } } @@ -389,7 +379,7 @@ public class ConformanceTest extends TestFmwk { } return buf.toString(); } - + /** * Do a normalization using the iterative API in the given direction. * @param str a Java StringCharacterIterator @@ -421,18 +411,19 @@ public class ConformanceTest extends TestFmwk { /** * @param op name of normalization form, e.g., "KC" + * @param op2 name of test case variant, e.g., "(-1)" * @param s string being normalized * @param got value received * @param exp expected value * @param msg description of this test * @returns true if got == exp */ - private boolean assertEqual(String op, String s, String got, + private boolean assertEqual(String op, String op2, String s, String got, String exp, String msg) { if (exp.equals(got)) { return true; } - errln((" " + msg + ") " + op + "(" + s + ")=" + hex(got) + + errln((" " + msg + ": " + op + op2 + '(' + s + ")=" + hex(got) + ", exp. " + hex(exp))); return false; } @@ -459,7 +450,7 @@ public class ConformanceTest extends TestFmwk { } // Our field is from pos..delim-1. buf.setLength(0); - + String toHex = s.substring(pos,delim); pos = delim; int index = 0; @@ -478,7 +469,7 @@ public class ConformanceTest extends TestFmwk { index = spacePos+1; } } - + if (buf.length() < 1) { throw new IllegalArgumentException("Empty field " + i + " in " + s); } @@ -492,13 +483,13 @@ public class ConformanceTest extends TestFmwk { throw new IllegalArgumentException("Out of range hex " + hex + " in " + s); }else if (hex > 0xFFFF){ - buf.append((char)((hex>>10)+0xd7c0)); + buf.append((char)((hex>>10)+0xd7c0)); buf.append((char)((hex&0x3ff)|0xdc00)); }else{ buf.append((char) hex); } } - + // Specific tests for debugging. These are generally failures // taken from the conformance file, but culled out to make // debugging easier. These can be eliminated without affecting @@ -516,6 +507,6 @@ public class ConformanceTest extends TestFmwk { hexsplit(line, ';', fields, buf); checkConformance(fields, line,options); } - + }