diff --git a/bindings/consts.go b/bindings/consts.go index 534e59cad..616128715 100644 --- a/bindings/consts.go +++ b/bindings/consts.go @@ -2,7 +2,7 @@ package bindings const CInt32Max = int(^uint32(0) >> 1) -const ReindexerVersion = "v4.17.2" +const ReindexerVersion = "v4.18.0" // public go consts from type_consts.h and reindexer_ctypes.h const ( diff --git a/changelog.md b/changelog.md index 9b507e5a7..5fc443b84 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,20 @@ +# Version 4.18.0 (31.10.2024) *beta* +## Replication +- [fix] Fixed possible origin LSN missmatch in snapshots during WAL/Force syncs + +## Reindexer server +- [fix] Fixed logical operations (`or`, `not`) parsining in JSON DSL joined queries + +## Ported +- [fea/fix] Ported all the fixes and features from [v3.29.0](https://github.com/Restream/reindexer/releases/tag/v3.25.0), [v3.26.0](https://github.com/Restream/reindexer/releases/tag/v3.29.0) + +## Face +- [fea] Added disabled mode for selectors on NS config page +- [fix] Fixed `shard_id` filter on the Items table after the Item editing +- [fix] Fixed scroll position on NS menu +- [fix] Fixed the issue related to NS config changes saving on tabs switching +- [fix] Fixed duplicated requests on Indexes and Items pages + # Version 4.17.2 *beta* (19.09.2024) ## Core - [fix] Fixed data race in cached comparators (`joins cache` may cause incorrect comparators deletion) diff --git a/cjson/creflect.go b/cjson/creflect.go index 925f17a6c..db4976319 100644 --- a/cjson/creflect.go +++ b/cjson/creflect.go @@ -85,7 +85,7 @@ type payloadIface struct { func (pl *payloadIface) ptr(field, idx, typ int) unsafe.Pointer { if pl.p == 0 { - panic(fmt.Errorf("Null pointer derefernce")) + panic(fmt.Errorf("Null pointer dereference")) } f := &pl.t.Fields[field] @@ -98,7 +98,7 @@ func (pl *payloadIface) ptr(field, idx, typ int) unsafe.Pointer { if !f.IsArray { if idx != 0 { - panic(fmt.Errorf("Trying to acces by index '%d' to non array field '%s'", idx, f.Name)) + panic(fmt.Errorf("Trying to access by index '%d' to non array field '%s'", idx, f.Name)) } return p } @@ -217,7 +217,7 @@ func (pl *payloadIface) getArrayLen(field int) int { return int((*ArrayHeader)(p).len) } -// get c reflect value and set to go reflect valie +// get c reflect value and set to go reflect value func (pl *payloadIface) getValue(field int, idx int, v reflect.Value) { k := v.Type().Kind() diff --git a/cpp_src/CMakeLists.txt b/cpp_src/CMakeLists.txt index 1e111cebf..debe61d28 100644 --- a/cpp_src/CMakeLists.txt +++ b/cpp_src/CMakeLists.txt @@ -45,7 +45,7 @@ else() option(LINK_RESOURCES "Link web resources as binary data" ON) endif() -set (REINDEXER_VERSION_DEFAULT "4.17.2") +set (REINDEXER_VERSION_DEFAULT "4.18.0") if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "RelWithDebInfo") @@ -88,7 +88,7 @@ endif() if(MSVC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -wd4244 -wd4267 -wd4996 -wd4717 -MP -MD") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -wd4244 -wd4267 -wd4996 -wd4717 -wd4800 -wd4396 -wd4503 -MP -MD") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -wd4244 -wd4267 -wd4996 -wd4717 -wd4800 -wd4396 -wd4503 -MP -MD /bigobj") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -SAFESEH:NO") else() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror -Wswitch-enum") @@ -629,8 +629,3 @@ add_custom_target(collect_coverage COMMAND genhtml coverage_filtered.info -o coverage_output COMMENT "Collecting Reindexer coverage" ) - -# Configure compile options extra -if(MSVC) - target_compile_options(${TARGET} PRIVATE /bigobj) -endif() diff --git a/cpp_src/client/cororeindexer.h b/cpp_src/client/cororeindexer.h index d7ef3796f..3bd911a28 100644 --- a/cpp_src/client/cororeindexer.h +++ b/cpp_src/client/cororeindexer.h @@ -36,7 +36,7 @@ class CoroReindexer { using ConnectionStateHandlerT = std::function; /// Create Reindexer database object - CoroReindexer(const ReindexerConfig& = ReindexerConfig()); + explicit CoroReindexer(const ReindexerConfig& = ReindexerConfig()); /// Destroy Reindexer database object ~CoroReindexer(); CoroReindexer(const CoroReindexer&) = delete; @@ -264,6 +264,7 @@ class CoroReindexer { typedef CoroQueryResults QueryResultsT; typedef Item ItemT; typedef ReindexerConfig ConfigT; + typedef CoroTransaction TransactionT; private: CoroReindexer(RPCClient* impl, InternalRdxContext&& ctx) : impl_(impl), ctx_(std::move(ctx)) {} diff --git a/cpp_src/client/corotransaction.cc b/cpp_src/client/corotransaction.cc index b68fb948d..1afc514db 100644 --- a/cpp_src/client/corotransaction.cc +++ b/cpp_src/client/corotransaction.cc @@ -8,8 +8,7 @@ #include "core/keyvalue/p_string.h" #include "net/cproto/coroclientconnection.h" -namespace reindexer { -namespace client { +namespace reindexer::client { CoroTransaction::~CoroTransaction() { if (!IsFree()) { @@ -226,5 +225,4 @@ CoroTransaction::Impl::Impl(CoroTransaction::Impl&&) noexcept = default; CoroTransaction::Impl& CoroTransaction::Impl::operator=(CoroTransaction::Impl&&) noexcept = default; CoroTransaction::Impl::~Impl() = default; -} // namespace client -} // namespace reindexer +} // namespace reindexer::client diff --git a/cpp_src/client/corotransaction.h b/cpp_src/client/corotransaction.h index 4d0d7dca7..08c35782d 100644 --- a/cpp_src/client/corotransaction.h +++ b/cpp_src/client/corotransaction.h @@ -7,11 +7,9 @@ namespace reindexer { -namespace net { -namespace cproto { +namespace net::cproto { class CoroClientConnection; -} // namespace cproto -} // namespace net +} // namespace net::cproto namespace client { @@ -58,7 +56,7 @@ class CoroTransaction { friend class RPCClient; friend class ReindexerImpl; friend class Transaction; - CoroTransaction(Error status) noexcept : i_(std::move(status)) {} + explicit CoroTransaction(Error status) noexcept : i_(std::move(status)) {} CoroTransaction(RPCClient* rpcClient, int64_t txId, std::chrono::milliseconds requestTimeout, std::chrono::milliseconds execTimeout, Namespace* ns) noexcept : i_(rpcClient, txId, requestTimeout, execTimeout, ns) {} @@ -82,13 +80,13 @@ class CoroTransaction { Impl& operator=(Impl&&) noexcept; ~Impl(); - int64_t txId_ = -1; - RPCClient* rpcClient_ = nullptr; - std::chrono::milliseconds requestTimeout_ = std::chrono::milliseconds{0}; - std::chrono::milliseconds execTimeout_ = std::chrono::milliseconds{0}; + int64_t txId_{-1}; + RPCClient* rpcClient_{nullptr}; + std::chrono::milliseconds requestTimeout_{0}; + std::chrono::milliseconds execTimeout_{0}; Error status_; std::unique_ptr localTm_; - Namespace* ns_ = nullptr; + Namespace* ns_{nullptr}; steady_clock_w::time_point sessionTs_; }; @@ -96,4 +94,5 @@ class CoroTransaction { }; } // namespace client + } // namespace reindexer diff --git a/cpp_src/client/rpcclient.cc b/cpp_src/client/rpcclient.cc index d16bbec56..27cf5fdaf 100644 --- a/cpp_src/client/rpcclient.cc +++ b/cpp_src/client/rpcclient.cc @@ -227,7 +227,6 @@ Error RPCClient::modifyItemCJSON(std::string_view nsName, Item& item, CoroQueryR // Add new names missing in JSON from tm newItem.impl_->addTagNamesFrom(item.impl_->tagsMatcher()); } - item = std::move(newItem); } } diff --git a/cpp_src/cluster/replication/replicationthread.cc b/cpp_src/cluster/replication/replicationthread.cc index aab032dd1..846c922ba 100644 --- a/cpp_src/cluster/replication/replicationthread.cc +++ b/cpp_src/cluster/replication/replicationthread.cc @@ -416,7 +416,7 @@ Error ReplThread::nodeReplicationImpl(Node& node) { const NamespaceName nsName(ns.name); err = syncNamespace(node, nsName, replState); if (!err.ok()) { - logWarn("%d:%d Namespace sync error: %s", serverId_, node.uid, err.what()); + logWarn("%d:%d:%s Namespace sync error: %s", serverId_, node.uid, nsName, err.what()); if (err.code() == errNotFound) { err = Error(); logWarn("%d:%d Expecting drop namespace record for '%s'", serverId_, node.uid, nsName); @@ -424,7 +424,7 @@ Error ReplThread::nodeReplicationImpl(Node& node) { replState = ReplicationStateV2(); err = syncNamespace(node, nsName, replState); if (!err.ok()) { - logWarn("%d:%d Namespace sync error (resync due to datahash missmatch): %s", serverId_, node.uid, + logWarn("%d:%d:%s Namespace sync error (resync due to datahash missmatch): %s", serverId_, node.uid, nsName, err.what()); } } @@ -437,7 +437,7 @@ Error ReplThread::nodeReplicationImpl(Node& node) { } if (integralError.ok()) { - integralError = Error(errTimeout, "%d:%d Unable to sync namespace", serverId_, node.uid); + integralError = Error(errTimeout, "%d:%d:%s Unable to sync namespace", serverId_, node.uid, ns.name); return; } }); @@ -594,12 +594,12 @@ Error ReplThread::syncNamespace(Node& node, const NamespaceName return err; } if (snapshot.HasRawData()) { - logInfo("%d:%d:%s Snapshot has raw data, creating tmp namespace", serverId_, node.uid, nsName); + logInfo("%d:%d:%s Snapshot has RAW data, creating tmp namespace (performing FORCE sync)", serverId_, node.uid, nsName); createTmpNamespace = true; } else if (snapshot.NsVersion().Server() != requiredLsn.NsVersion().Server() || snapshot.NsVersion().Counter() != requiredLsn.NsVersion().Counter()) { - logInfo("%d:%d:%s Snapshot has different ns version (%d vs %d), creating tmp namespace", serverId_, node.uid, nsName, - snapshot.NsVersion(), requiredLsn.NsVersion()); + logInfo("%d:%d:%s Snapshot has different ns version (%d vs %d), creating tmp namespace (performing FORCE sync)", serverId_, + node.uid, nsName, snapshot.NsVersion(), requiredLsn.NsVersion()); createTmpNamespace = true; } diff --git a/cpp_src/cluster/replication/roleswitcher.cc b/cpp_src/cluster/replication/roleswitcher.cc index e23c698d7..cf225c707 100644 --- a/cpp_src/cluster/replication/roleswitcher.cc +++ b/cpp_src/cluster/replication/roleswitcher.cc @@ -31,7 +31,7 @@ void RoleSwitcher::Run(std::vector&& dsns, RoleSwitcher::Config&& c nodes_.reserve(dsns.size()); for (auto&& dsn : dsns) { - nodes_.emplace_back(Node{std::move(dsn), {clientCfg}}); + nodes_.emplace_back(Node{std::move(dsn), client::CoroReindexer{clientCfg}}); } assert(cfg_.onRoleSwitchDone); diff --git a/cpp_src/cmd/reindexer_tool/commandsexecutor.cc b/cpp_src/cmd/reindexer_tool/commandsexecutor.cc index 9863cf4fb..3ce8b003c 100644 --- a/cpp_src/cmd/reindexer_tool/commandsexecutor.cc +++ b/cpp_src/cmd/reindexer_tool/commandsexecutor.cc @@ -224,7 +224,10 @@ Error CommandsExecutor::fromFileImpl(std::istream& in) { while (GetStatus().running && std::getline(in, line.str)) { if (reindexer::checkIfStartsWith("\\upsert ", line.str) || reindexer::checkIfStartsWith("\\delete ", line.str)) { try { - cmdCh.push(line); + LineData l; + l.lineNum = line.lineNum; + reindexer::deepCopy(l.str, line.str); + cmdCh.push(std::move(l)); } catch (std::exception&) { break; } @@ -578,7 +581,7 @@ Error CommandsExecutor::processImpl(const std::string& command) noe } catch (std::exception& e) { return Error(errLogic, "std::exception during command's execution: %s", e.what()); } catch (...) { - return Error(errLogic, "Unknow exception during command's execution"); + return Error(errLogic, "Unknown exception during command's execution"); } } return Error(errParams, "Unknown command '%s'. Type '\\help' to list of available commands", token); @@ -801,7 +804,7 @@ Error CommandsExecutor::commandUpsert(const std::string& command) { status = db().Upsert(nsName, item); if (!fromFile_ && status.ok()) { - output_() << "Upserted successfuly: 1 items" << std::endl; + output_() << "Upserted successfully: 1 items" << std::endl; } return status; } @@ -946,7 +949,7 @@ Error CommandsExecutor::commandDump(const std::string& command) { } for (auto it : itemResults) { - if (auto err = it.Status(); !err.ok()) { + if (err = it.Status(); !err.ok()) { return err; } if (cancelCtx_.IsCancelled()) { @@ -1190,7 +1193,7 @@ Error CommandsExecutor::commandProcessDatabase err = db().Status(); } if (err.ok()) { - output_() << "Succesfully connected to " << currentDsn << std::endl; + output_() << "Successfully connected to " << currentDsn << std::endl; } return err; } else if (subCommand == "create"sv) { @@ -1206,7 +1209,7 @@ Error CommandsExecutor::commandProcessDatabase std::vector dbNames; err = db().EnumDatabases(dbNames); if (std::find(dbNames.begin(), dbNames.end(), std::string(dbName)) != dbNames.end()) { - output_() << "Succesfully created database '" << dbName << "'" << std::endl; + output_() << "Successfully created database '" << dbName << "'" << std::endl; } else { std::cerr << "Error on database '" << dbName << "' creation" << std::endl; } diff --git a/cpp_src/cmd/reindexer_tool/readme.md b/cpp_src/cmd/reindexer_tool/readme.md index 2cbaf143e..e1cce80fe 100644 --- a/cpp_src/cmd/reindexer_tool/readme.md +++ b/cpp_src/cmd/reindexer_tool/readme.md @@ -23,14 +23,15 @@ reindexer_tool {OPTIONS} Options -d[DSN], --dsn=[DSN] DSN to 'reindexer', like 'cproto://127.0.0.1:6534/dbname', 'builtin:///var/lib/reindexer/dbname' or `ucproto://user@password:/tmp/reindexer.sock:/dbname` -f[FILENAME], --filename=[FILENAME] Execute commands from file, then exit - -c[COMMAND], --command=[COMMAND] Run only single command (SQL or internal) and exit + -c[COMMAND], --command=[COMMAND] Run single command (SQL or internal) and exit -o[FILENAME], --output=[FILENAME] Send query results to file -l[INT=1..5], --log=[INT=1..5] Reindexer logging level -C[INT], --connections=[INT] Number of simulateonous connections to db -t[INT], --threads=[INT] Number of threads used by db connector (used only for bench) - --createdb Enable created database if missed + --createdb Creates target database if it is missing + -a[Application name], + --appname=[Application name] Application name which will be used in login info --dump-mode=[DUMP_MODE] Dump mode for sharded databases: 'full_node' (default), 'sharded_only', 'local_only' - ``` ## Commands @@ -139,10 +140,13 @@ reindexer_tool --dsn cproto://127.0.0.1:6534/mydb --command '\dump' --output myd Restore database from backup file: ```sh -reindexer_tool --dsn cproto://127.0.0.1:6534/mydb --filename mydb.rxdump +reindexer_tool --dsn cproto://127.0.0.1:6534/mydb --createdb --filename mydb.rxdump ``` +Option `createdb` in example above allows to automatically create `mydb` if it does not exist. By default `reindexer_tool` requires an existing database to connect. + Backup only sharded namespaces from all of the shards into single backup file: ```sh reindexer_tool --dsn cproto://127.0.0.1:6534/mydb --command '\dump' --dump-mode=sharded_only --output mydb.rxdump ``` + diff --git a/cpp_src/cmd/reindexer_tool/reindexer_tool.cc b/cpp_src/cmd/reindexer_tool/reindexer_tool.cc index 6372e75f2..fc5e88a0f 100644 --- a/cpp_src/cmd/reindexer_tool/reindexer_tool.cc +++ b/cpp_src/cmd/reindexer_tool/reindexer_tool.cc @@ -65,29 +65,29 @@ int main(int argc, char* argv[]) { "DSN to 'reindexer'. Can be 'cproto://:/', 'builtin://' or 'ucproto://:/'", {'d', "dsn"}, "", Options::Single | Options::Global); #endif // _WIN32 - args::ValueFlag fileName(progOptions, "FILENAME", "execute commands from file, then exit", {'f', "filename"}, "", + args::ValueFlag fileName(progOptions, "FILENAME", "Execute commands from file, then exit", {'f', "filename"}, "", Options::Single | Options::Global); - args::ValueFlag command(progOptions, "COMMAND", "run only single command (SQL or internal) and exit'", {'c', "command"}, - "", Options::Single | Options::Global); - args::ValueFlag outFileName(progOptions, "FILENAME", "send query results to file", {'o', "output"}, "", + args::ValueFlag command(progOptions, "COMMAND", "Run single command (SQL or internal) and exit", {'c', "command"}, "", + Options::Single | Options::Global); + args::ValueFlag outFileName(progOptions, "FILENAME", "Send query results to file", {'o', "output"}, "", Options::Single | Options::Global); args::ValueFlag dumpMode(progOptions, "DUMP_MODE", - "dump mode for sharded databases: 'full_node' (default), 'sharded_only', 'local_only'", + "Dump mode for sharded databases: 'full_node' (default), 'sharded_only', 'local_only'", {"dump-mode"}, "", Options::Single | Options::Global); args::ValueFlag connThreads(progOptions, "INT=1..65535", "Number of threads(connections) used by db connector", {'t', "threads"}, 1, Options::Single | Options::Global); - args::Flag createDBF(progOptions, "", "Enable created database if missed", {"createdb"}); + args::Flag createDBF(progOptions, "", "Creates target database if it is missing", {"createdb"}); args::Positional dbName(progOptions, "DB name", "Name of a database to get connected to", Options::Single); - args::ActionFlag logLevel(progOptions, "INT=1..5", "reindexer logging level", {'l', "log"}, 1, &InstallLogLevel, + args::ActionFlag logLevel(progOptions, "INT=1..5", "Reindexer logging level", {'l', "log"}, 1, &InstallLogLevel, Options::Single | Options::Global); - args::Flag repair(progOptions, "", "Repair database", {'r', "repair"}); + args::Flag repair(progOptions, "", "Try to repair storage", {'r', "repair"}); - args::ValueFlag appName(progOptions, "Application name", "Application name which will be used in login info", + args::ValueFlag appName(progOptions, "Application name", "Application name that will be used in login info", {'a', "appname"}, "reindexer_tool", Options::Single | Options::Global); args::GlobalOptions globals(parser, progOptions); diff --git a/cpp_src/core/cjson/baseencoder.cc b/cpp_src/core/cjson/baseencoder.cc index 46bf25bb1..aabd273b0 100644 --- a/cpp_src/core/cjson/baseencoder.cc +++ b/cpp_src/core/cjson/baseencoder.cc @@ -1,6 +1,5 @@ #include "baseencoder.h" #include -#include #include "cjsonbuilder.h" #include "cjsontools.h" #include "core/keyvalue/p_string.h" @@ -48,7 +47,7 @@ void BaseEncoder::Encode(ConstPayload& pl, Builder& builder, const h_ve } objectScalarIndexes_.reset(); - std::fill_n(std::begin(fieldsoutcnt_), pl.NumFields(), 0); + std::fill(fieldsoutcnt_.begin(), fieldsoutcnt_.end(), 0); builder.SetTagsMatcher(tagsMatcher_); if constexpr (kWithTagsPathTracking) { builder.SetTagsPath(&curTagsPath_); @@ -175,11 +174,11 @@ bool BaseEncoder::encode(ConstPayload* pl, Serializer& rdser, Builder& [&](KeyValueType::String) { builder.Array(tagName, pl->GetArray(tagField).subspan(cnt, count), cnt); }, [&](KeyValueType::Uuid) { builder.Array(tagName, pl->GetArray(tagField).subspan(cnt, count), cnt); }, [](OneOf) noexcept { - assertrx(0); + assertrx(false); abort(); }); } - cnt += count; + cnt += int(count); break; } case TAG_NULL: diff --git a/cpp_src/core/cjson/baseencoder.h b/cpp_src/core/cjson/baseencoder.h index d68730095..4653592a7 100644 --- a/cpp_src/core/cjson/baseencoder.h +++ b/cpp_src/core/cjson/baseencoder.h @@ -10,7 +10,6 @@ namespace reindexer { class TagsMatcher; -class JsonBuilder; class MsgPackBuilder; class ProtobufBuilder; class CsvBuilder; @@ -38,7 +37,7 @@ class IAdditionalDatasource { template class BaseEncoder { public: - BaseEncoder(const TagsMatcher* tagsMatcher, const FieldsSet* filter = nullptr); + explicit BaseEncoder(const TagsMatcher* tagsMatcher, const FieldsSet* filter = nullptr); void Encode(ConstPayload& pl, Builder& builder, const h_vector*, 2>& dss = h_vector*, 2>()); void Encode(std::string_view tuple, Builder& wrSer, @@ -63,9 +62,9 @@ class BaseEncoder { std::string_view getPlTuple(ConstPayload& pl); - const TagsMatcher* tagsMatcher_; - std::array fieldsoutcnt_{0}; - const FieldsSet* filter_; + const TagsMatcher* tagsMatcher_{nullptr}; + std::array fieldsoutcnt_; + const FieldsSet* filter_{nullptr}; WrSerializer tmpPlTuple_; TagsPath curTagsPath_; IndexedTagsPathInternalT indexedTagsPath_; diff --git a/cpp_src/core/cjson/cjsondecoder.cc b/cpp_src/core/cjson/cjsondecoder.cc index 0809b16d1..02ae6b95e 100644 --- a/cpp_src/core/cjson/cjsondecoder.cc +++ b/cpp_src/core/cjson/cjsondecoder.cc @@ -11,7 +11,6 @@ bool CJsonDecoder::decodeCJson(Payload& pl, Serializer& rdser, WrSerializer& wrs const ctag tag = rdser.GetCTag(); TagType tagType = tag.Type(); if (tag == kCTagEnd) { - recoder.Serialize(wrser); wrser.PutCTag(kCTagEnd); return false; } diff --git a/cpp_src/core/cjson/cjsondecoder.h b/cpp_src/core/cjson/cjsondecoder.h index 443fea4c7..747c2fd7e 100644 --- a/cpp_src/core/cjson/cjsondecoder.h +++ b/cpp_src/core/cjson/cjsondecoder.h @@ -17,10 +17,8 @@ class Recoder { [[nodiscard]] virtual TagType Type(TagType oldTagType) = 0; virtual void Recode(Serializer&, WrSerializer&) const = 0; virtual void Recode(Serializer&, Payload&, int tagName, WrSerializer&) = 0; - [[nodiscard]] virtual bool Match(int field) noexcept = 0; - [[nodiscard]] virtual bool Match(TagType, const TagsPath&) = 0; - virtual void Serialize(WrSerializer& wrser) = 0; - virtual bool Reset() = 0; + [[nodiscard]] virtual bool Match(int field) const noexcept = 0; + [[nodiscard]] virtual bool Match(const TagsPath&) const = 0; virtual ~Recoder() = default; }; @@ -49,7 +47,7 @@ class CJsonDecoder { class IndexedSkipFilter { public: - IndexedSkipFilter(const FieldsSet& f) noexcept : f_(&f) {} + explicit IndexedSkipFilter(const FieldsSet& f) noexcept : f_(&f) {} IndexedSkipFilter MakeCleanCopy() const noexcept { return IndexedSkipFilter(*f_); } IndexedSkipFilter MakeSkipFilter() const noexcept { return IndexedSkipFilter(*f_); } @@ -57,7 +55,7 @@ class CJsonDecoder { RX_ALWAYS_INLINE bool match(const TagsPath&) const noexcept { return false; } private: - const FieldsSet* f_; + const FieldsSet* f_{nullptr}; }; class RestrictingFilter { @@ -85,8 +83,8 @@ class CJsonDecoder { } private: - const FieldsSet* f_; - bool match_; + const FieldsSet* f_{nullptr}; + bool match_{false}; }; class DummyRecoder { @@ -96,7 +94,6 @@ class CJsonDecoder { RX_ALWAYS_INLINE bool Recode(Serializer&, Payload&, int, WrSerializer&) const noexcept { return false; } RX_ALWAYS_INLINE TagType RegisterTagType(TagType tagType, int) const noexcept { return tagType; } RX_ALWAYS_INLINE TagType RegisterTagType(TagType tagType, const TagsPath&) const noexcept { return tagType; } - RX_ALWAYS_INLINE void Serialize(WrSerializer&) const {} }; class DefaultRecoder { public: @@ -121,14 +118,13 @@ class CJsonDecoder { return needToRecode_ ? r_->Type(tagType) : tagType; } RX_ALWAYS_INLINE TagType RegisterTagType(TagType tagType, const TagsPath& tagsPath) { - needToRecode_ = r_->Match(tagType, tagsPath); + needToRecode_ = r_->Match(tagsPath); return needToRecode_ ? r_->Type(tagType) : tagType; } - RX_ALWAYS_INLINE void Serialize(WrSerializer& wser) const { r_->Serialize(wser); } private: - Recoder* r_; - bool needToRecode_; + Recoder* r_{nullptr}; + bool needToRecode_{false}; }; struct NamedTagOpt {}; struct NamelessTagOpt {}; @@ -166,7 +162,7 @@ class CJsonDecoder { TagsMatcher& tagsMatcher_; TagsPath tagsPath_; - int32_t arrayLevel_ = 0; + int32_t arrayLevel_{0}; ScalarIndexesSetT objectScalarIndexes_; // storage for owning strings obtained from numbers std::deque& storage_; diff --git a/cpp_src/core/cjson/defaultvaluecoder.cc b/cpp_src/core/cjson/defaultvaluecoder.cc deleted file mode 100644 index d33713150..000000000 --- a/cpp_src/core/cjson/defaultvaluecoder.cc +++ /dev/null @@ -1,171 +0,0 @@ -#include "defaultvaluecoder.h" - -namespace reindexer { - -DefaultValueCoder::DefaultValueCoder(std::string_view ns, const PayloadFieldType& fld, std::vector&& tps, int16_t fieldIdx) - : ns_(ns), - field_(fld.Name()), - tags_(std::move(tps)), - fieldIdx_(fieldIdx), - type_(fld.Type().ToTagType()), - array_(fld.IsArray()), - basePath_(&tags_.front()) {} - -bool DefaultValueCoder::Match(int field) noexcept { - // non-nested field present in tuple - if ((field == fieldIdx_) && ready()) { - state_ = State::found; - } - return false; // returned result is always same -} - -bool DefaultValueCoder::Match(TagType tt, const TagsPath& tp) { - static const bool result = false; // returned result is always same - - // nothing to look for (start tuple global object) - if (tp.empty()) { - state_ = State::wait; - // inArray_ = false; - // arrField_ = 0; - return result; - } - - // found\recorded earlier - if ((state_ == State::found) || ((state_ == State::write) /* && !inArray_*/)) { - return result; - } - - // check if active array has been processed - const bool arrayTag = (tt == TAG_ARRAY); - // if (inArray_) { - // inArray_ = ((tt == TAG_OBJECT) || arrayTag) ? (tp.back() == arrField_) : (tp[tp.size() - 2] == arrField_); // -2 pre-last item - // // recorded earlier - stop it - // if (!inArray_ && (state_ == State::write)) { - // return result; - // } - // } - - // try match nested field - if (tt == TAG_OBJECT) { - assertrx(state_ != State::found); - match(tp); - return result; - } - - // may be end element of adjacent nested field - if (arrayTag) { - if (tp.size() <= basePath_->size() && std::equal(tp.begin(), tp.end(), basePath_->begin())) { - // Do not create anything inside objects arrays #1819 - state_ = State::found; - return result; - } - // inArray_ = (tp.front() == basePath_->front()); - // arrField_ = tp.back(); - } - - // not nested - if (copyPos_ == 0) { - return result; - } - - // detect array insertion into array (not supported) - if (arrayTag && array_) { - state_ = State::found; // do nothing - } else if ((tp.front() == basePath_->front()) && (tp.size() > basePath_->size())) { - ++nestingLevel_; - } - - return result; -} - -void DefaultValueCoder::Serialize(WrSerializer& wrser) { - if (blocked()) { - return; // skip processing - } - - // skip nested levels - if ((basePath_->size() > 1) || (nestingLevel_ > 1)) { - assertrx(nestingLevel_ > 0); - --nestingLevel_; - - // new field - move to valid level - if (nestingLevel_ > copyPos_) { - return; - } - } - - const auto written = write(wrser); - Reset(); - state_ = written ? State::write : State::found; -} - -bool DefaultValueCoder::Reset() noexcept { - nestingLevel_ = 1; - copyPos_ = 0; - // NOTE: return true when updating tuple - return (state_ == State::write); -} - -void DefaultValueCoder::match(const TagsPath& tp) { - ++nestingLevel_; - - for (auto& path : tags_) { - if (path.front() != tp.front()) { - continue; - } - - copyPos_ = 1; - auto pathSize = path.size(); - auto sz = std::min(pathSize, tp.size()); - for (size_t idx = 1; idx < sz; ++idx) { - if (path[idx] != tp[idx]) { - break; - } - ++copyPos_; - - // we are trying to add field with non-nested paths, but an intersection was found in additional nested paths. - // Stop, throw an error - if (tags_.front().size() == 1) { - throw Error(errLogic, "Cannot add field with name '%s' to namespace '%s'. One of nested json paths is already in use", - field_, ns_); - } - } - state_ = State::match; - basePath_ = &path; - break; - } -} - -bool DefaultValueCoder::write(WrSerializer& wrser) const { - if (array_ && copyPos_ + 1 < basePath_->size()) { - // Do not create multiple levels for nested array indexes to avoid problems with decoding in Go/Java connectors. #1819 - return false; - } - int32_t nestedObjects = 0; - for (size_t idx = copyPos_, sz = basePath_->size(); idx < sz; ++idx) { - auto tagName = (*basePath_)[idx]; - // real index field in last tag - const bool finalTag = (idx == (sz - 1)); - if (finalTag) { - if (array_) { - wrser.PutCTag(ctag{TAG_ARRAY, tagName, fieldIdx_}); - wrser.PutVarUint(0); - } else { - wrser.PutCTag(ctag{type_, tagName, fieldIdx_}); - } - break; - } - - // start nested object - wrser.PutCTag(ctag{TAG_OBJECT, tagName}); - ++nestedObjects; - } - - // add end tags to all objects - while (nestedObjects-- > 0) { - wrser.PutCTag(kCTagEnd); - } - return true; -} - -} // namespace reindexer diff --git a/cpp_src/core/cjson/defaultvaluecoder.h b/cpp_src/core/cjson/defaultvaluecoder.h deleted file mode 100644 index 3f4276dc2..000000000 --- a/cpp_src/core/cjson/defaultvaluecoder.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include "cjsondecoder.h" - -namespace reindexer { - -class DefaultValueCoder : public Recoder { -public: - DefaultValueCoder(std::string_view ns, const PayloadFieldType& fld, std::vector&& tps, int16_t fieldIdx); - RX_ALWAYS_INLINE TagType Type(TagType tt) noexcept override final { return tt; } - [[nodiscard]] bool Match(int f) noexcept override final; - [[nodiscard]] bool Match(TagType tt, const TagsPath& tp) override final; - RX_ALWAYS_INLINE void Recode(Serializer&, WrSerializer&) const noexcept override final { assertrx(false); } - RX_ALWAYS_INLINE void Recode(Serializer&, Payload&, int, WrSerializer&) noexcept override final { assertrx(false); } - void Serialize(WrSerializer& wrser) override final; - bool Reset() noexcept override final; - -private: - void match(const TagsPath& tp); - [[nodiscard]] bool write(WrSerializer& wrser) const; - [[nodiscard]] RX_ALWAYS_INLINE bool blocked() const noexcept { return ((state_ == State::found) || (state_ == State::write)); } - [[nodiscard]] RX_ALWAYS_INLINE bool ready() const noexcept { return ((state_ == State::wait) || (state_ == State::match)); } - -private: - const std::string ns_; - const std::string field_; - const std::vector tags_; - const int16_t fieldIdx_{0}; - const TagType type_; - const bool array_{false}; - - const TagsPath* basePath_{nullptr}; - enum class State { wait, found, match, write } state_{State::wait}; - uint32_t nestingLevel_{1}; - uint32_t copyPos_{0}; - - // bool inArray_{false}; - // int16_t arrField_{0}; -}; - -} // namespace reindexer diff --git a/cpp_src/core/cjson/jsondecoder.cc b/cpp_src/core/cjson/jsondecoder.cc index 85d3ac79d..7ee9a0e0e 100644 --- a/cpp_src/core/cjson/jsondecoder.cc +++ b/cpp_src/core/cjson/jsondecoder.cc @@ -115,13 +115,8 @@ void JsonDecoder::decodeJson(Payload* pl, CJsonBuilder& builder, const gason::Js builder.Null(tagName); break; case gason::JSON_ARRAY: { - ObjType type; CounterGuardIR32 g(arrayLevel_); - if (gason::isHomogeneousArray(v)) { - type = ObjType::TypeArray; - } else { - type = ObjType::TypeObjectArray; - } + ObjType type = (gason::isHomogeneousArray(v)) ? ObjType::TypeArray : ObjType::TypeObjectArray; auto arrNode = builder.Array(tagName, type); for (const auto& elem : v) { decodeJson(pl, arrNode, elem.value, 0, match); diff --git a/cpp_src/core/cjson/jsondecoder.h b/cpp_src/core/cjson/jsondecoder.h index 73dad50f2..066f6740a 100644 --- a/cpp_src/core/cjson/jsondecoder.h +++ b/cpp_src/core/cjson/jsondecoder.h @@ -8,8 +8,8 @@ namespace reindexer { class JsonDecoder { public: - explicit JsonDecoder(TagsMatcher& tagsMatcher) noexcept : tagsMatcher_(tagsMatcher), filter_(nullptr) {} - JsonDecoder(TagsMatcher& tagsMatcher, const FieldsSet* filter) noexcept : tagsMatcher_(tagsMatcher), filter_(filter) {} + explicit JsonDecoder(TagsMatcher& tagsMatcher, const FieldsSet* filter = nullptr) noexcept + : tagsMatcher_(tagsMatcher), filter_(filter) {} Error Decode(Payload& pl, WrSerializer& wrSer, const gason::JsonValue& v); void Decode(std::string_view json, CJsonBuilder& builder, const TagsPath& fieldPath); @@ -21,8 +21,8 @@ class JsonDecoder { TagsMatcher& tagsMatcher_; TagsPath tagsPath_; - const FieldsSet* filter_; - int32_t arrayLevel_ = 0; + const FieldsSet* filter_{nullptr}; + int32_t arrayLevel_{0}; ScalarIndexesSetT objectScalarIndexes_; }; diff --git a/cpp_src/core/cjson/msgpackdecoder.cc b/cpp_src/core/cjson/msgpackdecoder.cc index e08e55ab5..8b72c9f21 100644 --- a/cpp_src/core/cjson/msgpackdecoder.cc +++ b/cpp_src/core/cjson/msgpackdecoder.cc @@ -145,13 +145,13 @@ Error MsgPackDecoder::Decode(std::string_view buf, Payload& pl, WrSerializer& wr } catch (const Error& err) { return err; } catch (const std::exception& ex) { - return Error(errNotValid, "%s", ex.what()); + return {errNotValid, "%s", ex.what()}; } catch (...) { // all internal errors shall be handled and converted to Error - return Error(errNotValid, "Unexpected exception"); + return {errNotValid, "Unexpected exception"}; } - return Error(); + return {}; } constexpr std::string_view ToString(msgpack_object_type type) { diff --git a/cpp_src/core/cjson/protobufdecoder.cc b/cpp_src/core/cjson/protobufdecoder.cc index a8313ab01..7d2dcc04a 100644 --- a/cpp_src/core/cjson/protobufdecoder.cc +++ b/cpp_src/core/cjson/protobufdecoder.cc @@ -1,14 +1,13 @@ #include "protobufdecoder.h" #include "core/schema.h" #include "estl/protobufparser.h" -#include "protobufbuilder.h" namespace reindexer { void ArraysStorage::UpdateArraySize(int tagName, int field) { GetArray(tagName, field); } CJsonBuilder& ArraysStorage::GetArray(int tagName, int field) { - assertrx(indexes_.size() > 0); + assertrx(!indexes_.empty()); auto it = data_.find(tagName); if (it == data_.end()) { indexes_.back().emplace_back(tagName); @@ -25,7 +24,7 @@ CJsonBuilder& ArraysStorage::GetArray(int tagName, int field) { void ArraysStorage::onAddObject() { indexes_.emplace_back(h_vector()); } void ArraysStorage::onObjectBuilt(CJsonBuilder& parent) { - assertrx(indexes_.size() > 0); + assertrx(!indexes_.empty()); for (int tagName : indexes_.back()) { auto it = data_.find(tagName); assertrx(it != data_.end()); @@ -69,10 +68,10 @@ void ProtobufDecoder::setValue(Payload& pl, CJsonBuilder& builder, ProtobufValue Error ProtobufDecoder::decodeArray(Payload& pl, CJsonBuilder& builder, const ProtobufValue& item) { ProtobufObject object(item.As(), *schema_, tagsPath_, tm_); ProtobufParser parser(object); - bool packed = item.IsOfPrimitiveType(); - int field = tm_.tags2field(tagsPath_.data(), tagsPath_.size()); + const bool packed = item.IsOfPrimitiveType(); + const int field = tm_.tags2field(tagsPath_.data(), tagsPath_.size()); if (field > 0) { - auto& f = pl.Type().Field(field); + const auto& f = pl.Type().Field(field); if rx_unlikely (!f.IsArray()) { throw Error(errLogic, "Error parsing protobuf field '%s' - got array, expected scalar %s", f.Name(), f.Type().Name()); } @@ -104,7 +103,7 @@ Error ProtobufDecoder::decodeArray(Payload& pl, CJsonBuilder& builder, const Pro } } } - return Error(); + return {}; } Error ProtobufDecoder::decode(Payload& pl, CJsonBuilder& builder, const ProtobufValue& item) { diff --git a/cpp_src/core/cjson/uuid_recoders.h b/cpp_src/core/cjson/uuid_recoders.h index cdc264ac3..9bb51c701 100644 --- a/cpp_src/core/cjson/uuid_recoders.h +++ b/cpp_src/core/cjson/uuid_recoders.h @@ -19,10 +19,8 @@ class RecoderUuidToString : public Recoder { } void Recode(Serializer&, WrSerializer&) const override final; void Recode(Serializer&, Payload&, int, WrSerializer&) override final { assertrx(false); } - [[nodiscard]] bool Match(int) noexcept override final { return false; } - [[nodiscard]] bool Match(TagType, const TagsPath& tp) noexcept override final { return tagsPath_ == tp; } - void Serialize(WrSerializer&) override final {} - bool Reset() override final { return false; } + [[nodiscard]] bool Match(int) const noexcept final { return false; } + [[nodiscard]] bool Match(const TagsPath& tp) const noexcept final { return tagsPath_ == tp; } private: TagsPath tagsPath_; @@ -54,8 +52,8 @@ class RecoderStringToUuidArray : public Recoder { } return TAG_ARRAY; } - [[nodiscard]] bool Match(int f) noexcept override final { return f == field_; } - [[nodiscard]] bool Match(TagType, const TagsPath&) noexcept override final { return false; } + [[nodiscard]] bool Match(int f) const noexcept final { return f == field_; } + [[nodiscard]] bool Match(const TagsPath&) const noexcept final { return false; } void Recode(Serializer&, WrSerializer&) const override final { assertrx(false); } void Recode(Serializer& rdser, Payload& pl, int tagName, WrSerializer& wrser) override final { if (fromNotArrayField_) { @@ -78,8 +76,6 @@ class RecoderStringToUuidArray : public Recoder { wrser.PutVarUint(count); } } - void Serialize(WrSerializer&) override final {} - bool Reset() override final { return false; } private: const int field_{std::numeric_limits::max()}; @@ -98,15 +94,13 @@ class RecoderStringToUuid : public Recoder { } return TAG_UUID; } - [[nodiscard]] bool Match(int f) noexcept override final { return f == field_; } - [[nodiscard]] bool Match(TagType, const TagsPath&) noexcept override final { return false; } + [[nodiscard]] bool Match(int f) const noexcept final { return f == field_; } + [[nodiscard]] bool Match(const TagsPath&) const noexcept final { return false; } void Recode(Serializer&, WrSerializer&) const override final { assertrx(false); } void Recode(Serializer& rdser, Payload& pl, int tagName, WrSerializer& wrser) override final { pl.Set(field_, Variant{rdser.GetStrUuid()}, true); wrser.PutCTag(ctag{TAG_UUID, tagName, field_}); } - void Serialize(WrSerializer&) override final {} - bool Reset() override final { return false; } private: const int field_{std::numeric_limits::max()}; diff --git a/cpp_src/core/formatters/key_string_fmt.h b/cpp_src/core/formatters/key_string_fmt.h index 37869b917..59d0086df 100644 --- a/cpp_src/core/formatters/key_string_fmt.h +++ b/cpp_src/core/formatters/key_string_fmt.h @@ -1,7 +1,7 @@ #pragma once -#include "fmt/format.h" #include "core/keyvalue/key_string.h" +#include "fmt/format.h" template <> struct fmt::printf_formatter { diff --git a/cpp_src/core/formatters/uuid_fmt.h b/cpp_src/core/formatters/uuid_fmt.h index e77ec886b..e249d4b55 100644 --- a/cpp_src/core/formatters/uuid_fmt.h +++ b/cpp_src/core/formatters/uuid_fmt.h @@ -1,7 +1,7 @@ #pragma once -#include "fmt/format.h" #include "core/keyvalue/uuid.h" +#include "fmt/format.h" template <> struct fmt::printf_formatter { diff --git a/cpp_src/core/ft/areaholder.h b/cpp_src/core/ft/areaholder.h index 53bac35b1..3bb410fa8 100644 --- a/cpp_src/core/ft/areaholder.h +++ b/cpp_src/core/ft/areaholder.h @@ -14,10 +14,8 @@ struct Area { Area() noexcept : start(0), end(0) {} Area(int s, int e) noexcept : start(s), end(e) {} - [[nodiscard]] bool inline IsIn(int pos) noexcept { return pos <= end && pos >= start; } - - [[nodiscard]] bool inline Concat(const Area& rhs) noexcept { - if (IsIn(rhs.start) || IsIn(rhs.end) || (start > rhs.start && end < rhs.end)) { + [[nodiscard]] bool Concat(const Area& rhs) noexcept { + if (isIn(rhs.start) || isIn(rhs.end) || (start > rhs.start && end < rhs.end)) { if (start > rhs.start) { start = rhs.start; } @@ -31,19 +29,35 @@ struct Area { int start; int end; + +private: + [[nodiscard]] bool inline isIn(int pos) noexcept { return pos <= end && pos >= start; } }; -class AreaHolder; +struct AreaDebug { + enum class PhraseMode { None, Start, End }; + AreaDebug() {} + AreaDebug(int s, int e, std::string&& p, PhraseMode phMode) noexcept : start(s), end(e), props(p), phraseMode(phMode) {} + [[nodiscard]] RX_ALWAYS_INLINE bool Concat(const AreaDebug&) noexcept { return false; } + int start = 0; + int end = 0; + std::string props; + PhraseMode phraseMode = PhraseMode::None; +}; -class AreaBuffer { +template +class AreasInDocument; + +template +class AreasInField { public: - AreaBuffer() = default; + AreasInField() = default; [[nodiscard]] size_t Size() const noexcept { return data_.size(); } [[nodiscard]] bool Empty() const noexcept { return data_.empty(); } void Commit() { if (!data_.empty()) { boost::sort::pdqsort_branchless(data_.begin(), data_.end(), - [](const Area& rhs, const Area& lhs) noexcept { return rhs.start < lhs.start; }); + [](const AreaType& rhs, const AreaType& lhs) noexcept { return rhs.start < lhs.start; }); for (auto vit = data_.begin() + 1; vit != data_.end(); ++vit) { auto prev = vit - 1; if (vit->Concat(*prev)) { @@ -52,7 +66,7 @@ class AreaBuffer { } } } - [[nodiscard]] bool Insert(Area&& area, float termRank, int maxAreasInDoc, float maxTermRank) { + [[nodiscard]] bool Insert(AreaType&& area, float termRank, int maxAreasInDoc, float maxTermRank) { if (!data_.empty() && data_.back().Concat(area)) { return true; } else { @@ -71,22 +85,26 @@ class AreaBuffer { return false; } - [[nodiscard]] const RVector& GetData() const noexcept { return data_; } - void MoveAreas(AreaHolder& to, int field, int32_t rank, int maxAreasInDoc); + [[nodiscard]] const RVector& GetData() const noexcept { return data_; } + void MoveAreas(AreasInDocument& to, int field, int32_t rank, int maxAreasInDoc) { + for (auto& v : data_) { + [[maybe_unused]] bool r = to.InsertArea(std::move(v), field, rank, maxAreasInDoc); + } + to.UpdateRank(rank); + data_.resize(0); + } private: - RVector data_; + RVector data_; int index_ = 0; }; -class AreaHolder { +template +class AreasInDocument { public: - typedef std::shared_ptr Ptr; - typedef std::unique_ptr UniquePtr; - - AreaHolder() = default; - ~AreaHolder() = default; - AreaHolder(AreaHolder&&) = default; + AreasInDocument() = default; + ~AreasInDocument() = default; + AreasInDocument(AreasInDocument&&) = default; void Reserve(int size) { areas_.reserve(size); } void ReserveField(int size) { areas_.resize(size); } void Commit() { @@ -95,21 +113,24 @@ class AreaHolder { area.Commit(); } } - [[nodiscard]] bool AddWord(int pos, int field, int32_t rank, int maxAreasInDoc) { - return InsertArea(Area{pos, pos + 1}, field, rank, maxAreasInDoc); + [[nodiscard]] bool AddWord(AreaType&& area, int field, int32_t rank, int maxAreasInDoc) { + return InsertArea(std::move(area), field, rank, maxAreasInDoc); } void UpdateRank(int32_t rank) noexcept { if (rank > maxTermRank_) { maxTermRank_ = rank; } } - [[nodiscard]] AreaBuffer* GetAreas(int field) { + + [[nodiscard]] AreasInField* GetAreas(int field) { if (!commited_) { Commit(); } return (areas_.size() <= size_t(field)) ? nullptr : &areas_[field]; } - [[nodiscard]] AreaBuffer* GetAreasRaw(int field) noexcept { return (areas_.size() <= size_t(field)) ? nullptr : &areas_[field]; } + [[nodiscard]] AreasInField* GetAreasRaw(int field) noexcept { + return (areas_.size() <= size_t(field)) ? nullptr : &areas_[field]; + } [[nodiscard]] bool IsCommited() const noexcept { return commited_; } [[nodiscard]] size_t GetAreasCount() const noexcept { size_t size = 0; @@ -118,7 +139,7 @@ class AreaHolder { } return size; } - [[nodiscard]] bool InsertArea(Area&& area, int field, int32_t rank, int maxAreasInDoc) { + [[nodiscard]] bool InsertArea(AreaType&& area, int field, int32_t rank, int maxAreasInDoc) { commited_ = false; if (areas_.size() <= size_t(field)) { areas_.resize(field + 1); @@ -129,16 +150,8 @@ class AreaHolder { private: bool commited_ = false; - RVector areas_; + RVector, 3> areas_; int32_t maxTermRank_ = 0; }; -inline void AreaBuffer::MoveAreas(AreaHolder& to, int field, int32_t rank, int maxAreasInDoc) { - for (auto& v : data_) { - [[maybe_unused]] bool r = to.InsertArea(std::move(v), field, rank, maxAreasInDoc); - } - to.UpdateRank(rank); - data_.resize(0); -} - } // namespace reindexer diff --git a/cpp_src/core/ft/ft_fast/dataholder.cc b/cpp_src/core/ft/ft_fast/dataholder.cc index 4dc826ce9..e41d4f0b7 100644 --- a/cpp_src/core/ft/ft_fast/dataholder.cc +++ b/cpp_src/core/ft/ft_fast/dataholder.cc @@ -104,8 +104,8 @@ void DataHolder::Clear() { } template -void DataHolder::StartCommit(bool complte_updated) { - if (NeedRebuild(complte_updated)) { +void DataHolder::StartCommit(bool complete_updated) { + if (NeedRebuild(complete_updated)) { status_ = FullRebuild; Clear(); diff --git a/cpp_src/core/ft/ft_fast/dataholder.h b/cpp_src/core/ft/ft_fast/dataholder.h index 5926fc491..943f02b65 100644 --- a/cpp_src/core/ft/ft_fast/dataholder.h +++ b/cpp_src/core/ft/ft_fast/dataholder.h @@ -109,7 +109,7 @@ class IDataHolder { virtual void Process(size_t fieldSize, bool multithread) = 0; virtual size_t GetMemStat() = 0; virtual void Clear() = 0; - virtual void StartCommit(bool complte_updated) = 0; + virtual void StartCommit(bool complete_updated) = 0; void SetConfig(FtFastConfig* cfg); CommitStep& GetStep(WordIdType id) noexcept { assertrx(id.b.step_num < steps.size()); diff --git a/cpp_src/core/ft/ft_fast/selecter.cc b/cpp_src/core/ft/ft_fast/selecter.cc index e0bef67a1..ec3f63899 100644 --- a/cpp_src/core/ft/ft_fast/selecter.cc +++ b/cpp_src/core/ft/ft_fast/selecter.cc @@ -119,9 +119,9 @@ void Selecter::prepareVariants(std::vector& variants, RV // RX_NO_INLINE just for build test purpose. Do not expect any effect here template -template -RX_NO_INLINE MergeData Selecter::Process(FtDSLQuery&& dsl, bool inTransaction, FtSortType ftSortType, - FtMergeStatuses::Statuses&& mergeStatuses, const RdxContext& rdxCtx) { +template +MergeType Selecter::Process(FtDSLQuery&& dsl, bool inTransaction, FtSortType ftSortType, FtMergeStatuses::Statuses&& mergeStatuses, + const RdxContext& rdxCtx) { FtSelectContext ctx; ctx.rawResults.reserve(dsl.size()); // STEP 2: Search dsl terms for each variant @@ -210,38 +210,38 @@ RX_NO_INLINE MergeData Selecter::Process(FtDSLQuery&& dsl, bool inTransa for (auto& res : ctx.rawResults) { results.emplace_back(std::move(res)); } - const auto maxMergedSize = std::min(size_t(holder_.cfg_->mergeLimit), ctx.totalORVids); + const auto maxMergedSize = std::min(size_t(holder_.cfg_->mergeLimit), ctx.totalORVids); if (maxMergedSize < 0xFFFF) { - return mergeResultsBmType(std::move(results), ctx.totalORVids, synonymsBounds, inTransaction, ftSortType, - std::move(mergeStatuses), rdxCtx); + return mergeResultsBmType(std::move(results), ctx.totalORVids, synonymsBounds, inTransaction, ftSortType, + std::move(mergeStatuses), rdxCtx); } else if (maxMergedSize < 0xFFFFFFFF) { - return mergeResultsBmType(std::move(results), ctx.totalORVids, synonymsBounds, inTransaction, ftSortType, - std::move(mergeStatuses), rdxCtx); + return mergeResultsBmType(std::move(results), ctx.totalORVids, synonymsBounds, inTransaction, ftSortType, + std::move(mergeStatuses), rdxCtx); } else { assertrx_throw(false); } - return MergeData(); + return MergeType(); } template -template -MergeData Selecter::mergeResultsBmType(std::vector&& results, size_t totalORVids, +template +MergeType Selecter::mergeResultsBmType(std::vector&& results, size_t totalORVids, const std::vector& synonymsBounds, bool inTransaction, FtSortType ftSortType, FtMergeStatuses::Statuses&& mergeStatuses, const RdxContext& rdxCtx) { switch (holder_.cfg_->bm25Config.bm25Type) { case FtFastConfig::Bm25Config::Bm25Type::rx: - return mergeResults(std::move(results), totalORVids, synonymsBounds, inTransaction, ftSortType, - std::move(mergeStatuses), rdxCtx); + return mergeResults(std::move(results), totalORVids, synonymsBounds, inTransaction, + ftSortType, std::move(mergeStatuses), rdxCtx); case FtFastConfig::Bm25Config::Bm25Type::classic: - return mergeResults(std::move(results), totalORVids, synonymsBounds, inTransaction, ftSortType, - std::move(mergeStatuses), rdxCtx); + return mergeResults(std::move(results), totalORVids, synonymsBounds, inTransaction, + ftSortType, std::move(mergeStatuses), rdxCtx); case FtFastConfig::Bm25Config::Bm25Type::wordCount: - return mergeResults(std::move(results), totalORVids, synonymsBounds, inTransaction, ftSortType, - std::move(mergeStatuses), rdxCtx); + return mergeResults(std::move(results), totalORVids, synonymsBounds, inTransaction, + ftSortType, std::move(mergeStatuses), rdxCtx); } assertrx_throw(false); - return MergeData(); + return MergeType(); } template @@ -449,33 +449,32 @@ RX_ALWAYS_INLINE void Selecter::debugMergeStep(const char* msg, int vid, template template RX_ALWAYS_INLINE void Selecter::calcFieldBoost(const Calculator& bm25Calc, unsigned long long f, const IdRelType& relid, - const FtDslOpts& opts, int termProc, double& termRank, double& normBm25, - bool& dontSkipCurTermRank, h_vector& ranksInFields, int& field) { + const FtDslOpts& opts, TermRankInfo& termInf, bool& dontSkipCurTermRank, + h_vector& ranksInFields, int& field) { assertrx(f < holder_.cfg_->fieldsCfg.size()); const auto& fldCfg = holder_.cfg_->fieldsCfg[f]; // raw bm25 const double bm25 = bm25Calc.Get(relid.WordsInField(f), holder_.vdocs_[relid.Id()].wordsCount[f], holder_.avgWordsCount_[f]); - // normalized bm25 const double normBm25Tmp = bound(bm25, fldCfg.bm25Weight, fldCfg.bm25Boost); + termInf.positionRank = bound(::pos2rank(relid.MinPositionInField(f)), fldCfg.positionWeight, fldCfg.positionBoost); + termInf.termLenBoost = bound(opts.termLenBoost, fldCfg.termLenWeight, fldCfg.termLenBoost); - const double positionRank = bound(::pos2rank(relid.MinPositionInField(f)), fldCfg.positionWeight, fldCfg.positionBoost); - - float termLenBoost = bound(opts.termLenBoost, fldCfg.termLenWeight, fldCfg.termLenBoost); // final term rank calculation - const double termRankTmp = opts.fieldsOpts[f].boost * termProc * normBm25Tmp * opts.boost * termLenBoost * positionRank; + const double termRankTmp = + opts.fieldsOpts[f].boost * termInf.proc * normBm25Tmp * opts.boost * termInf.termLenBoost * termInf.positionRank; const bool needSumRank = opts.fieldsOpts[f].needSumRank; - if (termRankTmp > termRank) { + if (termRankTmp > termInf.termRank) { if (dontSkipCurTermRank) { - ranksInFields.push_back(termRank); + ranksInFields.push_back(termInf.termRank); } field = f; - normBm25 = normBm25Tmp; - termRank = termRankTmp; + termInf.termRank = termRankTmp; + termInf.bm25Norm = normBm25Tmp; dontSkipCurTermRank = needSumRank; - } else if (!dontSkipCurTermRank && needSumRank && termRank == termRankTmp) { + } else if (!dontSkipCurTermRank && needSumRank && termInf.termRank == termRankTmp) { field = f; - normBm25 = normBm25Tmp; + termInf.bm25Norm = normBm25Tmp; dontSkipCurTermRank = true; } else if (termRankTmp && needSumRank) { ranksInFields.push_back(termRankTmp); @@ -483,44 +482,71 @@ RX_ALWAYS_INLINE void Selecter::calcFieldBoost(const Calculator& bm25Cal } template -AreaHolder Selecter::createAreaFromSubMerge(const MergedIdRelExArea& posInfo) { - AreaHolder area; - if (posInfo.wordPosForChain.empty()) { - return area; +template +void Selecter::insertSubMergeArea(const MergedIdRelGroupArea& posInfo, PosT cur, int prevIndex, AreasInDocument& area) { + PosT last = cur, first = cur; + int indx = int(posInfo.wordPosForChain.size()) - 2; + while (indx >= 0 && prevIndex != -1) { + auto pos = posInfo.wordPosForChain[indx][prevIndex].first; + prevIndex = posInfo.wordPosForChain[indx][prevIndex].second; + first = pos; + indx--; } + assertrx_throw(first.field() == last.field()); + if (area.InsertArea(Area(first.pos(), last.pos() + 1), cur.field(), posInfo.rank, maxAreasInDoc_)) { + area.UpdateRank(float(posInfo.rank)); + } +} - for (const auto& v : posInfo.wordPosForChain.back()) { - IdRelType::PosType last = v.first; - IdRelType::PosType first = v.first; - int indx = int(posInfo.wordPosForChain.size()) - 2; - int prevIndex = v.second; - while (indx >= 0 && prevIndex != -1) { - auto pos = posInfo.wordPosForChain[indx][prevIndex].first; - prevIndex = posInfo.wordPosForChain[indx][prevIndex].second; - first = pos; - indx--; +template +template +void Selecter::insertSubMergeArea(const MergedIdRelGroupArea& posInfo, PosT cur, int prevIndex, + AreasInDocument& area) { + int indx = int(posInfo.wordPosForChain.size()) - 1; + while (indx >= 0 && prevIndex != -1) { + PosT pos = posInfo.wordPosForChain[indx][prevIndex].first; + prevIndex = posInfo.wordPosForChain[indx][prevIndex].second; + AreaDebug::PhraseMode mode = AreaDebug::PhraseMode::None; + if (indx == int(posInfo.wordPosForChain.size()) - 1) { + mode = AreaDebug::PhraseMode::End; + } else if (indx == 0) { + mode = AreaDebug::PhraseMode::Start; } - assertrx(first.field() == last.field()); - if (area.InsertArea(Area(first.pos(), last.pos() + 1), v.first.field(), posInfo.rank, maxAreasInDoc_)) { + if (area.InsertArea(AreaDebug(pos.pos(), pos.pos() + 1, std::move(pos.info), mode), cur.field(), posInfo.rank, -1)) { area.UpdateRank(float(posInfo.rank)); } + + indx--; + } +} + +template +template +AreasInDocument Selecter::createAreaFromSubMerge(const MergedIdRelGroupArea& posInfo) { + AreasInDocument area; + if (posInfo.wordPosForChain.empty()) { + return area; + } + for (const auto& v : posInfo.wordPosForChain.back()) { + insertSubMergeArea(posInfo, v.first, v.second, area); } return area; } template -void Selecter::copyAreas(AreaHolder& subMerged, AreaHolder& merged, int32_t rank) { +template +void Selecter::copyAreas(AreasInDocument& subMerged, AreasInDocument& merged, int32_t rank) { for (size_t f = 0; f < fieldSize_; f++) { auto areas = subMerged.GetAreas(f); if (areas) { - areas->MoveAreas(merged, f, rank, maxAreasInDoc_); + areas->MoveAreas(merged, f, rank, std::is_same_v ? -1 : maxAreasInDoc_); } } } template -template -void Selecter::subMergeLoop(std::vector& subMerged, std::vector& subMergedPos, MergeData& merged, +template +void Selecter::subMergeLoop(MergeType& subMerged, std::vector& subMergedPos, MergeType& merged, std::vector& merged_rd, FtMergeStatuses::Statuses& mergeStatuses, std::vector& idoffsets, std::vector* checkAndOpMerge, const bool hasBeenAnd) { for (size_t subMergedIndex = 0, sz = subMerged.size(); subMergedIndex < sz; subMergedIndex++) { @@ -543,7 +569,7 @@ void Selecter::subMergeLoop(std::vector& subMerged, std::vect for (const auto& p : smPos.posTmp) { mPos.next.Add(p.first); } - merged.vectorAreas.emplace_back(createAreaFromSubMerge(smPos)); + merged.vectorAreas.emplace_back(createAreaFromSubMerge(smPos)); m.areaIndex = merged.vectorAreas.size() - 1; } else { mPos.next = std::move(smPos.posTmp); @@ -565,14 +591,13 @@ void Selecter::subMergeLoop(std::vector& subMerged, std::vect for (const auto& p : subPos.posTmp) { subPos.next.Add(p.first); } - AreaHolder area = createAreaFromSubMerge(subPos); + AreasInDocument area = createAreaFromSubMerge(subPos); int32_t areaIndex = merged[mergedIndex].areaIndex; if (areaIndex != -1 && areaIndex >= int(merged.vectorAreas.size())) { throw Error(errLogic, "FT merge: Incorrect area index %d (areas vector size is %d)", areaIndex, merged.vectorAreas.size()); } - AreaHolder& areaTo = merged.vectorAreas[areaIndex]; - copyAreas(area, areaTo, subMergeInfo.proc); + copyAreas(area, merged.vectorAreas[areaIndex], subMergeInfo.proc); } else { subPos.next = std::move(subPos.posTmp); } @@ -589,9 +614,9 @@ void Selecter::subMergeLoop(std::vector& subMerged, std::vect } template -template +template void Selecter::mergeGroupResult(std::vector& rawResults, size_t from, size_t to, - FtMergeStatuses::Statuses& mergeStatuses, MergeData& merged, std::vector& merged_rd, + FtMergeStatuses::Statuses& mergeStatuses, MergeType& merged, std::vector& merged_rd, OpType op, const bool hasBeenAnd, std::vector& idoffsets, const bool inTransaction, const RdxContext& rdxCtx) { // And - MustPresent @@ -599,14 +624,16 @@ void Selecter::mergeGroupResult(std::vector& rawResul // Not - NotPresent // hasBeenAnd shows whether it is possible to expand the set of documents (if there was already And, then the set of documents is not // expandable) - MergeData subMerged; - std::vector subMergedPositionData; + MergeType subMerged; + std::vector subMergedPositionData; - mergeResultsPart(rawResults, from, to, subMerged, subMergedPositionData, inTransaction, rdxCtx); + mergeResultsPart(rawResults, from, to, subMerged, subMergedPositionData, + inTransaction, rdxCtx); switch (op) { case OpOr: { - subMergeLoop(subMerged, subMergedPositionData, merged, merged_rd, mergeStatuses, idoffsets, nullptr, hasBeenAnd); + subMergeLoop(subMerged, subMergedPositionData, merged, merged_rd, mergeStatuses, + idoffsets, nullptr, hasBeenAnd); break; } case OpAnd: { @@ -614,7 +641,8 @@ void Selecter::mergeGroupResult(std::vector& rawResul // To do this, we intersect the checkAndOpMerge array with the merged array std::vector checkAndOpMerge; checkAndOpMerge.resize(holder_.vdocs_.size(), false); - subMergeLoop(subMerged, subMergedPositionData, merged, merged_rd, mergeStatuses, idoffsets, &checkAndOpMerge, hasBeenAnd); + subMergeLoop(subMerged, subMergedPositionData, merged, merged_rd, mergeStatuses, + idoffsets, &checkAndOpMerge, hasBeenAnd); // intersect checkAndOpMerge with merged for (auto& mergedDocInfo : merged) { if (!checkAndOpMerge[mergedDocInfo.id]) { @@ -639,22 +667,19 @@ void Selecter::mergeGroupResult(std::vector& rawResul } } template -template -void Selecter::addNewTerm(FtMergeStatuses::Statuses& mergeStatuses, MergeData& merged, std::vector& idoffsets, +template +void Selecter::addNewTerm(FtMergeStatuses::Statuses& mergeStatuses, MergeType& merged, std::vector& idoffsets, std::vector& curExists, const IdRelType& relid, index_t rawResIndex, int32_t termRank, int field) { const int vid = relid.Id(); MergeInfo info; info.id = vid; info.proc = termRank; info.field = field; - if (needArea_) { + + if constexpr (std::is_same_v&, decltype(merged)> || std::is_same_v&, decltype(merged)>) { auto& area = merged.vectorAreas.emplace_back(); info.areaIndex = merged.vectorAreas.size() - 1; area.ReserveField(fieldSize_); - for (auto pos : relid.Pos()) { - [[maybe_unused]] bool r = area.AddWord(pos.pos(), pos.field(), termRank, maxAreasInDoc_); - } - area.UpdateRank(termRank); } merged.push_back(std::move(info)); mergeStatuses[vid] = rawResIndex + 1; @@ -665,16 +690,30 @@ void Selecter::addNewTerm(FtMergeStatuses::Statuses& mergeStatuses, Merg } template -void Selecter::addAreas(MergeData& merged, int32_t areaIndex, const IdRelType& relid, int32_t termRank) { - if (needArea_) { - AreaHolder& area = merged.vectorAreas[areaIndex]; - for (auto pos : relid.Pos()) { - if (!area.AddWord(pos.pos(), pos.field(), termRank, maxAreasInDoc_)) { - break; - } +void Selecter::addAreas(AreasInDocument& area, const IdRelType& relid, int32_t termRank, const TermRankInfo& termInf, + const std::wstring& pattern) { + (void)termInf; + (void)pattern; + for (auto pos : relid.Pos()) { + if (!area.AddWord(Area(pos.pos(), pos.pos() + 1), pos.field(), termRank, maxAreasInDoc_)) { + break; } - area.UpdateRank(termRank); } + area.UpdateRank(termRank); +} + +template +void Selecter::addAreas(AreasInDocument& area, const IdRelType& relid, int32_t termRank, const TermRankInfo& termInf, + const std::wstring& pattern) { + (void)termRank; + utf16_to_utf8(pattern, const_cast(termInf.ftDslTerm)); + for (auto pos : relid.Pos()) { + if (!area.AddWord(AreaDebug(pos.pos(), pos.pos() + 1, termInf.ToString(), AreaDebug::PhraseMode::None), pos.field(), + termInf.termRank, -1)) { + break; + } + } + area.UpdateRank(termInf.termRank); } // idf=max(0.2, log((N-M+1)/M)/log(1+N)) @@ -692,9 +731,9 @@ void Selecter::addAreas(MergeData& merged, int32_t areaIndex, const IdRe // docRank=summ(max(subTermRank))*255/allmax // allmax=max(docRank) template -template +template void Selecter::mergeIteration(TextSearchResults& rawRes, index_t rawResIndex, FtMergeStatuses::Statuses& mergeStatuses, - MergeData& merged, std::vector& merged_rd, std::vector& idoffsets, + MergedType& merged, std::vector& merged_rd, std::vector& idoffsets, std::vector& curExists, const bool hasBeenAnd, const bool inTransaction, const RdxContext& rdxCtx) { const auto& vdocs = holder_.vdocs_; @@ -753,7 +792,10 @@ void Selecter::mergeIteration(TextSearchResults& rawRes, index_t rawResI } // Find field with max rank - auto [termRank, field] = calcTermRank(rawRes, bm25, relid, r.proc); + TermRankInfo termInf; + termInf.proc = r.proc; + termInf.pattern = r.pattern; + auto [termRank, field] = calcTermRank(rawRes, bm25, relid, termInf); if (!termRank) { continue; } @@ -764,13 +806,18 @@ void Selecter::mergeIteration(TextSearchResults& rawRes, index_t rawResI if (simple) { // one term if (vidStatus) { MergeInfo& info = merged[idoffsets[vid]]; - addAreas(merged, info.areaIndex, relid, termRank); + if constexpr (std::is_same_v, MergedType> || std::is_same_v, MergedType>) { + addAreas(merged.vectorAreas[info.areaIndex], relid, termRank, termInf, rawRes.term.pattern); + } if (info.proc < static_cast(termRank)) { info.proc = termRank; info.field = field; } } else if (merged.size() < holder_.cfg_->mergeLimit) { // add new addNewTerm(mergeStatuses, merged, idoffsets, curExists, relid, rawResIndex, int32_t(termRank), field); + if constexpr (std::is_same_v, MergedType> || std::is_same_v, MergedType>) { + addAreas(merged.vectorAreas.back(), relid, termRank, termInf, rawRes.term.pattern); + } } } else { if (vidStatus) { @@ -784,8 +831,9 @@ void Selecter::mergeIteration(TextSearchResults& rawRes, index_t rawResI normDist = bound(1.0 / double(std::max(distance, 1)), holder_.cfg_->distanceWeight, holder_.cfg_->distanceBoost); } int finalRank = normDist * termRank; - - addAreas(merged, info.areaIndex, relid, termRank); + if constexpr (std::is_same_v, MergedType> || std::is_same_v, MergedType>) { + addAreas(merged.vectorAreas[info.areaIndex], relid, termRank, termInf, rawRes.term.pattern); + } if (finalRank > curMerged_rd.rank) { info.proc -= curMerged_rd.rank; info.proc += finalRank; @@ -795,6 +843,10 @@ void Selecter::mergeIteration(TextSearchResults& rawRes, index_t rawResI curExists[vid] = true; } else if (merged.size() < holder_.cfg_->mergeLimit && !hasBeenAnd) { // add new addNewTerm(mergeStatuses, merged, idoffsets, curExists, relid, rawResIndex, termRank, field); + MergeInfo& info = merged[idoffsets[vid]]; + if constexpr (std::is_same_v, MergedType> || std::is_same_v, MergedType>) { + addAreas(merged.vectorAreas[info.areaIndex], relid, termRank, termInf, rawRes.term.pattern); + } merged_rd.emplace_back(IdRelType(std::move(relid)), int32_t(termRank), rawRes.term.opts.qpos); } } @@ -802,14 +854,13 @@ void Selecter::mergeIteration(TextSearchResults& rawRes, index_t rawResI } } template + template std::pair Selecter::calcTermRank(const TextSearchResults& rawRes, Calculator bm25Calc, const IdRelType& relid, - int proc) { + TermRankInfo& termInf) { // Find field with max rank int field = 0; - double termRank = 0.0; bool dontSkipCurTermRank = false; - double normBm25 = 0.0; h_vector ranksInFields; for (unsigned long long fieldsMask = relid.UsedFieldsMask(), f = 0; fieldsMask; ++f, fieldsMask >>= 1) { @@ -827,31 +878,31 @@ std::pair Selecter::calcTermRank(const TextSearchResults& r assertrx(f < rawRes.term.opts.fieldsOpts.size()); const auto fboost = rawRes.term.opts.fieldsOpts[f].boost; if (fboost) { - calcFieldBoost(bm25Calc, f, relid, rawRes.term.opts, proc, termRank, normBm25, dontSkipCurTermRank, ranksInFields, field); + calcFieldBoost(bm25Calc, f, relid, rawRes.term.opts, termInf, dontSkipCurTermRank, ranksInFields, field); } } - if (!termRank) { - return std::make_pair(termRank, field); + if (!termInf.termRank) { + return std::make_pair(termInf.termRank, field); } if (holder_.cfg_->summationRanksByFieldsRatio > 0) { boost::sort::pdqsort_branchless(ranksInFields.begin(), ranksInFields.end()); double k = holder_.cfg_->summationRanksByFieldsRatio; for (auto rank : ranksInFields) { - termRank += (k * rank); + termInf.termRank += (k * rank); k *= holder_.cfg_->summationRanksByFieldsRatio; } } - return std::make_pair(termRank, field); + return std::make_pair(termInf.termRank, field); } template -template +template void Selecter::mergeIterationGroup(TextSearchResults& rawRes, index_t rawResIndex, FtMergeStatuses::Statuses& mergeStatuses, - MergeData& merged, std::vector

& merged_rd, std::vector& idoffsets, - std::vector& present, const bool firstTerm, const bool inTransaction, - const RdxContext& rdxCtx) { + MergeType& merged, std::vector& mergedPos, + std::vector& idoffsets, std::vector& present, const bool firstTerm, + const bool inTransaction, const RdxContext& rdxCtx) { const auto& vdocs = holder_.vdocs_; const size_t totalDocsCount = vdocs.size(); @@ -886,7 +937,10 @@ void Selecter::mergeIterationGroup(TextSearchResults& rawRes, index_t ra } // Find field with max rank - auto [termRank, field] = calcTermRank(rawRes, bm25, relid, r.proc); + TermRankInfo termInf; + termInf.proc = r.proc; + termInf.pattern = r.pattern; + auto [termRank, field] = calcTermRank(rawRes, bm25, relid, termInf); if (!termRank) { continue; } @@ -898,8 +952,18 @@ void Selecter::mergeIterationGroup(TextSearchResults& rawRes, index_t ra // match of 2-rd, and next terms if (!firstTerm) { auto& curMerged = merged[idoffsets[vid]]; - auto& curMergedPos = merged_rd[idoffsets[vid]]; - int minDist = curMergedPos.cur.MergeWithDist(relid, rawRes.term.opts.distance, curMergedPos.posTmp); + auto& curMergedPos = mergedPos[idoffsets[vid]]; + int minDist = -1; + if constexpr (isGroupMergeWithAreas()) { + if constexpr (std::is_same_v) { + utf16_to_utf8(rawRes.term.pattern, termInf.ftDslTerm); + minDist = curMergedPos.cur.MergeWithDist(relid, rawRes.term.opts.distance, curMergedPos.posTmp, termInf.ToString()); + } else { + minDist = curMergedPos.cur.MergeWithDist(relid, rawRes.term.opts.distance, curMergedPos.posTmp, ""); + } + } else { + minDist = curMergedPos.cur.MergeWithDist(relid, rawRes.term.opts.distance, curMergedPos.posTmp, ""); + } if (!curMergedPos.posTmp.empty()) { present[vid] = true; double normDist = bound(1.0 / minDist, holder_.cfg_->distanceWeight, holder_.cfg_->distanceBoost); @@ -915,14 +979,21 @@ void Selecter::mergeIterationGroup(TextSearchResults& rawRes, index_t ra } } else { if (vidStatus) { - if constexpr (isGroupMergeWithAreas

()) { - auto& pos = merged_rd[idoffsets[vid]].posTmp; + if constexpr (isGroupMergeWithAreas()) { + auto& pos = mergedPos[idoffsets[vid]].posTmp; pos.reserve(pos.size() + relid.Size()); for (const auto& p : relid.Pos()) { - pos.emplace_back(p, -1); + if constexpr (std::is_same_v) { + pos.emplace_back(p, -1); + } else if constexpr (std::is_same_v) { + utf16_to_utf8(rawRes.term.pattern, termInf.ftDslTerm); + pos.emplace_back(PosTypeDebug(p, termInf.ToString()), -1); + } else { + static_assert(!sizeof(MergedIdRelGroupType), "incorrect MergedIdRelGroupType::TypeTParam type"); + } } } else { - auto& pos = merged_rd[idoffsets[vid]].posTmp; + auto& pos = mergedPos[idoffsets[vid]].posTmp; pos.reserve(pos.Size() + relid.Size()); for (const auto& p : relid.Pos()) { @@ -938,16 +1009,24 @@ void Selecter::mergeIterationGroup(TextSearchResults& rawRes, index_t ra mergeStatuses[vid] = rawResIndex + 1; present[vid] = true; idoffsets[vid] = merged.size() - 1; - if constexpr (isGroupMergeWithAreas

()) { - RVector, 4> posTmp; + if constexpr (isGroupMergeWithAreas()) { + RVector, 4> posTmp; posTmp.reserve(relid.Size()); for (const auto& p : relid.Pos()) { - posTmp.emplace_back(p, -1); + if constexpr (std::is_same_v>) { + posTmp.emplace_back(p, -1); + } else if constexpr (std::is_same_v>) { + utf16_to_utf8(rawRes.term.pattern, termInf.ftDslTerm); + PosTypeDebug pd{p, termInf.ToString()}; + posTmp.emplace_back(pd, -1); + } else { + static_assert(!sizeof(MergedIdRelGroupType), "incorrect MergedIdRelGroupType type"); + } } - merged_rd.emplace_back(IdRelType(std::move(relid)), int(termRank), rawRes.term.opts.qpos, std::move(posTmp)); + mergedPos.emplace_back(IdRelType(std::move(relid)), int(termRank), rawRes.term.opts.qpos, std::move(posTmp)); } else { - merged_rd.emplace_back(IdRelType(std::move(relid)), int(termRank), rawRes.term.opts.qpos); + mergedPos.emplace_back(IdRelType(std::move(relid)), int(termRank), rawRes.term.opts.qpos); } } } @@ -955,7 +1034,7 @@ void Selecter::mergeIterationGroup(TextSearchResults& rawRes, index_t ra } for (size_t mergedIndex = 0; mergedIndex < merged.size(); mergedIndex++) { auto& mergedInfo = merged[mergedIndex]; - auto& mergedPosInfo = merged_rd[mergedIndex]; + auto& mergedPosInfo = mergedPos[mergedIndex]; if (mergedPosInfo.posTmp.empty()) { mergedInfo.proc = 0; mergeStatuses[mergedInfo.id] = 0; @@ -964,7 +1043,7 @@ void Selecter::mergeIterationGroup(TextSearchResults& rawRes, index_t ra mergedPosInfo.rank = 0; continue; } - if constexpr (isGroupMerge

()) { + if constexpr (isGroupMerge()) { mergedPosInfo.posTmp.SortAndUnique(); mergedPosInfo.cur = std::move(mergedPosInfo.posTmp); mergedPosInfo.next.Clear(); @@ -972,9 +1051,10 @@ void Selecter::mergeIterationGroup(TextSearchResults& rawRes, index_t ra mergedPosInfo.rank = 0; } else { auto& posTmp = mergedPosInfo.posTmp; - boost::sort::pdqsort_branchless(posTmp.begin(), posTmp.end(), - [](const std::pair& l, - const std::pair& r) noexcept { return l.first < r.first; }); + boost::sort::pdqsort_branchless( + posTmp.begin(), posTmp.end(), + [](const std::pair& l, + const std::pair& r) noexcept { return l.first < r.first; }); auto last = std::unique(posTmp.begin(), posTmp.end()); posTmp.resize(last - posTmp.begin()); @@ -992,9 +1072,9 @@ void Selecter::mergeIterationGroup(TextSearchResults& rawRes, index_t ra } template -template -void Selecter::mergeResultsPart(std::vector& rawResults, size_t from, size_t to, MergeData& merged, - std::vector& mergedPos, const bool inTransaction, const RdxContext& rdxCtx) { +template +void Selecter::mergeResultsPart(std::vector& rawResults, size_t from, size_t to, MergeType& merged, + std::vector& mergedPos, const bool inTransaction, const RdxContext& rdxCtx) { // Current implementation supports OpAnd only assertrx_throw(to <= rawResults.size()); FtMergeStatuses::Statuses mergeStatuses; @@ -1013,8 +1093,8 @@ void Selecter::mergeResultsPart(std::vector& rawResul std::vector exists; bool firstTerm = true; for (size_t i = from; i < to; ++i) { - mergeIterationGroup(rawResults[i], i, mergeStatuses, merged, mergedPos, idoffsets, exists, firstTerm, - inTransaction, rdxCtx); + mergeIterationGroup(rawResults[i], i, mergeStatuses, merged, mergedPos, + idoffsets, exists, firstTerm, inTransaction, rdxCtx); firstTerm = false; // set proc=0 (exclude) for document not containing term for (auto& info : merged) { @@ -1282,13 +1362,13 @@ bool Selecter::TyposHandler::isWordFitMaxLettPerm(const std::string_view } template -template -MergeData Selecter::mergeResults(std::vector&& rawResults, size_t maxMergedSize, - const std::vector& synonymsBounds, bool inTransaction, FtSortType ftSortType, - FtMergeStatuses::Statuses&& mergeStatuses, const RdxContext& rdxCtx) { +template +MergedType Selecter::mergeResults(std::vector&& rawResults, size_t maxMergedSize, + const std::vector& synonymsBounds, bool inTransaction, FtSortType ftSortType, + FtMergeStatuses::Statuses&& mergeStatuses, const RdxContext& rdxCtx) { const auto& vdocs = holder_.vdocs_; - MergeData merged; + MergedType merged; if (!rawResults.size() || !vdocs.size()) { return merged; } @@ -1322,12 +1402,15 @@ MergeData Selecter::mergeResults(std::vector&& rawRes rawResults[k].term.opts.op = OpAnd; k++; } - if (needArea_) { - mergeGroupResult(rawResults, i, k, mergeStatuses, merged, merged_rd, op, hasBeenAnd, idoffsets, - inTransaction, rdxCtx); + if constexpr (std::is_same_v>) { + mergeGroupResult, Bm25T, MergedOffsetT, MergedType>( + rawResults, i, k, mergeStatuses, merged, merged_rd, op, hasBeenAnd, idoffsets, inTransaction, rdxCtx); + } else if constexpr (std::is_same_v>) { + mergeGroupResult, Bm25T, MergedOffsetT, MergedType>( + rawResults, i, k, mergeStatuses, merged, merged_rd, op, hasBeenAnd, idoffsets, inTransaction, rdxCtx); } else { - mergeGroupResult(rawResults, i, k, mergeStatuses, merged, merged_rd, op, hasBeenAnd, idoffsets, - inTransaction, rdxCtx); + mergeGroupResult(rawResults, i, k, mergeStatuses, merged, merged_rd, op, + hasBeenAnd, idoffsets, inTransaction, rdxCtx); } if (op == OpAnd) { hasBeenAnd = true; @@ -1441,14 +1524,37 @@ void Selecter::printVariants(const FtSelectContext& ctx, const TextSearc } template class Selecter; -template MergeData Selecter::Process(FtDSLQuery&&, bool, FtSortType, FtMergeStatuses::Statuses&&, +template MergeDataBase Selecter::Process(FtDSLQuery&&, bool, FtSortType, + FtMergeStatuses::Statuses&&, + const RdxContext&); +template MergeData Selecter::Process>(FtDSLQuery&&, bool, FtSortType, + FtMergeStatuses::Statuses&&, + const RdxContext&); +template MergeData Selecter::Process>(FtDSLQuery&&, bool, + FtSortType, + FtMergeStatuses::Statuses&&, + const RdxContext&); + +template MergeDataBase Selecter::Process(FtDSLQuery&&, bool, FtSortType, + FtMergeStatuses::Statuses&&, const RdxContext&); +template MergeData Selecter::Process(FtDSLQuery&&, bool, FtSortType, + FtMergeStatuses::Statuses&&, const RdxContext&); +template MergeData Selecter::Process(FtDSLQuery&&, bool, FtSortType, + FtMergeStatuses::Statuses&&, const RdxContext&); + +template class Selecter; +template MergeDataBase Selecter::Process(FtDSLQuery&&, bool, FtSortType, FtMergeStatuses::Statuses&&, + const RdxContext&); +template MergeData Selecter::Process(FtDSLQuery&&, bool, FtSortType, FtMergeStatuses::Statuses&&, const RdxContext&); -template MergeData Selecter::Process(FtDSLQuery&&, bool, FtSortType, FtMergeStatuses::Statuses&&, +template MergeData Selecter::Process(FtDSLQuery&&, bool, FtSortType, + FtMergeStatuses::Statuses&&, const RdxContext&); + +template MergeDataBase Selecter::Process(FtDSLQuery&&, bool, FtSortType, FtMergeStatuses::Statuses&&, + const RdxContext&); +template MergeData Selecter::Process(FtDSLQuery&&, bool, FtSortType, FtMergeStatuses::Statuses&&, const RdxContext&); -template class Selecter; -template MergeData Selecter::Process(FtDSLQuery&&, bool, FtSortType, FtMergeStatuses::Statuses&&, - const RdxContext&); -template MergeData Selecter::Process(FtDSLQuery&&, bool, FtSortType, FtMergeStatuses::Statuses&&, - const RdxContext&); +template MergeData Selecter::Process(FtDSLQuery&&, bool, FtSortType, + FtMergeStatuses::Statuses&&, const RdxContext&); } // namespace reindexer diff --git a/cpp_src/core/ft/ft_fast/selecter.h b/cpp_src/core/ft/ft_fast/selecter.h index 0e159f484..0a7b555fe 100644 --- a/cpp_src/core/ft/ft_fast/selecter.h +++ b/cpp_src/core/ft/ft_fast/selecter.h @@ -6,6 +6,7 @@ namespace reindexer { +// Final information about found document struct MergeInfo { IdType id; // Virtual id of merged document (index in vdocs) int32_t proc; // Rank of document @@ -13,9 +14,15 @@ struct MergeInfo { int8_t field; // Field index, where was match }; -struct MergeData : public std::vector { +struct MergeDataBase : public std::vector { + virtual ~MergeDataBase() {} int maxRank = 0; - std::vector vectorAreas; +}; + +template +struct MergeData : public MergeDataBase { + using AT = AreaType; + std::vector> vectorAreas; }; template @@ -23,10 +30,10 @@ class Selecter { typedef fast_hash_map, WordIdTypeHash, WordIdTypeEqual, WordIdTypeLess> FoundWordsType; public: - Selecter(DataHolder& holder, size_t fieldSize, bool needArea, int maxAreasInDoc) - : holder_(holder), fieldSize_(fieldSize), needArea_(needArea), maxAreasInDoc_(maxAreasInDoc) {} + Selecter(DataHolder& holder, size_t fieldSize, int maxAreasInDoc) + : holder_(holder), fieldSize_(fieldSize), maxAreasInDoc_(maxAreasInDoc) {} - // Intermediate information about found document in current merge step. Used only for queries with 2 or more terms + // Intermediate information about document found at current merge step. Used only for queries with 2 or more terms struct MergedIdRel { explicit MergedIdRel(IdRelType&& c, int r, int q) : next(std::move(c)), rank(r), qpos(q) {} explicit MergedIdRel(int r, int q) : rank(r), qpos(q) {} @@ -37,24 +44,26 @@ class Selecter { int32_t qpos; // Position in query }; - struct MergedIdRelEx : public MergedIdRel { - explicit MergedIdRelEx(IdRelType&& c, int r, int q) : MergedIdRel(r, q), posTmp(std::move(c)) {} - MergedIdRelEx(MergedIdRelEx&&) = default; - IdRelType posTmp; // For group only. Collect all positions for subpatterns and the index in the vector with which we merged + struct MergedIdRelGroup : public MergedIdRel { + explicit MergedIdRelGroup(IdRelType&& c, int r, int q) : MergedIdRel(r, q), posTmp(std::move(c)) {} + MergedIdRelGroup(MergedIdRelGroup&&) = default; + IdRelType posTmp; // Group only. Collect all positions for subpatterns and index into vector we merged with }; - struct MergedIdRelExArea : public MergedIdRel { - MergedIdRelExArea(IdRelType&& c, int r, int q, RVector, 4>&& p) + template + struct MergedIdRelGroupArea : public MergedIdRel { + using TypeTParam = PosT; + MergedIdRelGroupArea(IdRelType&& c, int r, int q, RVector, 4>&& p) : MergedIdRel(std::move(c), r, q), posTmp(std::move(p)) {} - MergedIdRelExArea(MergedIdRelExArea&&) = default; + MergedIdRelGroupArea(MergedIdRelGroupArea&&) = default; - RVector, 4> + RVector, 4> posTmp; // For group only. Collect all positions for subpatterns and the index in the vector with which we merged - h_vector, 4>, 2> wordPosForChain; + RVector, 4>, 2> wordPosForChain; }; - template - MergeData Process(FtDSLQuery&& dsl, bool inTransaction, FtSortType ftSortType, FtMergeStatuses::Statuses&& mergeStatuses, + template + MergeType Process(FtDSLQuery&& dsl, bool inTransaction, FtSortType ftSortType, FtMergeStatuses::Statuses&& mergeStatuses, const RdxContext&); private: @@ -65,6 +74,24 @@ class Selecter { int16_t wordLen; }; + struct TermRankInfo { + int32_t termRank = 0; + double bm25Norm = 0.0; + double termLenBoost = 0.0; + double positionRank = 0.0; + double normDist = 0.0; + double proc = 0.0; + double fullMatchBoost = 0.0; + std::string_view pattern; + std::string ftDslTerm; + + std::string ToString() const { + return fmt::format( + R"json({{term_rank:{}, term:{}, pattern:{}, bm25_norm:{}, term_len_boost:{}, position_rank:{}, norm_dist:{}, proc:{}, full_match_boost:{}}} )json", + termRank, ftDslTerm, pattern, bm25Norm, termLenBoost, positionRank, normDist, proc, fullMatchBoost); + } + }; + struct FtVariantEntry { FtVariantEntry() = default; FtVariantEntry(std::string p, FtDslOpts o, int pr, int c) : pattern{std::move(p)}, opts{std::move(o)}, proc{pr}, charsCount{c} {} @@ -178,52 +205,69 @@ class Selecter { std::wstring foundWordUTF16_; }; - template - MergeData mergeResults(std::vector&& rawResults, size_t maxMergedSize, const std::vector& synonymsBounds, + template + MergeType mergeResults(std::vector&& rawResults, size_t totalORVids, const std::vector& synonymsBounds, bool inTransaction, FtSortType ftSortType, FtMergeStatuses::Statuses&& mergeStatuses, const RdxContext&); - template - void mergeIteration(TextSearchResults& rawRes, index_t rawResIndex, FtMergeStatuses::Statuses& mergeStatuses, MergeData& merged, + template + void mergeIteration(TextSearchResults& rawRes, index_t rawResIndex, FtMergeStatuses::Statuses& mergeStatuses, MergeType& merged, std::vector& merged_rd, std::vector& idoffsets, std::vector& curExists, const bool hasBeenAnd, const bool inTransaction, const RdxContext&); - template - void mergeIterationGroup(TextSearchResults& rawRes, index_t rawResIndex, FtMergeStatuses::Statuses& mergeStatuses, MergeData& merged, - std::vector

& merged_rd, std::vector& idoffsets, std::vector& present, + template + void mergeIterationGroup(TextSearchResults& rawRes, index_t rawResIndex, FtMergeStatuses::Statuses& mergeStatuses, MergeType& merged, + std::vector& mergedPos, std::vector& idoffsets, std::vector& present, const bool firstTerm, const bool inTransaction, const RdxContext& rdxCtx); - template + template void mergeGroupResult(std::vector& rawResults, size_t from, size_t to, FtMergeStatuses::Statuses& mergeStatuses, - MergeData& merged, std::vector& merged_rd, OpType op, const bool hasBeenAnd, + MergeType& merged, std::vector& merged_rd, OpType op, const bool hasBeenAnd, std::vector& idoffsets, const bool inTransaction, const RdxContext& rdxCtx); - template - void mergeResultsPart(std::vector& rawResults, size_t from, size_t to, MergeData& merged, + template + void mergeResultsPart(std::vector& rawResults, size_t from, size_t to, MergeType& merged, std::vector& mergedPos, const bool inTransaction, const RdxContext& rdxCtx); - AreaHolder createAreaFromSubMerge(const MergedIdRelExArea& posInfo); - void copyAreas(AreaHolder& subMerged, AreaHolder& merged, int32_t rank); - template - void subMergeLoop(std::vector& subMerged, std::vector& subMergedPos, MergeData& merged, - std::vector& merged_rd, FtMergeStatuses::Statuses& mergeStatuses, std::vector& idoffsets, - std::vector* checkAndOpMerge, const bool hasBeenAnd); + template + AreasInDocument createAreaFromSubMerge(const MergedIdRelGroupArea& posInfo); + + template + void insertSubMergeArea(const MergedIdRelGroupArea& posInfo, PosT cur, int prevIndex, AreasInDocument& area); + + template + void insertSubMergeArea(const MergedIdRelGroupArea& posInfo, PosT cur, int prevIndex, AreasInDocument& area); + + template + void copyAreas(AreasInDocument& subMerged, AreasInDocument& merged, int32_t rank); + + template + void subMergeLoop(MergeType& subMerged, std::vector& subMergedPos, MergeType& merged, std::vector& merged_rd, + FtMergeStatuses::Statuses& mergeStatuses, std::vector& idoffsets, std::vector* checkAndOpMerge, + const bool hasBeenAnd); template - void calcFieldBoost(const Calculator& bm25Calc, unsigned long long f, const IdRelType& relid, const FtDslOpts& opts, int termProc, - double& termRank, double& normBm25, bool& dontSkipCurTermRank, h_vector& ranksInFields, int& field); + void calcFieldBoost(const Calculator& bm25Calc, unsigned long long f, const IdRelType& relid, const FtDslOpts& opts, + TermRankInfo& termInf, bool& dontSkipCurTermRank, h_vector& ranksInFields, int& field); + template - std::pair calcTermRank(const TextSearchResults& rawRes, Calculator c, const IdRelType& relid, int proc); + std::pair calcTermRank(const TextSearchResults& rawRes, Calculator c, const IdRelType& relid, TermRankInfo& termInf); - template - void addNewTerm(FtMergeStatuses::Statuses& mergeStatuses, MergeData& merged, std::vector& idoffsets, + template + void addNewTerm(FtMergeStatuses::Statuses& mergeStatuses, MergeType& merged, std::vector& idoffsets, std::vector& curExists, const IdRelType& relid, index_t rawResIndex, int32_t termRank, int field); - void addAreas(MergeData& merged, int32_t areaIndex, const IdRelType& relid, int32_t termRank); + void addAreas(AreasInDocument& area, const IdRelType& relid, int32_t termRank, const TermRankInfo& termInf, + const std::wstring& pattern); + void addAreas(AreasInDocument& area, const IdRelType& relid, int32_t termRank, const TermRankInfo& termInf, + const std::wstring& pattern); + + template + constexpr static bool IsOneOf = (... || std::is_same_v); template static constexpr bool isSingleTermMerge() noexcept { static_assert( - std::is_same_v || std::is_same_v || std::is_same_v, + IsOneOf, MergedIdRelGroupArea, MergedIdRel>, "unsupported type for mergeIteration"); return std::is_same_v; } @@ -231,21 +275,22 @@ class Selecter { template static constexpr bool isGroupMerge() noexcept { static_assert( - std::is_same_v || std::is_same_v || std::is_same_v, + IsOneOf, MergedIdRelGroupArea, MergedIdRel>, "unsupported type for mergeIteration"); - return std::is_same_v; + return std::is_same_v; } template static constexpr bool isGroupMergeWithAreas() noexcept { static_assert( - std::is_same_v || std::is_same_v || std::is_same_v, + IsOneOf, MergedIdRelGroupArea, MergedIdRel>, "unsupported type for mergeIteration"); - return std::is_same_v; + return std::is_same_v> || + std::is_same_v>; } - template - MergeData mergeResultsBmType(std::vector&& results, size_t totalORVids, const std::vector& synonymsBounds, + template + MergeType mergeResultsBmType(std::vector&& results, size_t totalORVids, const std::vector& synonymsBounds, bool inTransaction, FtSortType ftSortType, FtMergeStatuses::Statuses&& mergeStatuses, const RdxContext& rdxCtx); @@ -263,7 +308,6 @@ class Selecter { DataHolder& holder_; size_t fieldSize_; - const bool needArea_; int maxAreasInDoc_; }; diff --git a/cpp_src/core/ft/ftsetcashe.h b/cpp_src/core/ft/ftsetcashe.h index 6d3802baa..ed1ea8f74 100644 --- a/cpp_src/core/ft/ftsetcashe.h +++ b/cpp_src/core/ft/ftsetcashe.h @@ -8,12 +8,11 @@ namespace reindexer { struct FtIdSetCacheVal { FtIdSetCacheVal() = default; FtIdSetCacheVal(IdSet::Ptr&& i) noexcept : ids(std::move(i)) {} - FtIdSetCacheVal(IdSet::Ptr&& i, FtCtx::Data::Ptr&& c) noexcept : ids(std::move(i)), ctx(std::move(c)) {} - + FtIdSetCacheVal(IdSet::Ptr&& i, FtCtxData::Ptr&& c) noexcept : ids(std::move(i)), ctx(std::move(c)) {} size_t Size() const noexcept { return ids ? (sizeof(*ids.get()) + ids->heap_size()) : 0; } IdSet::Ptr ids; - FtCtx::Data::Ptr ctx; + FtCtxData::Ptr ctx; }; using FtIdSetCache = LRUCache; diff --git a/cpp_src/core/ft/idrelset.cc b/cpp_src/core/ft/idrelset.cc index c1aeaf9e8..74cc28de9 100644 --- a/cpp_src/core/ft/idrelset.cc +++ b/cpp_src/core/ft/idrelset.cc @@ -76,4 +76,58 @@ int IdRelType::MinPositionInField(int field) const noexcept { return res; } +// RVector, 4> +// IdRelType +// RVector, 4> +template +int IdRelType::MergeWithDist(const IdRelType& newWordPos, unsigned int dist, PosTypeT& res, [[maybe_unused]] const std::string& inf) const { + unsigned int minDist = std::numeric_limits::max(); + auto rightIt = newWordPos.pos_.begin(); + const auto leftEnd = pos_.end(); + const auto rightEnd = newWordPos.pos_.end(); + for (auto leftIt = pos_.begin(); leftIt != leftEnd; ++leftIt) { + while (rightIt != rightEnd && rightIt->fpos < leftIt->fpos) { + ++rightIt; + } + // here right pos > left pos + if (rightIt == rightEnd) { + break; + } + if (rightIt->field() != leftIt->field()) { + continue; + } + + auto leftItNext = leftIt + 1; + uint32_t leftNextPos = std::numeric_limits::max(); + if (leftItNext != leftEnd) { + leftNextPos = leftItNext->pos(); + } + + while (rightIt != rightEnd && rightIt->field() == leftIt->field() && uint32_t(rightIt->pos()) < leftNextPos && + rightIt->fpos - leftIt->fpos <= dist) { + minDist = std::min(rightIt->fpos - leftIt->fpos, minDist); + if constexpr (std::is_same_v) { + res.Add(*rightIt); + } else if constexpr (std::is_same_v, 4>>) { + res.emplace_back(*rightIt, leftIt - pos_.begin()); + } else if constexpr (std::is_same_v, 4>>) { + res.emplace_back(PosTypeDebug{*rightIt, inf}, leftIt - pos_.begin()); + } else { + static_assert(!sizeof(PosTypeT), "incorrect PosType type "); + } + ++rightIt; + } + } + return minDist; +} + +template int IdRelType::MergeWithDist(const IdRelType& newWordPos, unsigned int dist, IdRelType& res, + const std::string& inf) const; +template int IdRelType::MergeWithDist, 4>>(const IdRelType& newWordPos, unsigned int dist, + RVector, 4>& res, + const std::string& inf) const; +template int IdRelType::MergeWithDist, 4>>(const IdRelType& newWordPos, unsigned int dist, + RVector, 4>& res, + const std::string&) const; + } // namespace reindexer diff --git a/cpp_src/core/ft/idrelset.h b/cpp_src/core/ft/idrelset.h index 05ed10950..fc967e460 100644 --- a/cpp_src/core/ft/idrelset.h +++ b/cpp_src/core/ft/idrelset.h @@ -48,46 +48,8 @@ class IdRelType { uint32_t fpos; }; - template - int MergeWithDist(const IdRelType& newWordPos, unsigned int dist, PosType& res) const { - int minDist = INT_MAX; - auto rightIt = newWordPos.pos_.begin(); - const auto leftEnd = pos_.end(); - const auto rightEnd = newWordPos.pos_.end(); - for (auto leftIt = pos_.begin(); leftIt != leftEnd; ++leftIt) { - while (rightIt != rightEnd && rightIt->fpos < leftIt->fpos) { - ++rightIt; - } - // here right pos > left pos - if (rightIt == rightEnd) { - break; - } - if (rightIt->field() != leftIt->field()) { - continue; - } - - auto leftItNext = leftIt + 1; - uint32_t leftNextPos = std::numeric_limits::max(); - if (leftItNext != leftEnd) { - leftNextPos = leftItNext->pos(); - } - - while (rightIt != rightEnd && rightIt->field() == leftIt->field() && uint32_t(rightIt->pos()) < leftNextPos && - rightIt->fpos - leftIt->fpos <= dist) { - int d = rightIt->fpos - leftIt->fpos; - if (d < minDist) { - minDist = d; - } - if constexpr (std::is_same_v) { - res.Add(*rightIt); - } else { - res.emplace_back(*rightIt, leftIt - pos_.begin()); - } - ++rightIt; - } - } - return minDist; - } + template + int MergeWithDist(const IdRelType& newWordPos, unsigned int dist, PosTypeT& res, const std::string& inf) const; void Add(int pos, int field) { assertrx_throw(0 <= field && field <= kMaxFtCompositeFields); @@ -141,6 +103,13 @@ class IdRelType { VDocIdType id_ = 0; // index of the document in which the word occurs }; +struct PosTypeDebug : public IdRelType::PosType { + PosTypeDebug() = default; + explicit PosTypeDebug(const IdRelType::PosType& pos, const std::string& inf) : IdRelType::PosType(pos), info(inf) {} + explicit PosTypeDebug(const IdRelType::PosType& pos, std::string&& inf) noexcept : IdRelType::PosType(pos), info(std::move(inf)) {} + std::string info; +}; + class IdRelSet : public std::vector { public: int Add(VDocIdType id, int pos, int field) { diff --git a/cpp_src/core/ft/usingcontainer.h b/cpp_src/core/ft/usingcontainer.h index 143376670..4edfe1549 100644 --- a/cpp_src/core/ft/usingcontainer.h +++ b/cpp_src/core/ft/usingcontainer.h @@ -11,11 +11,24 @@ namespace reindexer { template class RVector : public std::vector { public: + typedef unsigned size_type; + using std::vector::vector; template void clear() noexcept { std::vector::clear(); } + + size_t heap_size() { return std::vector::capacity() * sizeof(T); } + + static constexpr size_type max_size() noexcept { return std::numeric_limits::max() >> 1; } + + void grow(size_type sz) { + size_type cap = std::vector::capacity(); + if (sz > cap) { + std::vector::reserve(std::max(sz, std::min(max_size(), cap * 2))); + } + } }; #else template diff --git a/cpp_src/core/idset.h b/cpp_src/core/idset.h index d6235ac90..167370cc6 100644 --- a/cpp_src/core/idset.h +++ b/cpp_src/core/idset.h @@ -4,6 +4,7 @@ #include #include #include +#include "core/ft/usingcontainer.h" #include "cpp-btree/btree_set.h" #include "estl/h_vector.h" #include "estl/intrusive_ptr.h" @@ -12,7 +13,7 @@ namespace reindexer { -using base_idset = h_vector; +using base_idset = RVector; using base_idsetset = btree::btree_set; class IdSetPlain : protected base_idset { diff --git a/cpp_src/core/index/indextext/fastindextext.cc b/cpp_src/core/index/indextext/fastindextext.cc index fdded3b1f..75dac5450 100644 --- a/cpp_src/core/index/indextext/fastindextext.cc +++ b/cpp_src/core/index/indextext/fastindextext.cc @@ -97,8 +97,8 @@ void FastIndexText::Delete(const Variant& key, IdType id, StringsHolder& strH this->holder_->vdocs_[keyIt->second.VDocID()].keyEntry = nullptr; } if constexpr (is_str_map_v) { - this->idx_map.template erase>( - keyIt, {strHolder, this->KeyType().template Is() && this->opts_.GetCollateMode() == CollateNone}); + this->idx_map.template erase>(keyIt, + {strHolder, this->KeyType().template Is()}); } else { static_assert(is_payload_map_v); this->idx_map.template erase(keyIt, strHolder); @@ -106,9 +106,6 @@ void FastIndexText::Delete(const Variant& key, IdType id, StringsHolder& strH } else { this->addMemStat(keyIt); } - if (this->KeyType().template Is() && this->opts_.GetCollateMode() != CollateNone) { - IndexStore>::Delete(key, id, strHolder, clearCache); - } if (this->cache_ft_) { this->cache_ft_->Clear(); } @@ -125,8 +122,9 @@ IndexMemStat FastIndexText::GetMemStat(const RdxContext& ctx) { return ret; } template -MergeData::iterator FastIndexText::unstableRemoveIf(MergeData& md, int minRelevancy, double scalingFactor, size_t& releventDocs, - int& cnt) { +template +typename MergeType::iterator FastIndexText::unstableRemoveIf(MergeType& md, int minRelevancy, double scalingFactor, size_t& releventDocs, + int& cnt) { if (md.empty()) { return md.begin(); } @@ -138,14 +136,11 @@ MergeData::iterator FastIndexText::unstableRemoveIf(MergeData& md, int minRel if (first == last) { return first; } - auto& vdoc = holder.vdocs_[first->id]; - if (!vdoc.keyEntry) { - break; - } first->proc *= scalingFactor; if (first->proc < minRelevancy) { break; } + auto& vdoc = holder.vdocs_[first->id]; assertrx_throw(!vdoc.keyEntry->Unsorted().empty()); cnt += vdoc.keyEntry->Sorted(0).size(); ++releventDocs; @@ -157,9 +152,6 @@ MergeData::iterator FastIndexText::unstableRemoveIf(MergeData& md, int minRel if (first == last) { return first; } - if (!holder.vdocs_[last->id].keyEntry) { - continue; - } last->proc *= scalingFactor; if (last->proc >= minRelevancy) { break; @@ -176,53 +168,20 @@ MergeData::iterator FastIndexText::unstableRemoveIf(MergeData& md, int minRel } template -IdSet::Ptr FastIndexText::Select(FtCtx::Ptr fctx, FtDSLQuery&& dsl, bool inTransaction, FtSortType ftSortType, - FtMergeStatuses&& statuses, FtUseExternStatuses useExternSt, const RdxContext& rdxCtx) { - fctx->GetData()->extraWordSymbols_ = this->getConfig()->extraWordSymbols; - fctx->GetData()->isWordPositions_ = true; - - MergeData mergeData; - switch (holder_->cfg_->optimization) { - case FtFastConfig::Optimization::Memory: { - DataHolder* d = dynamic_cast*>(holder_.get()); - assertrx_throw(d); - Selecter selecter{*d, this->Fields().size(), fctx->NeedArea(), holder_->cfg_->maxAreasInDoc}; - if (useExternSt == FtUseExternStatuses::No) { - mergeData = selecter.Process(std::move(dsl), inTransaction, ftSortType, - std::move(statuses.statuses), rdxCtx); - } else { - mergeData = selecter.Process(std::move(dsl), inTransaction, ftSortType, - std::move(statuses.statuses), rdxCtx); - } - break; - } - case FtFastConfig::Optimization::CPU: { - DataHolder* d = dynamic_cast*>(holder_.get()); - assertrx_throw(d); - Selecter selecter{*d, this->Fields().size(), fctx->NeedArea(), holder_->cfg_->maxAreasInDoc}; - if (useExternSt == FtUseExternStatuses::No) { - mergeData = selecter.Process(std::move(dsl), inTransaction, ftSortType, - std::move(statuses.statuses), rdxCtx); - } else { - mergeData = selecter.Process(std::move(dsl), inTransaction, ftSortType, - std::move(statuses.statuses), rdxCtx); - } - break; - } - default: - assertrx_throw(0); - } - +template +IdSet::Ptr FastIndexText::afterSelect(FtCtx& fctx, MergeType&& mergeData, FtSortType ftSortType, FtMergeStatuses&& statuses, + FtUseExternStatuses useExternSt) { // convert vids(uniq documents id) to ids (real ids) IdSet::Ptr mergedIds = make_intrusive>(); - auto& holder = *this->holder_; + auto& holder = *this->holder_; if (mergeData.empty()) { return mergedIds; } int cnt = 0; const double scalingFactor = mergeData.maxRank > 255 ? 255.0 / mergeData.maxRank : 1.0; const int minRelevancy = getConfig()->minRelevancy * 100 * scalingFactor; + size_t releventDocs = 0; switch (ftSortType) { case FtSortType::RankAndID: { @@ -233,14 +192,10 @@ IdSet::Ptr FastIndexText::Select(FtCtx::Ptr fctx, FtDSLQuery&& dsl, bool inTr case FtSortType::RankOnly: { for (auto& vid : mergeData) { auto& vdoc = holder.vdocs_[vid.id]; - if (!vdoc.keyEntry) { - continue; - } vid.proc *= scalingFactor; if (vid.proc <= minRelevancy) { break; } - assertrx_throw(!vdoc.keyEntry->Unsorted().empty()); cnt += vdoc.keyEntry->Sorted(0).size(); ++releventDocs; @@ -253,47 +208,47 @@ IdSet::Ptr FastIndexText::Select(FtCtx::Ptr fctx, FtDSLQuery&& dsl, bool inTr } mergedIds->reserve(cnt); - fctx->Reserve(cnt); - if (!fctx->NeedArea()) { + if constexpr (std::is_same_v) { if (useExternSt == FtUseExternStatuses::No) { appendMergedIds(mergeData, releventDocs, [&fctx, &mergedIds](IdSetCRef::iterator ebegin, IdSetCRef::iterator eend, const MergeInfo& vid) { - fctx->Add(ebegin, eend, vid.proc); + fctx.Add(ebegin, eend, vid.proc); mergedIds->Append(ebegin, eend, IdSet::Unordered); }); } else { appendMergedIds(mergeData, releventDocs, [&fctx, &mergedIds, &statuses](IdSetCRef::iterator ebegin, IdSetCRef::iterator eend, const MergeInfo& vid) { - fctx->Add(ebegin, eend, vid.proc, statuses.rowIds); + fctx.Add(ebegin, eend, vid.proc, statuses.rowIds); mergedIds->Append(ebegin, eend, statuses.rowIds, IdSet::Unordered); }); } - } else { + } else if constexpr (std::is_same_v, MergeType> || std::is_same_v, MergeType>) { if (useExternSt == FtUseExternStatuses::No) { appendMergedIds(mergeData, releventDocs, [&fctx, &mergedIds, &mergeData](IdSetCRef::iterator ebegin, IdSetCRef::iterator eend, const MergeInfo& vid) { - assertrx_throw(vid.areaIndex != std::numeric_limits::max()); - fctx->Add(ebegin, eend, vid.proc, std::move(mergeData.vectorAreas[vid.areaIndex])); + fctx.Add(ebegin, eend, vid.proc, std::move(mergeData.vectorAreas[vid.areaIndex])); mergedIds->Append(ebegin, eend, IdSet::Unordered); }); + } else { appendMergedIds( mergeData, releventDocs, - [&fctx, &mergedIds, &mergeData, &statuses](IdSetCRef::iterator ebegin, IdSetCRef::iterator eend, const MergeInfo& vid) { - assertrx_throw(vid.areaIndex != std::numeric_limits::max()); - fctx->Add(ebegin, eend, vid.proc, statuses.rowIds, std::move(mergeData.vectorAreas[vid.areaIndex])); + [&fctx, &mergedIds, &statuses, &mergeData](IdSetCRef::iterator ebegin, IdSetCRef::iterator eend, const MergeInfo& vid) { + fctx.Add(ebegin, eend, vid.proc, statuses.rowIds, std::move(mergeData.vectorAreas[vid.areaIndex])); mergedIds->Append(ebegin, eend, statuses.rowIds, IdSet::Unordered); }); } + } else { + static_assert(!sizeof(MergeType), "incorrect MergeType"); } + if rx_unlikely (getConfig()->logLevel >= LogInfo) { logPrintf(LogInfo, "Total merge out: %d ids", mergedIds->size()); - std::string str; - for (size_t i = 0; i < fctx->Size();) { + for (size_t i = 0; i < fctx.Size();) { size_t j = i; - for (; j < fctx->Size() && fctx->Proc(i) == fctx->Proc(j); j++); - str += std::to_string(fctx->Proc(i)) + "%"; + for (; j < fctx.Size() && fctx.Proc(i) == fctx.Proc(j); j++); + str += std::to_string(fctx.Proc(i)) + "%"; if (j - i > 1) { str += "("; str += std::to_string(j - i); @@ -302,9 +257,9 @@ IdSet::Ptr FastIndexText::Select(FtCtx::Ptr fctx, FtDSLQuery&& dsl, bool inTr str += " "; i = j; } - logPrintf(LogInfo, "Relevancy(%d): %s", fctx->Size(), str); + logPrintf(LogInfo, "Relevancy(%d): %s", fctx.Size(), str); } - assertrx_throw(mergedIds->size() == fctx->Size()); + assertrx_throw(mergedIds->size() == fctx.Size()); if (ftSortType == FtSortType::RankAndID) { std::vector sortIds; size_t nItems = mergedIds->size(); @@ -312,7 +267,7 @@ IdSet::Ptr FastIndexText::Select(FtCtx::Ptr fctx, FtDSLQuery&& dsl, bool inTr for (size_t i = 0; i < nItems; i++) { sortIds.emplace_back(i); } - std::vector& proc = fctx->GetData()->proc_; + std::vector& proc = fctx.GetData()->proc; boost::sort::pdqsort(sortIds.begin(), sortIds.end(), [&proc, mergedIds](size_t i1, size_t i2) { int p1 = proc[i1]; int p2 = proc[i2]; @@ -345,6 +300,74 @@ IdSet::Ptr FastIndexText::Select(FtCtx::Ptr fctx, FtDSLQuery&& dsl, bool inTr } return mergedIds; } + +template +template +IdSet::Ptr FastIndexText::applyCtxTypeAndSelect(DataHolder* d, const BaseFunctionCtx::Ptr& bctx, FtDSLQuery&& dsl, + bool inTransaction, FtSortType ftSortType, FtMergeStatuses&& statuses, + FtUseExternStatuses useExternSt, const RdxContext& rdxCtx) { + Selecter selecter{*d, this->Fields().size(), holder_->cfg_->maxAreasInDoc}; + intrusive_ptr fctx = static_ctx_pointer_cast(bctx); + assertrx_throw(fctx); + fctx->SetExtraWordSymbols(this->getConfig()->extraWordSymbols); + fctx->SetWordPosition(true); + + switch (bctx->type) { + case BaseFunctionCtx::CtxType::kFtCtx: { + MergeDataBase mergeData = selecter.template Process( + std::move(dsl), inTransaction, ftSortType, std::move(statuses.statuses), rdxCtx); + return afterSelect(*fctx.get(), std::move(mergeData), ftSortType, std::move(statuses), useExternSt); + } + case BaseFunctionCtx::CtxType::kFtArea: { + MergeData mergeData = selecter.template Process>( + std::move(dsl), inTransaction, ftSortType, std::move(statuses.statuses), rdxCtx); + return afterSelect(*fctx.get(), std::move(mergeData), ftSortType, std::move(statuses), useExternSt); + } + case BaseFunctionCtx::CtxType::kFtAreaDebug: { + MergeData mergeData = selecter.template Process>( + std::move(dsl), inTransaction, ftSortType, std::move(statuses.statuses), rdxCtx); + return afterSelect(*fctx.get(), std::move(mergeData), ftSortType, std::move(statuses), useExternSt); + } + default: + throw_assert(false); + } +} + +template +template +IdSet::Ptr FastIndexText::applyOptimizationAndSelect(DataHolder* d, BaseFunctionCtx::Ptr bctx, FtDSLQuery&& dsl, + bool inTransaction, FtSortType ftSortType, FtMergeStatuses&& statuses, + FtUseExternStatuses useExternSt, const RdxContext& rdxCtx) { + if (useExternSt == FtUseExternStatuses::Yes) { + return applyCtxTypeAndSelect(d, std::move(bctx), std::move(dsl), inTransaction, ftSortType, + std::move(statuses), useExternSt, rdxCtx); + } else { + return applyCtxTypeAndSelect(d, std::move(bctx), std::move(dsl), inTransaction, ftSortType, + std::move(statuses), useExternSt, rdxCtx); + } +} + +template +IdSet::Ptr FastIndexText::Select(FtCtx::Ptr bctx, FtDSLQuery&& dsl, bool inTransaction, FtSortType ftSortType, + FtMergeStatuses&& statuses, FtUseExternStatuses useExternSt, const RdxContext& rdxCtx) { + switch (holder_->cfg_->optimization) { + case FtFastConfig::Optimization::Memory: { + DataHolder* d = dynamic_cast*>(holder_.get()); + assertrx_throw(d); + return applyOptimizationAndSelect(d, bctx, std::move(dsl), inTransaction, ftSortType, std::move(statuses), + useExternSt, rdxCtx); + } + case FtFastConfig::Optimization::CPU: { + DataHolder* d = dynamic_cast*>(holder_.get()); + assertrx_throw(d); + return applyOptimizationAndSelect(d, bctx, std::move(dsl), inTransaction, ftSortType, std::move(statuses), + useExternSt, rdxCtx); + } + default: + throw_assert(false); + } +} + template void FastIndexText::commitFulltextImpl() { try { @@ -431,15 +454,15 @@ void FastIndexText::buildVdocs(Container& data) { } else { doc = it; } - doc->second.SetVDocID(vdocs.size()); vdocsTexts.emplace_back(gt.getDocFields(doc->first, bufStrs)); - #ifdef REINDEX_FT_EXTRA_DEBUG std::string text(vdocsTexts.back()[0].first); vdocs.push_back({(text.length() > 48) ? text.substr(0, 48) + "..." : text, doc->second.get(), {}, {}}); #else vdocs.push_back({doc->second.get(), {}, {}}); #endif + // Set VDocID after actual doc emplacing + doc->second.SetVDocID(vdocs.size() - 1); if rx_unlikely (getConfig()->logLevel <= LogInfo) { for (auto& f : vdocsTexts.back()) { @@ -453,16 +476,13 @@ void FastIndexText::buildVdocs(Container& data) { } template -template -RX_ALWAYS_INLINE void FastIndexText::appendMergedIds(MergeData& mergeData, size_t releventDocs, F&& appender) { +template +RX_ALWAYS_INLINE void FastIndexText::appendMergedIds(MergeType& mergeData, size_t releventDocs, F&& appender) { auto& holder = *this->holder_; - for (size_t i = 0; i < releventDocs;) { + for (size_t i = 0; i < releventDocs; i++) { auto& vid = mergeData[i]; auto& vdoc = holder.vdocs_[vid.id]; - if (vdoc.keyEntry) { - appender(vdoc.keyEntry->Sorted(0).begin(), vdoc.keyEntry->Sorted(0).end(), vid); - i++; - } + appender(vdoc.keyEntry->Sorted(0).begin(), vdoc.keyEntry->Sorted(0).end(), vid); } } diff --git a/cpp_src/core/index/indextext/fastindextext.h b/cpp_src/core/index/indextext/fastindextext.h index 8e902d945..68c3afe29 100644 --- a/cpp_src/core/index/indextext/fastindextext.h +++ b/cpp_src/core/index/indextext/fastindextext.h @@ -7,8 +7,6 @@ namespace reindexer { -struct MergeData; - template class FastIndexText : public IndexText { using Base = IndexText; @@ -32,8 +30,9 @@ class FastIndexText : public IndexText { // Creates uncommited copy return std::make_unique>(*this); } - IdSet::Ptr Select(FtCtx::Ptr fctx, FtDSLQuery&& dsl, bool inTransactionbool, FtSortType ftSortType, FtMergeStatuses&&, - FtUseExternStatuses, const RdxContext&) override final; + IdSet::Ptr Select(FtCtx::Ptr ctx, FtDSLQuery&& dsl, bool inTransaction, FtSortType ftSortType, FtMergeStatuses&&, FtUseExternStatuses, + const RdxContext&) override final; + IndexMemStat GetMemStat(const RdxContext&) override final; Variant Upsert(const Variant& key, IdType id, bool& clearCache) override final; void Delete(const Variant& key, IdType id, StringsHolder&, bool& clearCache) override final; @@ -47,16 +46,30 @@ class FastIndexText : public IndexText { bool EnablePreselectBeforeFt() const override final { return getConfig()->enablePreselectBeforeFt; } private: + template + IdSet::Ptr afterSelect(FtCtx& fctx, MergeType&& mergeData, FtSortType ftSortType, FtMergeStatuses&& statuses, FtUseExternStatuses); + + template + IdSet::Ptr applyOptimizationAndSelect(DataHolder* d, BaseFunctionCtx::Ptr bctx, FtDSLQuery&& dsl, bool inTransaction, + FtSortType ftSortType, FtMergeStatuses&& statuses, FtUseExternStatuses, const RdxContext& rdxCtx); + + template + IdSet::Ptr applyCtxTypeAndSelect(DataHolder* d, const BaseFunctionCtx::Ptr& bctx, FtDSLQuery&& dsl, bool inTransaction, + FtSortType ftSortType, FtMergeStatuses&& statuses, FtUseExternStatuses useExternSt, + const RdxContext& rdxCtx); + +protected: void commitFulltextImpl() override final; FtFastConfig* getConfig() const noexcept { return dynamic_cast(this->cfg_.get()); } void initConfig(const FtFastConfig* = nullptr); void initHolder(FtFastConfig&); template void buildVdocs(Data& data); - template - void appendMergedIds(MergeData& merged, size_t releventDocs, F&& appender); - - MergeData::iterator unstableRemoveIf(MergeData& md, const int minRelevancy, double scalingFactor, size_t& releventDocs, int& cnt); + template + void appendMergedIds(MergeType& merged, size_t releventDocs, F&& appender); + template + typename MergeType::iterator unstableRemoveIf(MergeType& md, const int minRelevancy, double scalingFactor, size_t& releventDocs, + int& cnt); std::unique_ptr holder_; }; diff --git a/cpp_src/core/index/indextext/fieldsgetter.h b/cpp_src/core/index/indextext/fieldsgetter.h index 300fe4cdc..bce1e0579 100644 --- a/cpp_src/core/index/indextext/fieldsgetter.h +++ b/cpp_src/core/index/indextext/fieldsgetter.h @@ -45,7 +45,7 @@ class FieldsGetter { } else { const std::string_view stringRef(kref); if (rx_likely(!utf8::is_valid(stringRef.data(), stringRef.data() + stringRef.size()))) { - throw Error(errParams, "Invalid UTF8 string in FullTextindex"); + throw Error(errParams, "Invalid UTF8 string in FullText index"); } ret.emplace_back(stringRef, fieldPos); } diff --git a/cpp_src/core/index/indextext/fuzzyindextext.cc b/cpp_src/core/index/indextext/fuzzyindextext.cc index 148db2e0c..908bec1e3 100644 --- a/cpp_src/core/index/indextext/fuzzyindextext.cc +++ b/cpp_src/core/index/indextext/fuzzyindextext.cc @@ -5,7 +5,8 @@ namespace reindexer { template -IdSet::Ptr FuzzyIndexText::Select(FtCtx::Ptr fctx, FtDSLQuery&& dsl, bool inTransaction, FtSortType ftSortType, FtMergeStatuses&&, + +IdSet::Ptr FuzzyIndexText::Select(FtCtx::Ptr bctx, FtDSLQuery&& dsl, bool inTransaction, FtSortType ftSortType, FtMergeStatuses&&, FtUseExternStatuses withExternSt, const RdxContext& rdxCtx) { assertrx_throw(withExternSt == FtUseExternStatuses::No); (void)ftSortType; @@ -15,6 +16,7 @@ IdSet::Ptr FuzzyIndexText::Select(FtCtx::Ptr fctx, FtDSLQuery&& dsl, bool inT auto mergedIds = make_intrusive>(); mergedIds->reserve(result.data_->size() * 2); + intrusive_ptr fctx = static_ctx_pointer_cast(bctx); fctx->Reserve(result.data_->size() * 2); double coof = 1; if (result.max_proc_ > 100) { diff --git a/cpp_src/core/index/indextext/fuzzyindextext.h b/cpp_src/core/index/indextext/fuzzyindextext.h index d92a0a210..6459025a6 100644 --- a/cpp_src/core/index/indextext/fuzzyindextext.h +++ b/cpp_src/core/index/indextext/fuzzyindextext.h @@ -22,9 +22,10 @@ class FuzzyIndexText : public IndexText { assertrx(0); abort(); } + std::unique_ptr Clone() const override final { return std::make_unique>(*this); } - IdSet::Ptr Select(FtCtx::Ptr fctx, FtDSLQuery&& dsl, bool inTransaction, FtSortType ftSortType, FtMergeStatuses&&, FtUseExternStatuses, - const RdxContext&) override final; + IdSet::Ptr Select(FtCtx::Ptr fctx, FtDSLQuery&& dsl, bool inTransaction, FtSortType ftSortType, FtMergeStatuses&&, + FtUseExternStatuses withExternSt, const RdxContext&) override final; Variant Upsert(const Variant& key, IdType id, bool& clearCache) override final { this->isBuilt_ = false; return Base::Upsert(key, id, clearCache); diff --git a/cpp_src/core/index/indextext/indextext.cc b/cpp_src/core/index/indextext/indextext.cc index 695456a7e..e1e5db9c0 100644 --- a/cpp_src/core/index/indextext/indextext.cc +++ b/cpp_src/core/index/indextext/indextext.cc @@ -71,16 +71,6 @@ void IndexText::ReconfigureCache(const NamespaceCacheConfigData& cacheCfg) { Base::ReconfigureCache(cacheCfg); } -template -FtCtx::Ptr IndexText::prepareFtCtx(const BaseFunctionCtx::Ptr& ctx) { - FtCtx::Ptr ftctx = reindexer::static_ctx_pointer_cast(ctx); - if rx_unlikely (!ftctx) { - throw Error(errParams, "Full text index (%s) may not be used without context", Index::Name()); - } - ftctx->PrepareAreas(ftFields_, this->name_); - return ftctx; -} - template void IndexText::build(const RdxContext& rdxCtx) { smart_lock lck(mtx_, rdxCtx); @@ -103,7 +93,6 @@ SelectKeyResults IndexText::SelectKey(const VariantArray& keys, CondType cond throw Error(errParams, "Full text index (%s) support only EQ or SET condition with 1 or 2 parameter", Index::Name()); } - FtCtx::Ptr ftctx = prepareFtCtx(ctx); auto mergeStatuses = this->GetFtMergeStatuses(rdxCtx); bool needPutCache = false; IdSetCacheKey ckey{keys, condition, 0}; @@ -111,23 +100,26 @@ SelectKeyResults IndexText::SelectKey(const VariantArray& keys, CondType cond if (cache_ft.valid) { if (!cache_ft.val.ids) { needPutCache = true; - } else if (ftctx->NeedArea() && (!cache_ft.val.ctx || !cache_ft.val.ctx->NeedArea())) { + } else if (ctx->type == BaseFunctionCtx::CtxType::kFtArea && + (!cache_ft.val.ctx || !(cache_ft.val.ctx->type == BaseFunctionCtx::CtxType::kFtArea))) { needPutCache = true; } else { - return resultFromCache(keys, std::move(cache_ft), ftctx); + return resultFromCache(keys, std::move(cache_ft), ctx); } } + return doSelectKey(keys, needPutCache ? std::optional{std::move(ckey)} : std::nullopt, std::move(mergeStatuses), - FtUseExternStatuses::No, opts.inTransaction, FtSortType(opts.ftSortType), std::move(ftctx), rdxCtx); + FtUseExternStatuses::No, opts.inTransaction, FtSortType(opts.ftSortType), ctx, rdxCtx); } template -SelectKeyResults IndexText::resultFromCache(const VariantArray& keys, FtIdSetCache::Iterator&& it, FtCtx::Ptr& ftctx) { +SelectKeyResults IndexText::resultFromCache(const VariantArray& keys, FtIdSetCache::Iterator&& it, const BaseFunctionCtx::Ptr& ctx) { if rx_unlikely (cfg_->logLevel >= LogInfo) { logPrintf(LogInfo, "Get search results for '%s' in '%s' from cache", keys[0].As(), this->payloadType_ ? this->payloadType_->Name() : ""); } assertrx(it.val.ctx); + FtCtx::Ptr ftctx = static_ctx_pointer_cast(ctx); ftctx->SetData(std::move(it.val.ctx)); return SelectKeyResult{{SingleSelectKeyResult{std::move(it.val.ids)}}}; } @@ -135,7 +127,7 @@ SelectKeyResults IndexText::resultFromCache(const VariantArray& keys, FtIdSet template SelectKeyResults IndexText::doSelectKey(const VariantArray& keys, const std::optional& ckey, FtMergeStatuses&& mergeStatuses, FtUseExternStatuses useExternSt, bool inTransaction, - FtSortType ftSortType, FtCtx::Ptr ftctx, const RdxContext& rdxCtx) { + FtSortType ftSortType, const BaseFunctionCtx::Ptr& bctx, const RdxContext& rdxCtx) { if rx_unlikely (cfg_->logLevel >= LogInfo) { logPrintf(LogInfo, "Searching for '%s' in '%s' %s", keys[0].As(), this->payloadType_ ? this->payloadType_->Name() : "", ckey ? "(will cache)" : ""); @@ -145,36 +137,40 @@ SelectKeyResults IndexText::doSelectKey(const VariantArray& keys, const std:: FtDSLQuery dsl(this->ftFields_, this->cfg_->stopWords, this->cfg_->extraWordSymbols); dsl.parse(keys[0].As()); - IdSet::Ptr mergedIds = Select(ftctx, std::move(dsl), inTransaction, ftSortType, std::move(mergeStatuses), useExternSt, rdxCtx); + auto ftCtx = static_ctx_pointer_cast(bctx); + IdSet::Ptr mergedIds = Select(ftCtx, std::move(dsl), inTransaction, ftSortType, std::move(mergeStatuses), useExternSt, rdxCtx); SelectKeyResult res; if (mergedIds) { + auto ftCtxDataBase = ftCtx->GetData(); bool need_put = (useExternSt == FtUseExternStatuses::No) && ckey.has_value(); - if (ftctx->NeedArea() && need_put && mergedIds->size()) { + // count the number of Areas and determine whether the request should be cached + if (bctx->type == BaseFunctionCtx::CtxType::kFtArea && need_put && mergedIds->size()) { auto config = dynamic_cast(cfg_.get()); + auto ftCtxDataArea = static_ctx_pointer_cast>(ftCtxDataBase); + if (config && config->maxTotalAreasToCache >= 0) { - auto& d = *ftctx->GetData(); size_t totalAreas = 0; - assertrx_throw(d.holders_.has_value()); - for (auto& area : d.holders_.value()) { - totalAreas += d.area_[area.second].GetAreasCount(); + assertrx_throw(ftCtxDataArea->holders.has_value()); + // NOLINTNEXTLINE(bugprone-unchecked-optional-access) + for (auto& area : ftCtxDataArea->holders.value()) { + totalAreas += ftCtxDataArea->area[area.second].GetAreasCount(); } + if (totalAreas > unsigned(config->maxTotalAreasToCache)) { need_put = false; } } - } - if (need_put && mergedIds->size()) { - // This areas will be shared via cache, so lazy commit may race - auto dPtr = ftctx->GetData(); - auto& d = *dPtr; - if (d.holders_.has_value()) { - for (auto& area : d.holders_.value()) { - if (auto& aData = d.area_[area.second]; !aData.IsCommited()) { + if (need_put && ftCtxDataArea->holders.has_value()) { + // NOLINTNEXTLINE(bugprone-unchecked-optional-access) + for (auto& area : ftCtxDataArea->holders.value()) { + if (auto& aData = ftCtxDataArea->area[area.second]; !aData.IsCommited()) { aData.Commit(); } } } - cache_ft_->Put(*ckey, FtIdSetCacheVal{IdSet::Ptr(mergedIds), std::move(dPtr)}); + } + if (need_put && mergedIds->size()) { + cache_ft_->Put(*ckey, FtIdSetCacheVal{IdSet::Ptr(mergedIds), std::move(ftCtxDataBase)}); } res.emplace_back(std::move(mergedIds)); @@ -190,7 +186,7 @@ SelectKeyResults IndexText::SelectKey(const VariantArray& keys, CondType cond throw Error(errParams, "Full text index (%s) support only EQ or SET condition with 1 or 2 parameter", Index::Name()); } return doSelectKey(keys, std::nullopt, std::move(preselect), FtUseExternStatuses::Yes, opts.inTransaction, FtSortType(opts.ftSortType), - prepareFtCtx(ctx), rdxCtx); + ctx, rdxCtx); } template diff --git a/cpp_src/core/index/indextext/indextext.h b/cpp_src/core/index/indextext/indextext.h index 52b094da8..3a0af5a12 100644 --- a/cpp_src/core/index/indextext/indextext.h +++ b/cpp_src/core/index/indextext/indextext.h @@ -33,8 +33,9 @@ class IndexText : public IndexUnordered { SelectKeyResults SelectKey(const VariantArray& keys, CondType, Index::SelectOpts, const BaseFunctionCtx::Ptr&, FtPreselectT&&, const RdxContext&) override; void UpdateSortedIds(const UpdateSortedContext&) override {} - virtual IdSet::Ptr Select(FtCtx::Ptr fctx, FtDSLQuery&& dsl, bool inTransaction, FtSortType ftSortType, FtMergeStatuses&&, + virtual IdSet::Ptr Select(FtCtx::Ptr ctx, FtDSLQuery&& dsl, bool inTransaction, FtSortType ftSortType, FtMergeStatuses&&, FtUseExternStatuses, const RdxContext&) = 0; + void SetOpts(const IndexOpts& opts) override; void Commit() override final { // Do nothing @@ -65,10 +66,11 @@ class IndexText : public IndexUnordered { using Mutex = MarkedMutex; virtual void commitFulltextImpl() = 0; - FtCtx::Ptr prepareFtCtx(const BaseFunctionCtx::Ptr&); SelectKeyResults doSelectKey(const VariantArray& keys, const std::optional&, FtMergeStatuses&&, - FtUseExternStatuses useExternSt, bool inTransaction, FtSortType ftSortType, FtCtx::Ptr, const RdxContext&); - SelectKeyResults resultFromCache(const VariantArray& keys, FtIdSetCache::Iterator&&, FtCtx::Ptr&); + FtUseExternStatuses useExternSt, bool inTransaction, FtSortType ftSortType, + const BaseFunctionCtx::Ptr& ctx, const RdxContext&); + + SelectKeyResults resultFromCache(const VariantArray& keys, FtIdSetCache::Iterator&&, const BaseFunctionCtx::Ptr&); void build(const RdxContext& rdxCtx); void initSearchers(); diff --git a/cpp_src/core/itemmodifier.h b/cpp_src/core/itemmodifier.h index 72e0f9596..4532996a0 100644 --- a/cpp_src/core/itemmodifier.h +++ b/cpp_src/core/itemmodifier.h @@ -54,7 +54,7 @@ class ItemModifier { data_.reserve(DefaultCJsonSize); } data_.assign(str.begin(), str.end()); - cjson_ = std::string_view(&data_[0], str.size()); + cjson_ = !str.empty() ? std::string_view(&data_[0], str.size()) : std::string_view(); } p_string Get() const { return p_string(&cjson_); } void Reset() { cjson_ = {nullptr, 0}; } diff --git a/cpp_src/core/keyvalue/variant.cc b/cpp_src/core/keyvalue/variant.cc index 9d6a242f8..89c35dde2 100644 --- a/cpp_src/core/keyvalue/variant.cc +++ b/cpp_src/core/keyvalue/variant.cc @@ -521,31 +521,31 @@ class Comparator { return compare(v1_.As(), v2_.As()); } RX_ALWAYS_INLINE ComparationResult operator()(KeyValueType::Bool, KeyValueType::Int) const noexcept { - return compare(v1_.As(), v2_.As()); + return compare(int(v1_.As()), v2_.As()); } RX_ALWAYS_INLINE ComparationResult operator()(KeyValueType::Bool, KeyValueType::Int64) const noexcept { - return compare(v1_.As(), v2_.As()); + return compare(int64_t(v1_.As()), v2_.As()); } RX_ALWAYS_INLINE ComparationResult operator()(KeyValueType::Bool, KeyValueType::Double) const noexcept { - return compare(v1_.As(), v2_.As()); + return compare(double(v1_.As()), v2_.As()); } RX_ALWAYS_INLINE ComparationResult operator()(KeyValueType::Int, KeyValueType::Bool) const noexcept { - return compare(v1_.As(), v2_.As()); + return compare(v1_.As(), int(v2_.As())); } RX_ALWAYS_INLINE ComparationResult operator()(KeyValueType::Int, KeyValueType::Int) const noexcept { return compare(v1_.As(), v2_.As()); } RX_ALWAYS_INLINE ComparationResult operator()(KeyValueType::Int, KeyValueType::Int64) const noexcept { - return compare(v1_.As(), v2_.As()); + return compare(int64_t(v1_.As()), v2_.As()); } RX_ALWAYS_INLINE ComparationResult operator()(KeyValueType::Int, KeyValueType::Double) const noexcept { return compare(v1_.As(), v2_.As()); } RX_ALWAYS_INLINE ComparationResult operator()(KeyValueType::Int64, KeyValueType::Bool) const noexcept { - return compare(v1_.As(), v2_.As()); + return compare(v1_.As(), int64_t(v2_.As())); } RX_ALWAYS_INLINE ComparationResult operator()(KeyValueType::Int64, KeyValueType::Int) const noexcept { - return compare(v1_.As(), v2_.As()); + return compare(v1_.As(), int64_t(v2_.As())); } RX_ALWAYS_INLINE ComparationResult operator()(KeyValueType::Int64, KeyValueType::Int64) const noexcept { return compare(v1_.As(), v2_.As()); @@ -554,7 +554,7 @@ class Comparator { return compare(v1_.As(), v2_.As()); } RX_ALWAYS_INLINE ComparationResult operator()(KeyValueType::Double, KeyValueType::Bool) const noexcept { - return compare(v1_.As(), v2_.As()); + return compare(v1_.As(), double(v2_.As())); } RX_ALWAYS_INLINE ComparationResult operator()(KeyValueType::Double, KeyValueType::Int) const noexcept { return compare(v1_.As(), v2_.As()); diff --git a/cpp_src/core/namespace/itemsloader.cc b/cpp_src/core/namespace/itemsloader.cc index 19df50dd0..9d1b5d8da 100644 --- a/cpp_src/core/namespace/itemsloader.cc +++ b/cpp_src/core/namespace/itemsloader.cc @@ -57,7 +57,7 @@ void ItemsLoader::reading() { throw Error(errLogic, "Can't load data storage of '%s' - there are no PK fields in ns", ns_.name_); } if (dataSlice.size() < sizeof(int64_t)) { - lastErr = Error(errParseBin, "Not enougth data in data slice"); + lastErr = Error(errParseBin, "Not enough data in data slice"); logPrintf(LogTrace, "Error load item to '%s' from storage: '%s'", ns_.name_, lastErr.what()); ++errCount; continue; @@ -110,7 +110,7 @@ void ItemsLoader::reading() { continue; } item.impl.Value().SetLSN(l); - // Prealloc payload here, because reading|parsing thread is faster then index insertion thread + // Preallocate payload here, because reading|parsing thread is faster than index insertion thread item.preallocPl = PayloadValue(item.impl.GetConstPayload().RealSize()); lck.lock(); diff --git a/cpp_src/core/namespace/namespace.cc b/cpp_src/core/namespace/namespace.cc index ecd68adfc..d219ba229 100644 --- a/cpp_src/core/namespace/namespace.cc +++ b/cpp_src/core/namespace/namespace.cc @@ -122,7 +122,7 @@ NamespacePerfStat Namespace::GetPerfStat(const RdxContext& ctx) { void Namespace::ApplySnapshotChunk(const SnapshotChunk& ch, bool isInitialLeaderSync, const RdxContext& ctx) { if (!ch.IsTx() || ch.IsShallow() || !ch.IsWAL()) { - return nsFuncWrapper<&NamespaceImpl::ApplySnapshotChunk>(ch, isInitialLeaderSync, ctx); + nsFuncWrapper<&NamespaceImpl::ApplySnapshotChunk>(ch, isInitialLeaderSync, ctx); } else { SnapshotTxHandler handler(*this); handler.ApplyChunk(ch, isInitialLeaderSync, ctx); @@ -156,17 +156,20 @@ bool Namespace::isExpectingSelectsOnNamespace(const NamespaceImpl::Ptr& ns, cons void Namespace::doRename(const Namespace::Ptr& dst, std::string_view newName, const std::string& storagePath, const std::function)>& replicateCb, const RdxContext& ctx) { - logPrintf(LogTrace, "[rename] Trying to rename namespace '%s'...", GetName(ctx)); + auto srcNsName = GetName(ctx); + logPrintf(LogInfo, "[rename] Trying to rename namespace '%s'...", srcNsName); std::string dbpath; const auto flushOpts = StorageFlushOpts().WithImmediateReopen(); auto lck = nsFuncWrapper<&NamespaceImpl::dataWLock>(ctx, true); auto srcNsPtr = atomicLoadMainNs(); auto& srcNs = *srcNsPtr; + logPrintf(LogInfo, "[rename] Performing double check for unflushed data for '%s'...", srcNsName); srcNs.storage_.Flush(flushOpts); // Repeat flush, to raise any disk errors before attempt to close storage auto storageStatus = srcNs.storage_.GetStatusCached(); if (!storageStatus.err.ok()) { throw Error(storageStatus.err.code(), "Unable to flush storage before rename: %s", storageStatus.err.what()); } + logPrintf(LogInfo, "[rename] All data in '%s' were flushed succesfully", srcNsName); NamespaceImpl::Locker::WLockT dstLck; NamespaceImpl::Ptr dstNs; if (dst) { @@ -237,7 +240,7 @@ void Namespace::doRename(const Namespace::Ptr& dst, std::string_view newName, co srcNs.tagsMatcher_.stateToken(), srcNs.tagsMatcher_.version()); if (hadStorage) { - logPrintf(LogTrace, "[rename] Storage was moved from %s to %s", srcDbpath, dbpath); + logPrintf(LogInfo, "[rename] Storage was moved from '%s' to '%s'", srcDbpath, dbpath); auto status = srcNs.storage_.Open(storageType, srcNs.name_, dbpath, srcNs.storageOpts_); if (!status.ok()) { srcNs.storage_.Close(); diff --git a/cpp_src/core/namespace/namespaceimpl.cc b/cpp_src/core/namespace/namespaceimpl.cc index ce171f51b..9353a5ec2 100644 --- a/cpp_src/core/namespace/namespaceimpl.cc +++ b/cpp_src/core/namespace/namespaceimpl.cc @@ -4,7 +4,6 @@ #include #include #include "core/cjson/cjsondecoder.h" -// #include "core/cjson/defaultvaluecoder.h" #include "core/cjson/jsonbuilder.h" #include "core/cjson/uuid_recoders.h" #include "core/formatters/lsn_fmt.h" @@ -97,9 +96,9 @@ NamespaceImpl::NamespaceImpl(const NamespaceImpl& src, AsyncStorage::FullLockT& optimizationState_{NotOptimized}, strHolder_{makeStringsHolder()}, nsUpdateSortedContextMemory_{0}, - dbDestroyed_(false), - incarnationTag_(src.incarnationTag_), - observers_(src.observers_) { + dbDestroyed_{false}, + incarnationTag_{src.incarnationTag_}, + observers_{src.observers_} { for (auto& idxIt : src.indexes_) { indexes_.push_back(idxIt->Clone()); } @@ -118,24 +117,24 @@ static int64_t GetCurrentTimeUS() noexcept { NamespaceImpl::NamespaceImpl(const std::string& name, std::optional stateToken, const cluster::IDataSyncer& syncer, UpdatesObservers& observers) : intrusive_atomic_rc_base(), - indexes_(*this), - name_(name), - payloadType_(name), + indexes_{*this}, + name_{name}, + payloadType_{name}, tagsMatcher_(payloadType_, stateToken.has_value() ? stateToken.value() : tools::RandomGenerator::gets32()), locker_(syncer, *this), - enablePerfCounters_(false), - queryCountCache_( - std::make_unique(config_.cacheConfig.queryCountCacheSize, config_.cacheConfig.queryCountHitsToCache)), - joinCache_(std::make_unique(config_.cacheConfig.joinCacheSize, config_.cacheConfig.joinHitsToCache)), - wal_(getWalSize(config_)), + enablePerfCounters_{false}, + queryCountCache_{ + std::make_unique(config_.cacheConfig.queryCountCacheSize, config_.cacheConfig.queryCountHitsToCache)}, + joinCache_{std::make_unique(config_.cacheConfig.joinCacheSize, config_.cacheConfig.joinHitsToCache)}, + wal_{getWalSize(config_)}, lastSelectTime_{0}, cancelCommitCnt_{0}, lastUpdateTime_{0}, - nsIsLoading_(false), + nsIsLoading_{false}, strHolder_{makeStringsHolder()}, - dbDestroyed_(false), + dbDestroyed_{false}, incarnationTag_(GetCurrentTimeUS() % lsn_t::kDefaultCounter, 0), - observers_(observers) { + observers_{observers} { logPrintf(LogTrace, "NamespaceImpl::NamespaceImpl (%s)", name_); FlagGuardT nsLoadingGuard(nsIsLoading_); items_.reserve(10000); @@ -375,7 +374,7 @@ class NamespaceImpl::RollBack_recreateCompositeIndexes final : private RollBackB private: NamespaceImpl& ns_; std::vector> indexes_; - size_t startIdx_; + size_t startIdx_{0}; }; template <> @@ -459,32 +458,11 @@ class NamespaceImpl::RollBack_updateItems final : private RollBackBase { NamespaceImpl& ns_; RollBack_recreateCompositeIndexes rollbacker_recreateCompositeIndexes_; std::vector> items_; - uint64_t dataHash_; - size_t itemsDataSize_; + uint64_t dataHash_{0}; + size_t itemsDataSize_{0}; std::unique_ptr tuple_; }; -std::vector NamespaceImpl::pickJsonPath(const PayloadFieldType& fld) { - const auto& paths = fld.JsonPaths(); - if (fld.IsArray()) { - std::vector result; - result.reserve(paths.size()); - for (const auto& path : paths) { - auto tags = tagsMatcher_.path2tag(path, false); - result.push_back(std::move(tags)); - // first without nested path - always (any, now last one found) - if ((result.size() > 1) && (result.back().size() == 1)) { - std::swap(result.front(), result.back()); - } - } - return result; - } - - assertrx_throw(paths.size() == 1); - auto tags = tagsMatcher_.path2tag(paths.front(), false); - return {std::move(tags)}; -} - template <> class NamespaceImpl::RollBack_updateItems { public: @@ -548,16 +526,6 @@ NamespaceImpl::RollBack_updateItems NamespaceImpl::updateItems(con recoder = std::make_unique(changedField); } } - // TODO: This logic must be reenabled after #1353. Now it's potentially unsafe - // else { - // const auto& indexToUpdate = indexes_[changedField]; - // if (!IsComposite(indexToUpdate->Type()) && !indexToUpdate->Opts().IsSparse()) { - // auto tagsNames = pickJsonPath(fld); - // if (!tagsNames.empty()) { - // recoder = std::make_unique(name_, fld, std::move(tagsNames), changedField); - // } - // } - // } } rollbacker.SaveTuple(); @@ -581,7 +549,6 @@ NamespaceImpl::RollBack_updateItems NamespaceImpl::updateItems(con ItemImpl oldItem(oldPlType, plCurr, tagsMatcher_); oldItem.Unsafe(true); newItem.FromCJSON(oldItem, recoder.get()); - const bool itemTupleUpdated = recoder && recoder->Reset(); PayloadValue plNew = oldValue.CopyTo(payloadType_, fieldChangeType == FieldChangeType::Add); plNew.SetLSN(plCurr.GetLSN()); @@ -633,17 +600,6 @@ NamespaceImpl::RollBack_updateItems NamespaceImpl::updateItems(con plCurr = std::move(plNew); repl_.dataHash ^= Payload(payloadType_, plCurr).GetHash(); itemsDataSize_ += plCurr.GetCapacity() + sizeof(PayloadValue::dataHeader); - - // update data in storage - if (itemTupleUpdated && storage_.IsValid()) { - pk.Reset(); - data.Reset(); - pk << kRxStorageItemPrefix; - Payload(payloadType_, plCurr).SerializeFields(pk, pkFields()); - data.PutUInt64(int64_t(plCurr.GetLSN())); - newItem.GetCJSON(data); - storage_.Write(pk.Slice(), data.Slice()); - } } markUpdated(IndexOptimization::Partial); @@ -1366,7 +1322,7 @@ int NamespaceImpl::getIndexByName(std::string_view index) const { } int NamespaceImpl::getIndexByNameOrJsonPath(std::string_view index) const { - int idx; + int idx = 0; if (tryGetIndexByName(index, idx)) { return idx; } @@ -1379,7 +1335,7 @@ int NamespaceImpl::getIndexByNameOrJsonPath(std::string_view index) const { } int NamespaceImpl::getScalarIndexByName(std::string_view index) const { - int idx; + int idx = 0; if (tryGetIndexByName(index, idx)) { if (idx < indexes_.firstCompositePos()) { return idx; @@ -1410,7 +1366,7 @@ bool NamespaceImpl::getIndexByNameOrJsonPath(std::string_view name, int& index) } bool NamespaceImpl::getScalarIndexByName(std::string_view name, int& index) const { - int idx; + int idx = 0; if (tryGetIndexByName(name, idx)) { if (idx < indexes_.firstCompositePos()) { index = idx; @@ -1454,7 +1410,7 @@ void NamespaceImpl::doDelete(IdType id) { storage_.Remove(pk.Slice()); // erase last item - int field; + int field = 0; // erase from composite indexes auto indexesCacheCleaner{GetIndexesCacheCleaner()}; @@ -1810,12 +1766,6 @@ void NamespaceImpl::doUpsert(ItemImpl* ritem, IdType id, bool doUpdate) { plNew.Get(field, skrefs); } - if (index.Opts().GetCollateMode() == CollateUTF8) { - for (auto& key : skrefs) { - key.EnsureUTF8(); - } - } - // Check for update if (doUpdate) { if (isIndexSparse) { @@ -1962,6 +1912,22 @@ void NamespaceImpl::doModifyItem(Item& item, ItemModifyMode mode, UpdatesContain return; } + for (int field = 1, regularIndexes = indexes_.firstCompositePos(); field < regularIndexes; ++field) { + Index& index = *indexes_[field]; + if (index.Opts().GetCollateMode() == CollateUTF8 && index.KeyType().Is()) { + if (index.Opts().IsSparse()) { + assertrx(index.Fields().getTagsPathsLength() > 0); + newPl.GetByJsonPath(index.Fields().getTagsPath(0), skrefs, KeyValueType::String{}); + } else { + newPl.Get(field, skrefs); + } + + for (auto& key : skrefs) { + key.EnsureUTF8(); + } + } + } + if (suggestedId >= 0 && exists && suggestedId != realItem.first) { throw Error(errParams, "Suggested ID doesn't correspond to real ID: %d vs %d", suggestedId, realItem.first); } @@ -3053,7 +3019,11 @@ void NamespaceImpl::removeExpiredItems(RdxActivityContext* ctx) { index->GetTTLValue(); LocalQueryResults qr; qr.AddNamespace(this, true); - doDelete(Query(name_).Where(index->Name(), CondLt, expirationThreshold), qr, pendedRepl, NsContext(rdxCtx)); + auto q = Query(name_).Where(index->Name(), CondLt, expirationThreshold); + doDelete(q, qr, pendedRepl, NsContext(rdxCtx)); + if (qr.Count()) { + logFmt(LogInfo, "{}: {} items were removed: TTL({}) has expired", name_.OriginalName(), qr.Count(), index->Name()); + } } replicate(std::move(pendedRepl), std::move(wlck), true, nullptr, RdxContext(ctx)); } @@ -3470,7 +3440,14 @@ void NamespaceImpl::processWalRecord(WALRecord&& wrec, const NsContext& ctx, lsn if (item) { assertrx(!lsn.isEmpty()); - item->setLSN(lsn); + // Cloning is required to avoid LSN modification in the QueryResult's/Snapshot's item + if (!item->impl_->RealValue().IsFree()) { + item->impl_->RealValue().Clone(); + item->impl_->RealValue().SetLSN(lsn); + } else if (!item->impl_->Value().IsFree()) { + item->impl_->Value().Clone(); + item->impl_->Value().SetLSN(lsn); + } } #ifdef REINDEX_WITH_V3_FOLLOWERS if (!repl_.temporary && !ctx.inSnapshot) { diff --git a/cpp_src/core/namespace/namespaceimpl.h b/cpp_src/core/namespace/namespaceimpl.h index 54ed29df6..83eb97b2c 100644 --- a/cpp_src/core/namespace/namespaceimpl.h +++ b/cpp_src/core/namespace/namespaceimpl.h @@ -624,9 +624,10 @@ class NamespaceImpl final : public intrusive_atomic_rc_base { // NOLINT(*perfor storage_.TryForceFlush(); } } - size_t getWalSize(const NamespaceConfigData& cfg) const noexcept { return isSystem() ? int64_t(1) : std::max(cfg.walSize, int64_t(1)); } + int64_t getWalSize(const NamespaceConfigData& cfg) const noexcept { + return isSystem() ? int64_t(1) : std::max(cfg.walSize, int64_t(1)); + } void clearNamespaceCaches(); - std::vector pickJsonPath(const PayloadFieldType& fld); PerfStatCounterMT updatePerfCounter_, selectPerfCounter_; std::atomic_bool enablePerfCounters_{false}; diff --git a/cpp_src/core/namespace/snapshot/snapshothandler.cc b/cpp_src/core/namespace/snapshot/snapshothandler.cc index b06fc1d87..4b0ece6f4 100644 --- a/cpp_src/core/namespace/snapshot/snapshothandler.cc +++ b/cpp_src/core/namespace/snapshot/snapshothandler.cc @@ -12,7 +12,8 @@ Snapshot SnapshotHandler::CreateSnapshot(const SnapshotOpts& opts) const { const auto from = opts.from; try { if (!from.IsCompatibleByNsVersion(ExtendedLsn(ns_.repl_.nsVersion, ns_.wal_.LastLSN()))) { - throw Error(errOutdatedWAL); + throw Error(errOutdatedWAL, "Requested LSN is not compatible by NS version (%d). Current namespace has %d", from.NsVersion(), + ns_.repl_.nsVersion); } Query q = Query(ns_.name_).Where("#lsn", CondGt, int64_t(from.LSN())); SelectCtx selCtx(q, nullptr); @@ -27,6 +28,8 @@ Snapshot SnapshotHandler::CreateSnapshot(const SnapshotOpts& opts) const { if (err.code() != errOutdatedWAL) { throw err; } + logFmt(LogInfo, "[repl:{}]:{} Creating RAW (force sync) snapshot. Reason: {}", ns_.name_.OriginalName(), ns_.wal_.GetServer(), + err.what()); const auto minLsn = ns_.wal_.LSNByOffset(opts.maxWalDepthOnForceSync); if (minLsn.isEmpty()) { return Snapshot(ns_.tagsMatcher_, ns_.repl_.nsVersion, ns_.repl_.dataHash, ns_.itemsCount(), ns_.repl_.clusterStatus); @@ -65,6 +68,7 @@ void SnapshotHandler::ApplyChunk(const SnapshotChunk& ch, bool isInitialLeaderSy for (auto& rec : ch.Records()) { applyRecord(rec, ctx, repl); } + ns_.storage_.TryForceFlush(); } void SnapshotHandler::applyRecord(const SnapshotRecord& snRec, const ChunkContext& ctx, h_vector& pendedRepl) { @@ -126,7 +130,6 @@ Error SnapshotHandler::applyRealRecord(lsn_t lsn, const SnapshotRecord& snRec, c NsContext ctx(dummyCtx_); ctx.InSnapshot(lsn, chCtx.wal, false, chCtx.initialLeaderSync); auto rec = snRec.Unpack(); - switch (rec.type) { // Modify item case WalItemModify: { @@ -217,8 +220,8 @@ Error SnapshotHandler::applyRealRecord(lsn_t lsn, const SnapshotRecord& snRec, c const auto version = ser.GetVarint(); const auto stateToken = ser.GetVarint(); tm.deserialize(ser, version, stateToken); - logPrintf(LogInfo, "Changing tm's statetoken on %d: %08X->%08X", ns_.wal_.GetServer(), ns_.tagsMatcher_.stateToken(), - stateToken); + logPrintf(LogInfo, "[%s]: Changing tm's statetoken on %d: %08X->%08X", ns_.name_, ns_.wal_.GetServer(), + ns_.tagsMatcher_.stateToken(), stateToken); ns_.tagsMatcher_ = std::move(tm); ns_.tagsMatcher_.UpdatePayloadType(ns_.payloadType_, NeedChangeTmVersion::No); ns_.tagsMatcher_.setUpdated(); @@ -294,7 +297,6 @@ void SnapshotTxHandler::ApplyChunk(const SnapshotChunk& ch, bool isInitialLeader break; } case WalRawItem: { - Serializer ser(wrec.rawItem.itemCJson.data(), wrec.rawItem.itemCJson.size()); Item item = tx.NewItem(); auto err = item.Unsafe().FromCJSON(wrec.rawItem.itemCJson, false); if (!err.ok()) { diff --git a/cpp_src/core/nsselecter/joinedselector.cc b/cpp_src/core/nsselecter/joinedselector.cc index edfa39c1d..6fed45c84 100644 --- a/cpp_src/core/nsselecter/joinedselector.cc +++ b/cpp_src/core/nsselecter/joinedselector.cc @@ -230,7 +230,7 @@ void JoinedSelector::AppendSelectIteratorOfJoinIndexData(SelectIteratorContainer [](const SelectIteratorContainer&) -> VariantArray { throw_as_assert; }}, preresult.payload); auto ctx = selectFnc ? selectFnc->CreateCtx(joinEntry.LeftIdxNo()) : BaseFunctionCtx::Ptr{}; - assertrx_throw(!ctx || ctx->type != BaseFunctionCtx::kFtCtx); + assertrx_throw(!ctx || ctx->type != BaseFunctionCtx::CtxType::kFtCtx); if (leftIndex->Opts().GetCollateMode() == CollateUTF8) { for (auto& key : values) { diff --git a/cpp_src/core/nsselecter/selectiteratorcontainer.cc b/cpp_src/core/nsselecter/selectiteratorcontainer.cc index 836af43e6..33b747a15 100644 --- a/cpp_src/core/nsselecter/selectiteratorcontainer.cc +++ b/cpp_src/core/nsselecter/selectiteratorcontainer.cc @@ -309,7 +309,7 @@ SelectKeyResults SelectIteratorContainer::processQueryEntry(const QueryEntry& qe opts.inTransaction = ctx_->inTransaction; auto ctx = selectFnc ? selectFnc->CreateCtx(qe.IndexNo()) : BaseFunctionCtx::Ptr{}; - if (ctx && ctx->type == BaseFunctionCtx::kFtCtx) { + if (ctx) { ftCtx = reindexer::static_ctx_pointer_cast(ctx); } diff --git a/cpp_src/core/payload/payloadiface.h b/cpp_src/core/payload/payloadiface.h index 6ec5fa19a..68d1217df 100644 --- a/cpp_src/core/payload/payloadiface.h +++ b/cpp_src/core/payload/payloadiface.h @@ -84,7 +84,7 @@ class PayloadIface { template ::value>::type* = nullptr> void SetSingleElement(int field, const Variant& key); - // Set element or array by field index + // Set element or array by index path template ::value>::type* = nullptr> void Set(std::string_view field, const VariantArray& keys, bool append = false) { return Set(t_.FieldByName(field), keys, append); diff --git a/cpp_src/core/query/dsl/dslparser.cc b/cpp_src/core/query/dsl/dslparser.cc index 69a915254..af9240952 100644 --- a/cpp_src/core/query/dsl/dslparser.cc +++ b/cpp_src/core/query/dsl/dslparser.cc @@ -144,7 +144,7 @@ constexpr static auto kAggregationTypes = MakeFastStrMap({ {"count_cached", AggCountCached}, }); -// additionalfor parse field 'equation_positions' +// additional for parse field 'equation_positions' constexpr static auto kEquationPositionMap = MakeFastStrMap({{"positions", EqualPosition::Positions}}); // additional for 'Root::QueryType' field @@ -380,8 +380,18 @@ static void parseFilter(const JsonValue& filter, Query& q, std::vector 0); const auto& qjoin = q.GetJoinQueries().back(); - if (qjoin.joinType != JoinType::LeftJoin) { - q.AppendQueryEntry((qjoin.joinType == JoinType::InnerJoin) ? OpAnd : OpOr, q.GetJoinQueries().size() - 1); + if (qjoin.joinType == JoinType::LeftJoin) { + if (op != OpAnd) { + throw Error(errParseJson, "Operation %s is not allowed with LeftJoin", OpTypeToStr(op)); + } + } else { + if (qjoin.joinType == JoinType::OrInnerJoin) { + if (op == OpNot) { + throw Error(errParseJson, "Operation NOT is not allowed with OrInnerJoin"); + } + op = OpOr; + } + q.AppendQueryEntry(op, q.GetJoinQueries().size() - 1); } break; } diff --git a/cpp_src/core/query/expressionevaluator.cc b/cpp_src/core/query/expressionevaluator.cc index 02d5e8c2b..bbec5f3ee 100644 --- a/cpp_src/core/query/expressionevaluator.cc +++ b/cpp_src/core/query/expressionevaluator.cc @@ -56,21 +56,17 @@ ExpressionEvaluator::PrimaryToken ExpressionEvaluator::getPrimaryToken(tokenizer if rx_unlikely (parser.next_token().text() != ")"sv) { throw Error(errParams, "')' expected in arithmetical expression"); } - return {.value = val, .type = PrimaryToken::Type::Scalar}; + return {.value = Variant{val}, .type = PrimaryToken::Type::Scalar}; } else if (outTok.text() == "["sv) { captureArrayContent(parser); - return {.value = std::nullopt, .type = PrimaryToken::Type::Array}; + return {.value = Variant{}, .type = PrimaryToken::Type::Array}; } switch (outTok.type) { case TokenNumber: { try { - using double_conversion::StringToDoubleConverter; - static const StringToDoubleConverter converter{StringToDoubleConverter::NO_FLAGS, NAN, NAN, nullptr, nullptr}; - int countOfCharsParsedAsDouble; - return {.value = converter.StringToDouble(outTok.text_.data(), outTok.text_.size(), &countOfCharsParsedAsDouble), - .type = PrimaryToken::Type::Scalar}; + return {.value = getVariantFromToken(outTok), .type = PrimaryToken::Type::Scalar}; } catch (...) { - throw Error(errParams, "Unable to convert '%s' to double value", outTok.text()); + throw Error(errParams, "Unable to convert '%s' to numeric value", outTok.text()); } } case TokenName: @@ -79,7 +75,7 @@ ExpressionEvaluator::PrimaryToken ExpressionEvaluator::getPrimaryToken(tokenizer if (strAllowed == StringAllowed::Yes) { arrayValues_.MarkArray(); arrayValues_.emplace_back(token2kv(outTok, parser, CompositeAllowed::No, FieldAllowed::No)); - return {.value = std::nullopt, .type = PrimaryToken::Type::Array}; + return {.value = Variant{}, .type = PrimaryToken::Type::Array}; } else { throwUnexpectedTokenError(parser, outTok); } @@ -106,17 +102,17 @@ ExpressionEvaluator::PrimaryToken ExpressionEvaluator::handleTokenName(tokenizer arrayValues_.emplace_back(std::move(val)); } return (state_ == StateArrayConcat || fieldValues.size() != 1) - ? PrimaryToken{.value = std::nullopt, .type = PrimaryToken::Type::Array} + ? PrimaryToken{.value = Variant{}, .type = PrimaryToken::Type::Array} : type_.Field(field).Type().EvaluateOneOf( [this](OneOf) -> PrimaryToken { - return {.value = arrayValues_.back().As(), .type = PrimaryToken::Type::Array}; + return {.value = arrayValues_.back(), .type = PrimaryToken::Type::Array}; }, [&, this](OneOf) -> PrimaryToken { if rx_unlikely (nonIntAllowed == NonIntegralAllowed::No && state_ != StateArrayConcat && parser.peek_token(tokenizer::flags::treat_sign_as_token).text() != "|"sv) { throw Error(errParams, kWrongFieldTypeError, outTok.text()); } - return {.value = std::nullopt, .type = PrimaryToken::Type::Array}; + return {.value = Variant{}, .type = PrimaryToken::Type::Array}; }, [](OneOf) noexcept -> PrimaryToken { @@ -130,7 +126,7 @@ ExpressionEvaluator::PrimaryToken ExpressionEvaluator::handleTokenName(tokenizer if rx_unlikely (fieldValues.empty()) { throw Error(errParams, "Calculating value of an empty field is impossible: '%s'", outTok.text()); } - return {.value = fieldValues.front().As(), .type = PrimaryToken::Type::Scalar}; + return {.value = fieldValues.front(), .type = PrimaryToken::Type::Scalar}; }, [&, this](OneOf) -> PrimaryToken { throwUnexpectedTokenError(parser, outTok); @@ -140,20 +136,20 @@ ExpressionEvaluator::PrimaryToken ExpressionEvaluator::handleTokenName(tokenizer abort(); }); } else if rx_unlikely (outTok.text() == "array_remove"sv || outTok.text() == "array_remove_once"sv) { - return {.value = double((outTok.text() == "array_remove"sv) ? Command::ArrayRemove : Command::ArrayRemoveOnce), + return {.value = Variant{int(outTok.text() == "array_remove"sv ? Command::ArrayRemove : Command::ArrayRemoveOnce)}, .type = PrimaryToken::Type::Command}; } else if rx_unlikely (outTok.text() == "true"sv || outTok.text() == "false"sv) { if rx_unlikely (nonIntAllowed == NonIntegralAllowed::No) { throwUnexpectedTokenError(parser, outTok); } arrayValues_.emplace_back(outTok.text() == "true"sv); - return {.value = std::nullopt, .type = PrimaryToken::Type::Null}; + return {.value = Variant{}, .type = PrimaryToken::Type::Null}; } pv.GetByJsonPath(outTok.text(), tagsMatcher_, fieldValues, KeyValueType::Undefined{}); if (fieldValues.IsNullValue()) { - return {.value = std::nullopt, .type = PrimaryToken::Type::Null}; + return {.value = Variant{}, .type = PrimaryToken::Type::Null}; } const bool isArrayField = fieldValues.IsArrayValue(); @@ -162,18 +158,18 @@ ExpressionEvaluator::PrimaryToken ExpressionEvaluator::handleTokenName(tokenizer arrayValues_.emplace_back(std::move(val)); } if ((state_ == StateArrayConcat) || (fieldValues.size() != 1)) { - return {.value = std::nullopt, .type = PrimaryToken::Type::Array}; + return {.value = Variant{}, .type = PrimaryToken::Type::Array}; } } if (fieldValues.size() == 1) { const Variant* vptr = isArrayField ? &arrayValues_.back() : &fieldValues.front(); return vptr->Type().EvaluateOneOf( [vptr, isArrayField](OneOf) -> PrimaryToken { - return {.value = vptr->As(), .type = isArrayField ? PrimaryToken::Type::Array : PrimaryToken::Type::Scalar}; + return {.value = *vptr, .type = isArrayField ? PrimaryToken::Type::Array : PrimaryToken::Type::Scalar}; }, [&, this](OneOf) -> PrimaryToken { if (isArrayField) { - return {.value = std::nullopt, .type = PrimaryToken::Type::Array}; + return {.value = Variant{}, .type = PrimaryToken::Type::Array}; } throwUnexpectedTokenError(parser, outTok); }, @@ -184,16 +180,16 @@ ExpressionEvaluator::PrimaryToken ExpressionEvaluator::handleTokenName(tokenizer } else if (parser.peek_token(tokenizer::flags::treat_sign_as_token).text() == "("sv) { SelectFuncStruct funcData = SelectFuncParser().ParseFunction(parser, true, outTok); funcData.field = std::string(forField_); - return {.value = functionExecutor_.Execute(funcData, ctx).As(), .type = PrimaryToken::Type::Scalar}; + return {.value = functionExecutor_.Execute(funcData, ctx), .type = PrimaryToken::Type::Scalar}; } - return {.value = std::nullopt, .type = PrimaryToken::Type::Null}; + return {.value = Variant{}, .type = PrimaryToken::Type::Null}; } -void ExpressionEvaluator::handleCommand(tokenizer& parser, const PayloadValue& v, std::optional flag, const NsContext& ctx) { - if (!flag.has_value()) { +void ExpressionEvaluator::handleCommand(tokenizer& parser, const PayloadValue& v, const Variant& flag, const NsContext& ctx) { + if (!flag.Type().Is()) { throw Error(errParams, "Could not recognize command"); } - auto cmd = Command(int(flag.value())); + auto cmd = Command(flag.As()); if ((cmd != Command::ArrayRemove) && (cmd != Command::ArrayRemoveOnce)) { throw Error(errParams, "Unexpected command detected"); } @@ -228,8 +224,8 @@ void ExpressionEvaluator::handleCommand(tokenizer& parser, const PayloadValue& v if rx_unlikely (val.type != PrimaryToken::Type::Null) { if ((val.type != PrimaryToken::Type::Array) && (val.type != PrimaryToken::Type::Scalar)) { throw Error(errParams, "Expecting array or scalar as command parameter: '%s'", valueToken.text()); - } else if ((val.type == PrimaryToken::Type::Scalar) && val.value.has_value()) { - arrayValues_.emplace_back(Variant(val.value.value())); + } else if ((val.type == PrimaryToken::Type::Scalar) && !val.value.IsNullValue()) { + arrayValues_.emplace_back(val.value); } } @@ -274,7 +270,7 @@ double ExpressionEvaluator::performArrayConcatenation(tokenizer& parser, const P break; case PrimaryToken::Type::Array: case PrimaryToken::Type::Null: - if rx_unlikely (!left.value.has_value() && tok.text() != "|"sv) { + if rx_unlikely (left.value.IsNullValue() && tok.text() != "|"sv) { throw Error(errParams, "Unable to use array and null values outside of the arrays concatenation"); } break; @@ -282,7 +278,7 @@ double ExpressionEvaluator::performArrayConcatenation(tokenizer& parser, const P handleCommand(parser, v, left.value, ctx); // update state - left.value.reset(); + left.value = Variant{}; state_ = StateArrayConcat; tok = parser.peek_token(); break; @@ -304,12 +300,12 @@ double ExpressionEvaluator::performArrayConcatenation(tokenizer& parser, const P } if rx_unlikely (right.type == PrimaryToken::Type::Command) { handleCommand(parser, v, right.value, ctx); - right.value.reset(); + right.value = Variant{}; } - assertrx_throw(!right.value.has_value()); + assertrx_throw(right.value.IsNullValue()); tok = parser.peek_token(); } - return left.value.has_value() ? left.value.value() : 0.0; + return left.value.IsNullValue() ? 0.0 : left.value.As(); } double ExpressionEvaluator::performMultiplicationAndDivision(tokenizer& parser, const PayloadValue& v, token& tok, const NsContext& ctx) { diff --git a/cpp_src/core/query/expressionevaluator.h b/cpp_src/core/query/expressionevaluator.h index 225634256..855c65ded 100644 --- a/cpp_src/core/query/expressionevaluator.h +++ b/cpp_src/core/query/expressionevaluator.h @@ -22,7 +22,7 @@ class ExpressionEvaluator { struct PrimaryToken { enum class Type { Scalar, Array, Command, Null }; - std::optional value; + Variant value; Type type; }; @@ -35,7 +35,7 @@ class ExpressionEvaluator { [[nodiscard]] double performSumAndSubtracting(tokenizer& parser, const PayloadValue& v, const NsContext& ctx); [[nodiscard]] double performMultiplicationAndDivision(tokenizer& parser, const PayloadValue& v, token& lastTok, const NsContext& ctx); [[nodiscard]] double performArrayConcatenation(tokenizer& parser, const PayloadValue& v, token& lastTok, const NsContext& ctx); - void handleCommand(tokenizer& parser, const PayloadValue& v, std::optional flag, const NsContext& ctx); + void handleCommand(tokenizer& parser, const PayloadValue& v, const Variant& flag, const NsContext& ctx); void captureArrayContent(tokenizer& parser); [[noreturn]] void throwUnexpectedTokenError(tokenizer& parser, const token& outTok); diff --git a/cpp_src/core/query/queryentry.h b/cpp_src/core/query/queryentry.h index e699cc183..d5b939231 100644 --- a/cpp_src/core/query/queryentry.h +++ b/cpp_src/core/query/queryentry.h @@ -377,9 +377,9 @@ class QueryJoinEntry { QueryField rightField_; const OpType op_{OpOr}; const CondType condition_{CondAny}; - const bool reverseNamespacesOrder_{false}; ///< controls SQL encoding order - ///< false: mainNs.index Condition joinNs.joinIndex - ///< true: joinNs.joinIndex Invert(Condition) mainNs.index + const bool reverseNamespacesOrder_{false}; ///< controls SQL encoding order + ///< false: mainNs.index Condition joinNs.joinIndex + ///< true: joinNs.joinIndex Invert(Condition) mainNs.index }; enum class InjectionDirection : bool { IntoMain, FromMain }; diff --git a/cpp_src/core/query/sql/sqlparser.cc b/cpp_src/core/query/sql/sqlparser.cc index 0d27567e3..a9921ffaf 100644 --- a/cpp_src/core/query/sql/sqlparser.cc +++ b/cpp_src/core/query/sql/sqlparser.cc @@ -315,33 +315,6 @@ class SQLParser::ParserContextsAppendGuard { SqlParsingCtx& nestedCtx_; }; -static KeyValueType detectValueType(const token& tok) { - const std::string_view val = tok.text(); - if (tok.type == TokenNumber) { - unsigned i = 0; - bool flt = false; - bool digit = val.length() < 21 && val.length() > 0; - if (val[i] == '+' || val[i] == '-') { - i++; - } - for (; i < val.length() && digit; i++) { - if (val[i] == '.') { - flt = true; - } else if (!isdigit(val[i])) { - digit = false; - } - } - if (digit && val.length() > 0) { - if (flt) { - return {KeyValueType::Double{}}; - } else { - return {KeyValueType::Int64{}}; - } - } - } - return {KeyValueType::String{}}; -} - Variant token2kv(const token& tok, tokenizer& parser, CompositeAllowed allowComposite, FieldAllowed allowField) { if (tok.text() == "{"sv) { // Composite value parsing @@ -354,7 +327,7 @@ Variant token2kv(const token& tok, tokenizer& parser, CompositeAllowed allowComp compositeValues.push_back(token2kv(nextTok, parser, CompositeAllowed::No, FieldAllowed::No)); nextTok = parser.next_token(); if (nextTok.text() == "}"sv) { - return Variant(compositeValues); // end process + return Variant(compositeValues); // end process } if (nextTok.text() != ","sv) { throw Error(errParseSQL, "Expected ',', but found '%s' in query, %s", nextTok.text(), parser.where()); @@ -379,24 +352,7 @@ Variant token2kv(const token& tok, tokenizer& parser, CompositeAllowed allowComp throw Error(errParseSQL, "Expected parameter, but found '%s' in query, %s", tok.text(), parser.where()); } - return detectValueType(tok).EvaluateOneOf( - [&](KeyValueType::Int64) { return Variant(int64_t(stoll(value))); }, - [&](KeyValueType::Double) { - try { - using double_conversion::StringToDoubleConverter; - static const StringToDoubleConverter converter{StringToDoubleConverter::NO_FLAGS, NAN, NAN, nullptr, nullptr}; - int countOfCharsParsedAsDouble; - return Variant(converter.StringToDouble(value.data(), int(value.size()), &countOfCharsParsedAsDouble)); - } catch (...) { - throw Error(errParseSQL, "Unable to convert '%s' to double value", value); - } - }, - [&](KeyValueType::String) { return Variant(make_key_string(value.data(), value.length())); }, - [](OneOf) noexcept -> Variant { - assertrx(0); - abort(); - }); + return getVariantFromToken(tok); } int SQLParser::parseOrderBy(tokenizer& parser, SortingEntries& sortingEntries, std::vector& forcedSortOrder_) { @@ -591,7 +547,7 @@ void SQLParser::parseCommand(tokenizer& parser) const { tok = parser.next_token(); // try parse as scalar value if ((tok.type == TokenNumber) || (tok.type == TokenString) || (tok.type == TokenName)) { - token2kv(tok, parser, CompositeAllowed::No, FieldAllowed::Yes); // ignore result + token2kv(tok, parser, CompositeAllowed::No, FieldAllowed::Yes); // ignore result } else { parseArray(parser, tok.text(), nullptr); } diff --git a/cpp_src/core/queryresults/localqueryresults.cc b/cpp_src/core/queryresults/localqueryresults.cc index bcf1e8db6..6c6ee045c 100644 --- a/cpp_src/core/queryresults/localqueryresults.cc +++ b/cpp_src/core/queryresults/localqueryresults.cc @@ -8,6 +8,7 @@ #include "core/itemimpl.h" #include "core/namespace/namespace.h" #include "joinresults.h" +#include "server/outputparameters.h" #include "tools/catch_and_return.h" namespace reindexer { @@ -279,6 +280,9 @@ Error LocalQueryResults::Iterator::GetProtobuf(WrSerializer& wrser, bool withHdr auto& itemRef = qr_->items_[idx_]; assertrx(qr_->ctxs.size() > itemRef.Nsid()); auto& ctx = qr_->ctxs[itemRef.Nsid()]; + if (!ctx.schema_) { + return Error(errParams, "The schema was not found for Protobuf builder"); + } if (itemRef.Value().IsFree()) { return Error(errNotFound, "Item not found"); @@ -287,6 +291,10 @@ Error LocalQueryResults::Iterator::GetProtobuf(WrSerializer& wrser, bool withHdr ConstPayload pl(ctx.type_, itemRef.Value()); ProtobufEncoder encoder(&ctx.tagsMatcher_); ProtobufBuilder builder(&wrser, ObjType::TypePlain, ctx.schema_.get(), const_cast(&ctx.tagsMatcher_)); + + auto item = builder.Object(kProtoQueryResultsFields.at(kParamItems)); + auto ItemImpl = item.Object(ctx.schema_->GetProtobufNsNumber() + 1); + if (withHdrLen) { auto slicePosSaver = wrser.StartSlice(); encoder.Encode(pl, builder); @@ -294,7 +302,7 @@ Error LocalQueryResults::Iterator::GetProtobuf(WrSerializer& wrser, bool withHdr encoder.Encode(pl, builder); } - return errOK; + return {}; } Error LocalQueryResults::Iterator::GetJSON(WrSerializer& ser, bool withHdrLen) { diff --git a/cpp_src/core/reindexer.h b/cpp_src/core/reindexer.h index 9d95f7bdb..60b8463d1 100644 --- a/cpp_src/core/reindexer.h +++ b/cpp_src/core/reindexer.h @@ -14,7 +14,6 @@ namespace reindexer { using std::chrono::milliseconds; class ShardingProxy; -class ProtobufSchema; struct ReplicationStateV2; struct ClusterizationStatus; class SnapshotChunk; @@ -52,6 +51,7 @@ class Reindexer { /// Create Reindexer database object /// @param cfg - general database options explicit Reindexer(ReindexerConfig cfg = ReindexerConfig()); + /// Destroy Reindexer database object ~Reindexer(); /// Create not holding copy @@ -379,6 +379,7 @@ class Reindexer { typedef QueryResults QueryResultsT; typedef Item ItemT; + typedef Transaction TransactionT; Error DumpIndex(std::ostream& os, std::string_view nsName, std::string_view index); diff --git a/cpp_src/core/reindexer_impl/reindexerimpl.cc b/cpp_src/core/reindexer_impl/reindexerimpl.cc index 010dee640..424ceb633 100644 --- a/cpp_src/core/reindexer_impl/reindexerimpl.cc +++ b/cpp_src/core/reindexer_impl/reindexerimpl.cc @@ -750,7 +750,10 @@ Error ReindexerImpl::renameNamespace(std::string_view srcNsName, const std::stri rlock.unlock(); if (srcNs) { - auto err = srcNs->awaitMainNs(rdxCtx)->FlushStorage(rdxCtx); + auto nsPtr = srcNs->awaitMainNs(rdxCtx); + logFmt(LogInfo, "[rename] Performing storage flush before namespace renaming ('{}' -> '{}')...", srcNsName, dstNsName); + auto err = nsPtr->FlushStorage(rdxCtx); + logFmt(LogInfo, "[rename] Flush done for '{}'", srcNsName); if (!err.ok()) { return Error(err.code(), "Unable to flush storage before rename: %s", err.what()); } diff --git a/cpp_src/core/selectfunc/ctx/basefunctionctx.h b/cpp_src/core/selectfunc/ctx/basefunctionctx.h index cebba4e26..261ff9960 100644 --- a/cpp_src/core/selectfunc/ctx/basefunctionctx.h +++ b/cpp_src/core/selectfunc/ctx/basefunctionctx.h @@ -1,5 +1,6 @@ #pragma once +#include "core/selectfunc/functions/debugrank.h" #include "core/selectfunc/functions/highlight.h" #include "core/selectfunc/functions/snippet.h" @@ -26,21 +27,22 @@ constexpr std::size_t variant_index() { } } -using SelectFuncVariant = std::variant; +using SelectFuncVariant = std::variant; enum class SelectFuncType { None = variant_index(), Snippet = variant_index(), Highlight = variant_index(), SnippetN = variant_index(), - + DebugRank = variant_index(), Max // Max possible value }; class BaseFunctionCtx : public intrusive_atomic_rc_base { public: typedef intrusive_ptr Ptr; - enum CtxType { kFtCtx = 0 }; - virtual ~BaseFunctionCtx() {} + enum class CtxType { kFtCtx = 1, kFtArea = 2, kFtAreaDebug = 3 }; + BaseFunctionCtx(CtxType t) noexcept : type(t) {} + virtual ~BaseFunctionCtx() = default; void AddFunction(const std::string& name, SelectFuncType functionIndx) { auto it = std::find_if(functions_.begin(), functions_.end(), [&name](const FuncData& data) { return data.name == name; }); @@ -67,7 +69,8 @@ class BaseFunctionCtx : public intrusive_atomic_rc_base { FuncData(std::string&& _name) noexcept : name(std::move(_name)) {} std::string name; - TypesArrayT types{}; + + TypesArrayT types = {}; }; h_vector functions_; }; diff --git a/cpp_src/core/selectfunc/ctx/ftctx.cc b/cpp_src/core/selectfunc/ctx/ftctx.cc index 5964c81a0..ff8b68922 100644 --- a/cpp_src/core/selectfunc/ctx/ftctx.cc +++ b/cpp_src/core/selectfunc/ctx/ftctx.cc @@ -2,38 +2,19 @@ namespace reindexer { -bool FtCtx::PrepareAreas(const RHashMap& fields, const std::string& name) { - assertrx_dbg(!NeedArea()); - auto& data = *data_; - if (!fields.empty()) { - data.isComposite_ = true; - } - - bool needArea = false; - if (data.isComposite_) { - for (auto& field : fields) { - needArea = CheckFunction(field.first, {SelectFuncType::Snippet, SelectFuncType::SnippetN, SelectFuncType::Highlight}); - if (needArea) { - break; - } - } - } - needArea = needArea || CheckFunction(name, {SelectFuncType::Snippet, SelectFuncType::SnippetN, SelectFuncType::Highlight}); - if (needArea) { - data.InitHolders(); - } - return needArea; -} - -template -void FtCtx::Add(InputIterator begin, InputIterator end, int16_t proc, AreaHolder&& holder) { - auto& data = *data_; - data.area_.emplace_back(std::move(holder)); - for (; begin != end; ++begin) { - data.proc_.emplace_back(proc); - if (data.holders_.has_value()) { - data.holders_->emplace(*begin, data_->area_.size() - 1); - } +FtCtx::FtCtx(BaseFunctionCtx::CtxType t) : BaseFunctionCtx(t) { + switch (t) { + case BaseFunctionCtx::CtxType::kFtCtx: + data_ = make_intrusive(t); + break; + case BaseFunctionCtx::CtxType::kFtArea: + data_ = make_intrusive>(t); + data_->holders.emplace(); + break; + case BaseFunctionCtx::CtxType::kFtAreaDebug: + data_ = make_intrusive>(t); + data_->holders.emplace(); + break; } } @@ -41,42 +22,66 @@ template void FtCtx::Add(InputIterator begin, InputIterator end, int16_t proc) { auto& data = *data_; for (; begin != end; ++begin) { - data.proc_.emplace_back(proc); + data.proc.emplace_back(proc); } } template -void FtCtx::Add(InputIterator begin, InputIterator end, int16_t proc, const std::vector& mask, AreaHolder&& holder) { +void FtCtx::Add(InputIterator begin, InputIterator end, int16_t proc, const std::vector& mask) { auto& data = *data_; - data.area_.emplace_back(std::move(holder)); for (; begin != end; ++begin) { assertrx(static_cast(*begin) < mask.size()); if (!mask[*begin]) { continue; } - data.proc_.emplace_back(proc); - if (data.holders_.has_value()) { - data.holders_->emplace(*begin, data.area_.size() - 1); + data.proc.emplace_back(proc); + } +} + +template +void FtCtx::Add(InputIterator begin, InputIterator end, int16_t proc, AreasInDocument&& areas) { + intrusive_ptr> dataArea = static_ctx_pointer_cast>(data_); + assertrx_throw(dataArea); + dataArea->area.emplace_back(std::move(areas)); + auto& data = *data_; + if (data.holders.has_value()) { + auto& holders = data.holders.value(); + for (; begin != end; ++begin) { + data.proc.push_back(proc); + holders.emplace(*begin, dataArea->area.size() - 1); } } } -template -void FtCtx::Add(InputIterator begin, InputIterator end, int16_t proc, const std::vector& mask) { +template +void FtCtx::Add(InputIterator begin, InputIterator end, int16_t proc, const std::vector& mask, AreasInDocument&& areas) { + intrusive_ptr> dataArea = static_ctx_pointer_cast>(data_); + assertrx_throw(dataArea); auto& data = *data_; - for (; begin != end; ++begin) { - assertrx(static_cast(*begin) < mask.size()); - if (!mask[*begin]) { - continue; + dataArea->area.emplace_back(std::move(areas)); + if (data.holders.has_value()) { + auto& holders = data.holders.value(); + for (; begin != end; ++begin) { + assertrx_dbg(static_cast(*begin) < mask.size()); + if (!mask[*begin]) { + continue; + } + data.proc.push_back(proc); + holders.emplace(*begin, dataArea->area.size() - 1); } - data.proc_.emplace_back(proc); } } +template void FtCtx::Add::iterator, Area>(span::iterator begin, span::iterator end, + int16_t proc, AreasInDocument&& holder); +template void FtCtx::Add::iterator, Area>(span::iterator begin, span::iterator end, + int16_t proc, const std::vector&, AreasInDocument&& holder); + template void FtCtx::Add::iterator>(span::iterator begin, span::iterator end, int16_t proc, - AreaHolder&& holder); + AreasInDocument&& holder); template void FtCtx::Add::iterator>(span::iterator begin, span::iterator end, int16_t proc, - const std::vector&, AreaHolder&& holder); + const std::vector&, AreasInDocument&& holder); + template void FtCtx::Add::iterator>(span::iterator begin, span::iterator end, int16_t proc); template void FtCtx::Add::iterator>(span::iterator begin, span::iterator end, int16_t proc, const std::vector&); diff --git a/cpp_src/core/selectfunc/ctx/ftctx.h b/cpp_src/core/selectfunc/ctx/ftctx.h index 636ccc42a..af696e286 100644 --- a/cpp_src/core/selectfunc/ctx/ftctx.h +++ b/cpp_src/core/selectfunc/ctx/ftctx.h @@ -8,49 +8,58 @@ namespace reindexer { +struct FtCtxData : public intrusive_atomic_rc_base { + FtCtxData(BaseFunctionCtx::CtxType t) noexcept : type(t) {} + virtual ~FtCtxData() = default; + void InitHolders() { + assertrx_dbg(!holders.has_value()); + holders.emplace(); + } + typedef intrusive_ptr Ptr; + std::vector proc; + std::optional> holders; + bool isComposite = false; + bool isWordPositions = false; + std::string extraWordSymbols; + BaseFunctionCtx::CtxType type; +}; + +template +struct FtCtxAreaData : public FtCtxData { + FtCtxAreaData(BaseFunctionCtx::CtxType t) noexcept : FtCtxData(t) {} + std::vector> area; +}; enum FtSortType { RankOnly, RankAndID, ExternalExpression }; class FtCtx : public BaseFunctionCtx { public: typedef intrusive_ptr Ptr; - struct Data : public BaseFunctionCtx { - bool NeedArea() const noexcept { return holders_.has_value(); } - void InitHolders() { - assertrx_dbg(!holders_.has_value()); - holders_.emplace(); - } - - typedef intrusive_ptr Ptr; - std::vector proc_; - std::optional> holders_; - std::vector area_; - bool isComposite_ = false; - bool isWordPositions_ = false; - std::string extraWordSymbols_; - }; - - FtCtx() : data_(make_intrusive()) { this->type = BaseFunctionCtx::kFtCtx; } - int16_t Proc(size_t pos) const noexcept { return (pos < data_->proc_.size()) ? data_->proc_[pos] : 0; } + FtCtx(BaseFunctionCtx::CtxType t); + int16_t Proc(size_t pos) const noexcept { return (pos < data_->proc.size()) ? data_->proc[pos] : 0; } - template - void Add(InputIterator begin, InputIterator end, int16_t proc, AreaHolder&& holder); template void Add(InputIterator begin, InputIterator end, int16_t proc); - template - void Add(InputIterator begin, InputIterator end, int16_t proc, const std::vector& mask, AreaHolder&& holder); template void Add(InputIterator begin, InputIterator end, int16_t proc, const std::vector& mask); - void Reserve(size_t size) { data_->proc_.reserve(size); } - size_t Size() const noexcept { return data_->proc_.size(); } - bool NeedArea() const noexcept { return data_->NeedArea(); } - bool PrepareAreas(const RHashMap& fields, const std::string& name); + template + void Add(InputIterator begin, InputIterator end, int16_t proc, AreasInDocument&& holder); - void SetData(Data::Ptr data) noexcept { data_ = std::move(data); } - const Data::Ptr& GetData() const noexcept { return data_; } + template + void Add(InputIterator begin, InputIterator end, int16_t proc, const std::vector& mask, AreasInDocument&& holder); + + void Reserve(size_t size) { data_->proc.reserve(size); } + size_t Size() const noexcept { return data_->proc.size(); } + + void SetExtraWordSymbols(const std::string& s) { data_->extraWordSymbols = s; } + void SetWordPosition(bool v) { data_->isWordPositions = v; } + + FtCtxData::Ptr GetData() { return data_; } + void SetData(FtCtxData::Ptr data) noexcept { data_ = std::move(data); } private: - Data::Ptr data_; + FtCtxData::Ptr data_; }; + } // namespace reindexer diff --git a/cpp_src/core/selectfunc/functions/debugrank.cc b/cpp_src/core/selectfunc/functions/debugrank.cc new file mode 100644 index 000000000..ac04e94a9 --- /dev/null +++ b/cpp_src/core/selectfunc/functions/debugrank.cc @@ -0,0 +1,103 @@ +#include "debugrank.h" +#include "core/keyvalue/p_string.h" +#include "core/payload/payloadiface.h" +#include "core/selectfunc/ctx/ftctx.h" +#include "core/selectfunc/selectfuncparser.h" + +namespace reindexer { + +bool DebugRank::Process(ItemRef& res, PayloadType& plType, const SelectFuncStruct& func, std::vector& stringsHolder) { + if (!func.funcArgs.empty()) { + throw Error(errParams, "'debug_rank()' does not expect any arguments, but got %d", func.funcArgs.size()); + } + if (!func.ctx || func.ctx->type != BaseFunctionCtx::CtxType::kFtAreaDebug) { + return false; + } + if (!func.tagsPath.empty()) { + throw Error(errConflict, "SetByJsonPath is not implemented yet!"); + } + + FtCtx::Ptr ftctx = reindexer::static_ctx_pointer_cast(func.ctx); + if (!ftctx->GetData()->isWordPositions) { + throw Error(errParams, "debug_rank() is supported for 'text' index only"); + } + + FtCtxAreaData& dataFtCtx = *(reindexer::static_ctx_pointer_cast>(ftctx->GetData())); + if (!dataFtCtx.holders.has_value()) { + return false; + } + const auto it = dataFtCtx.holders->find(res.Id()); + if (it == dataFtCtx.holders->end()) { + return false; + } + + Payload pl(plType, res.Value()); + + VariantArray kr; + pl.Get(func.field, kr); + + if (kr.empty() || !kr[0].Type().IsSame(KeyValueType::String{})) { + throw Error(errLogic, "Unable to apply debug_rank function to the non-string field '%s'", func.field); + } + + const std::string* data = p_string(kr[0]).getCxxstr(); + + const auto pva = dataFtCtx.area[it->second].GetAreas(func.fieldNo); + if (!pva || pva->Empty()) { + return false; + } + const auto& va = *pva; + + std::string resultString; + + Word2PosHelper word2pos(*data, ftctx->GetData()->extraWordSymbols); + + static const std::string_view startString = ""; + static const std::string_view endString = ""; + + const auto& areaVector = va.GetData(); + size_t id = 0; + size_t beforeStr = 0; + while (id < areaVector.size()) { + bool next = false; + int endStringCount = 0; + std::pair pos = word2pos.convert(areaVector[id].start, areaVector[id].end); + resultString += std::string_view(data->c_str() + beforeStr, pos.first - beforeStr); + do { + next = false; + switch (areaVector[id].phraseMode) { + case AreaDebug::PhraseMode::Start: + resultString += startString; + break; + case AreaDebug::PhraseMode::End: + endStringCount++; + break; + case AreaDebug::PhraseMode::None: + break; + } + resultString += areaVector[id].props; + id++; + if (id < areaVector.size() && areaVector[id].start == areaVector[id - 1].start) { + if (areaVector[id].end != areaVector[id - 1].end) { + throw Error(errLogic, "areas not equals start=%d ends(%d %d)", areaVector[id].start, areaVector[id].end, + areaVector[id - 1].end); + } + next = true; + } + } while (next); + resultString += std::string_view(data->c_str() + pos.first, pos.second - pos.first); + beforeStr = pos.second; + for (int i = 0; i < endStringCount; i++) { + resultString += endString; + } + } + resultString += std::string_view(data->c_str() + beforeStr, data->size() - beforeStr); + + stringsHolder.emplace_back(make_key_string(std::move(resultString))); + res.Value().Clone(); + + pl.Set(func.field, VariantArray{Variant{stringsHolder.back()}}); + + return true; +} +} // namespace reindexer \ No newline at end of file diff --git a/cpp_src/core/selectfunc/functions/debugrank.h b/cpp_src/core/selectfunc/functions/debugrank.h new file mode 100644 index 000000000..6cfecfa42 --- /dev/null +++ b/cpp_src/core/selectfunc/functions/debugrank.h @@ -0,0 +1,13 @@ +#pragma once +#include "core/item.h" +#include "core/queryresults/queryresults.h" + +namespace reindexer { + +struct SelectFuncStruct; + +class DebugRank { +public: + bool Process(ItemRef& res, PayloadType& plType, const SelectFuncStruct& func, std::vector& stringsHolder); +}; +} // namespace reindexer diff --git a/cpp_src/core/selectfunc/functions/highlight.cc b/cpp_src/core/selectfunc/functions/highlight.cc index ecbad1e7d..a3f9eb2b6 100644 --- a/cpp_src/core/selectfunc/functions/highlight.cc +++ b/cpp_src/core/selectfunc/functions/highlight.cc @@ -11,36 +11,35 @@ bool Highlight::Process(ItemRef& res, PayloadType& pl_type, const SelectFuncStru if (func.funcArgs.size() < 2) { throw Error(errParams, "Invalid highlight params need minimum 2 - have %d", func.funcArgs.size()); } - - if (!func.ctx || func.ctx->type != BaseFunctionCtx::kFtCtx) { + if (!func.ctx || func.ctx->type != BaseFunctionCtx::CtxType::kFtArea) { return false; } - + if (!func.tagsPath.empty()) { + throw Error(errConflict, "SetByJsonPath is not implemented yet!"); + } FtCtx::Ptr ftctx = reindexer::static_ctx_pointer_cast(func.ctx); - auto& dataFtCtx = *ftctx->GetData(); - if (!dataFtCtx.holders_.has_value()) { + FtCtxAreaData& dataFtCtx = *(reindexer::static_ctx_pointer_cast>(ftctx->GetData())); + if (!dataFtCtx.holders.has_value()) { return false; } - auto it = dataFtCtx.holders_->find(res.Id()); - if (it == dataFtCtx.holders_->end()) { + + auto it = dataFtCtx.holders->find(res.Id()); + if (it == dataFtCtx.holders->end()) { return false; } Payload pl(pl_type, res.Value()); VariantArray kr; - if (func.tagsPath.empty()) { - pl.Get(func.field, kr); - } else { - pl.GetByJsonPath(func.tagsPath, kr, KeyValueType::Undefined{}); - } + pl.Get(func.field, kr); if (kr.empty() || !kr[0].Type().IsSame(KeyValueType::String{})) { throw Error(errLogic, "Unable to apply highlight function to the non-string field '%s'", func.field); } const std::string* data = p_string(kr[0]).getCxxstr(); - auto pva = dataFtCtx.area_[it->second].GetAreas(func.fieldNo); + + auto pva = dataFtCtx.area[it->second].GetAreas(func.fieldNo); if (!pva || pva->Empty()) { return false; } @@ -50,12 +49,12 @@ bool Highlight::Process(ItemRef& res, PayloadType& pl_type, const SelectFuncStru result_string.reserve(data->size() + va.Size() * (func.funcArgs[0].size() + func.funcArgs[1].size())); result_string = *data; - Word2PosHelper word2pos(*data, ftctx->GetData()->extraWordSymbols_); + Word2PosHelper word2pos(*data, ftctx->GetData()->extraWordSymbols); int offset = 0; for (auto area : va.GetData()) { std::pair pos = - ftctx->GetData()->isWordPositions_ ? word2pos.convert(area.start, area.end) : std::make_pair(area.start, area.end); + ftctx->GetData()->isWordPositions ? word2pos.convert(area.start, area.end) : std::make_pair(area.start, area.end); result_string.insert(pos.first + offset, func.funcArgs[0]); offset += func.funcArgs[0].size(); @@ -68,11 +67,7 @@ bool Highlight::Process(ItemRef& res, PayloadType& pl_type, const SelectFuncStru stringsHolder.emplace_back(make_key_string(std::move(result_string))); res.Value().Clone(); - if (func.tagsPath.empty()) { - pl.Set(func.field, Variant{stringsHolder.back()}); - } else { - throw Error(errConflict, "SetByJsonPath is not implemented yet!"); - } + pl.Set(func.field, Variant{stringsHolder.back()}); return true; } diff --git a/cpp_src/core/selectfunc/functions/snippet.cc b/cpp_src/core/selectfunc/functions/snippet.cc index a6affd5fc..d512b97bb 100644 --- a/cpp_src/core/selectfunc/functions/snippet.cc +++ b/cpp_src/core/selectfunc/functions/snippet.cc @@ -185,10 +185,10 @@ A Snippet::RecalcZoneHelper::RecalcZoneToOffset(const Area& area) { return outAreas; } -void Snippet::buildResult(RecalcZoneHelper& recalcZoneHelper, const AreaBuffer& pva, const std::string& data, std::string& resultString) { +void Snippet::buildResult(RecalcZoneHelper& recalcZoneHelper, const AreasInField& pva, const std::string& data, + std::string& resultString) { // resultString =preDelim_+with_area_str+data_str_before+marker_before+zone_str+marker_after+data_strAfter+postDelim_ Area snippetAreaPrev; - Area snippetAreaPrevChar; zonesList_.clear(); for (const auto& area : pva.GetData()) { @@ -228,7 +228,7 @@ void Snippet::buildResult(RecalcZoneHelper& recalcZoneHelper, const AreaBuffer& resultString.append(postDelim_); } -void Snippet::buildResultWithPrefix(RecalcZoneHelper& recalcZoneHelper, const AreaBuffer& pva, const std::string& data, +void Snippet::buildResultWithPrefix(RecalcZoneHelper& recalcZoneHelper, const AreasInField& pva, const std::string& data, std::string& resultString) { // resultString =preDelim_+with_area_str+data_str_before+marker_before+zone_str+marker_after+data_strAfter+postDelim_ Area snippetAreaPrev; @@ -257,28 +257,31 @@ void Snippet::buildResultWithPrefix(RecalcZoneHelper& recalcZoneHelper, const Ar addSnippet(resultString, data, snippetAreaPrev, snippetAreaPrevChar); } -bool Snippet::Process(ItemRef& res, PayloadType& pl_type, const SelectFuncStruct& func, std::vector& stringsHolder) { +bool Snippet::Process(ItemRef& res, PayloadType& plType, const SelectFuncStruct& func, std::vector& stringsHolder) { if (!func.ctx) { return false; } + if (!func.tagsPath.empty()) { + throw Error(errConflict, "SetByJsonPath is not implemented yet!"); + } + init(func); FtCtx::Ptr ftctx = reindexer::static_ctx_pointer_cast(func.ctx); - auto& dataFtCtx = *ftctx->GetData(); - if (!dataFtCtx.isWordPositions_) { + auto& dataFtCtx = *(reindexer::static_ctx_pointer_cast>(ftctx->GetData())); + + if (!dataFtCtx.isWordPositions) { throw Error(errParams, "Snippet function does not work with ft_fuzzy index."); } - if (!func.tagsPath.empty()) { - throw Error(errConflict, "SetByJsonPath is not implemented yet!"); - } - if (!dataFtCtx.holders_.has_value()) { + if (!dataFtCtx.holders.has_value()) { return false; } - auto it = dataFtCtx.holders_->find(res.Id()); - if (it == dataFtCtx.holders_->end()) { + + auto it = dataFtCtx.holders->find(res.Id()); + if (it == dataFtCtx.holders->end()) { return false; } - Payload pl(pl_type, res.Value()); + Payload pl(plType, res.Value()); VariantArray kr; pl.Get(func.field, kr); @@ -287,7 +290,8 @@ bool Snippet::Process(ItemRef& res, PayloadType& pl_type, const SelectFuncStruct } const std::string* data = p_string(kr[0]).getCxxstr(); - auto pva = dataFtCtx.area_[it->second].GetAreas(func.fieldNo); + + auto pva = dataFtCtx.area[it->second].GetAreas(func.fieldNo); if (!pva || pva->Empty()) { return false; } @@ -295,7 +299,7 @@ bool Snippet::Process(ItemRef& res, PayloadType& pl_type, const SelectFuncStruct std::string resultString; resultString.reserve(data->size()); - RecalcZoneHelper recalcZoneHelper(*data, ftctx->GetData()->extraWordSymbols_, after_, before_, leftBound_, rightBound_); + RecalcZoneHelper recalcZoneHelper(*data, ftctx->GetData()->extraWordSymbols, after_, before_, leftBound_, rightBound_); if (needAreaStr_) { buildResultWithPrefix(recalcZoneHelper, *pva, *data, resultString); diff --git a/cpp_src/core/selectfunc/functions/snippet.h b/cpp_src/core/selectfunc/functions/snippet.h index d1240c8a5..c82dbda19 100644 --- a/cpp_src/core/selectfunc/functions/snippet.h +++ b/cpp_src/core/selectfunc/functions/snippet.h @@ -40,8 +40,8 @@ class Snippet { std::string_view leftBound_, rightBound_; }; - void buildResult(RecalcZoneHelper& recalcZoneHelper, const AreaBuffer& pva, const std::string& data, std::string& resultString); - void buildResultWithPrefix(RecalcZoneHelper& recalcZoneHelper, const AreaBuffer& pva, const std::string& data, + void buildResult(RecalcZoneHelper& recalcZoneHelper, const AreasInField& pva, const std::string& data, std::string& resultString); + void buildResultWithPrefix(RecalcZoneHelper& recalcZoneHelper, const AreasInField& pva, const std::string& data, std::string& resultString); bool isInit_ = false; diff --git a/cpp_src/core/selectfunc/selectfunc.cc b/cpp_src/core/selectfunc/selectfunc.cc index bd544d066..45f2474df 100644 --- a/cpp_src/core/selectfunc/selectfunc.cc +++ b/cpp_src/core/selectfunc/selectfunc.cc @@ -109,39 +109,6 @@ BaseFunctionCtx::Ptr SelectFunction::createFuncForProc(int indexNo) { } } -bool SelectFunction::NeedArea(int indexNo) const { - if (functions_.empty()) { - return false; - } - IndexType indexType = nm_.getIndexType(indexNo); - - auto checkField = [&](int field) -> bool { - const auto it = functions_.find(field); - if (it != functions_.end()) { - if (std::holds_alternative(it->second.func) || std::holds_alternative(it->second.func) || - std::holds_alternative(it->second.func)) { - return true; - } - } - return false; - }; - - if (IsComposite(indexType)) { - int cjsonFieldIdx = nm_.getIndexesCount(); - for (auto field : nm_.getIndexFields(indexNo)) { - if (field == IndexValueType::SetByJsonPath) { - field = cjsonFieldIdx++; - } - if (checkField(field)) { - return true; - } - } - } else { - return checkField(indexNo); - } - return false; -} - BaseFunctionCtx::Ptr SelectFunction::CreateCtx(int indexNo) { // we use this hack because ft always needs ctx to generate proc in response if (functions_.empty() && IsFullText(nm_.getIndexType(indexNo))) { @@ -220,8 +187,46 @@ bool SelectFunction::ProcessItem(ItemRef& res, PayloadType& pl_type, std::vector BaseFunctionCtx::Ptr SelectFunction::createCtx(SelectFuncStruct& data, BaseFunctionCtx::Ptr ctx, IndexType index_type) { if (IsFullText(index_type)) { if (!ctx) { - data.ctx = make_intrusive(); + switch (SelectFuncType(data.func.index())) { + case SelectFuncType::None: + data.ctx = make_intrusive(BaseFunctionCtx::CtxType::kFtCtx); + break; + case SelectFuncType::Snippet: + case SelectFuncType::Highlight: + case SelectFuncType::SnippetN: + data.ctx = make_intrusive(BaseFunctionCtx::CtxType::kFtArea); + break; + case SelectFuncType::DebugRank: + data.ctx = make_intrusive(BaseFunctionCtx::CtxType::kFtAreaDebug); + break; + case SelectFuncType::Max: + throw reindexer::Error(errLogic, "incorrect function type 'Max'"); + } } else { + switch (SelectFuncType(data.func.index())) { + case SelectFuncType::None: + if (ctx->type != BaseFunctionCtx::CtxType::kFtCtx) { + throw reindexer::Error(errLogic, "The existing calling context type '%d' does not allow this function", + int(ctx->type)); + } + break; + case SelectFuncType::Snippet: + case SelectFuncType::Highlight: + case SelectFuncType::SnippetN: + if (ctx->type != BaseFunctionCtx::CtxType::kFtArea) { + throw reindexer::Error(errLogic, "The existing calling context type '%d' does not allow this function", + int(ctx->type)); + } + break; + case SelectFuncType::DebugRank: + if (ctx->type != BaseFunctionCtx::CtxType::kFtAreaDebug) { + throw reindexer::Error(errLogic, "The existing calling context type '%d' does not allow this function", + int(ctx->type)); + } + break; + case SelectFuncType::Max: + throw reindexer::Error(errLogic, "incorrect function type 'Max'"); + } data.ctx = std::move(ctx); } const std::string& indexName = (data.indexNo >= nm_.getIndexesCount()) ? data.field : nm_.getIndexName(data.indexNo); diff --git a/cpp_src/core/selectfunc/selectfunc.h b/cpp_src/core/selectfunc/selectfunc.h index 169a54106..662d10ffc 100644 --- a/cpp_src/core/selectfunc/selectfunc.h +++ b/cpp_src/core/selectfunc/selectfunc.h @@ -24,7 +24,6 @@ class SelectFunction : public intrusive_atomic_rc_base { /// @param indexNo - number of index. /// @return pointer to a function context or null if some error happened. BaseFunctionCtx::Ptr CreateCtx(int indexNo); - bool NeedArea(int indexNo) const; private: BaseFunctionCtx::Ptr createCtx(SelectFuncStruct& data, BaseFunctionCtx::Ptr ctx, IndexType index_type); @@ -32,7 +31,7 @@ class SelectFunction : public intrusive_atomic_rc_base { BaseFunctionCtx::Ptr createFuncForProc(int indexNo); /// Containers of functions by index number. - fast_hash_map functions_; + RHashMap functions_; /// Interface to NsSelector object. NsSelectFuncInterface nm_; diff --git a/cpp_src/core/selectfunc/selectfuncparser.cc b/cpp_src/core/selectfunc/selectfuncparser.cc index 6c734664c..f55ef1344 100644 --- a/cpp_src/core/selectfunc/selectfuncparser.cc +++ b/cpp_src/core/selectfunc/selectfuncparser.cc @@ -190,38 +190,44 @@ SelectFuncStruct& SelectFuncParser::ParseFunction(tokenizer& parser, bool partOf static const Args args(4, {"pre_delim", "post_delim", "with_area", "left_bound", "right_bound"}); parsePositionalAndNamedArgs(parser, args); return selectFuncStruct_; + } else if (tok.text() == "debug_rank") { + selectFuncStruct_.func = DebugRank(); } selectFuncStruct_.funcName = std::string(tok.text()); tok = parser.next_token(tokenizer::flags::no_flags); if (tok.text() == "(") { - std::string arg; - while (!parser.end()) { - tok = parser.next_token(tokenizer::flags::no_flags); - if (tok.text() == ")") { - if (!partOfExpression) { - token nextTok = parser.next_token(tokenizer::flags::no_flags); - if (nextTok.text().length() > 0) { - throw Error(errParseDSL, "%s: Unexpected character `%s` after closing parenthesis", selectFuncStruct_.funcName, - nextTok.text()); + if (parser.peek_token(tokenizer::flags::no_flags).text() == ")") { + parser.next_token(tokenizer::flags::no_flags); + selectFuncStruct_.isFunction = true; + } else { + std::string arg; + while (!parser.end()) { + tok = parser.next_token(tokenizer::flags::no_flags); + if (tok.text() == ")") { + if (!partOfExpression) { + token nextTok = parser.next_token(tokenizer::flags::no_flags); + if (nextTok.text().length() > 0) { + throw Error(errParseDSL, "%s: Unexpected character `%s` after closing parenthesis", selectFuncStruct_.funcName, + nextTok.text()); + } } + selectFuncStruct_.funcArgs.emplace_back(std::move(arg)); + selectFuncStruct_.isFunction = true; + arg.clear(); + break; + } + if (tok.text() == "," && tok.type == TokenSymbol) { + selectFuncStruct_.funcArgs.emplace_back(std::move(arg)); + arg.clear(); + } else { + arg += tok.text(); } - selectFuncStruct_.funcArgs.emplace_back(std::move(arg)); - selectFuncStruct_.isFunction = true; - arg.clear(); - break; } - if (tok.text() == "," && tok.type == TokenSymbol) { - selectFuncStruct_.funcArgs.emplace_back(std::move(arg)); - arg.clear(); - } else { - arg += tok.text(); + if (!selectFuncStruct_.isFunction) { + throw Error(errParseDSL, "%s: The closing parenthesis is required, but found `%s`", selectFuncStruct_.funcName, tok.text()); } } - if (!selectFuncStruct_.isFunction) { - throw Error(errParseDSL, "%s: The closing parenthesis is required, but found `%s`. Select function name: `%s`", - selectFuncStruct_.funcName, tok.text(), selectFuncStruct_.funcName); - } } else { throw Error(errParseDSL, "%s: An open parenthesis is required, but found `%s`. Select function name: `%s`", selectFuncStruct_.funcName, tok.text(), selectFuncStruct_.funcName); diff --git a/cpp_src/core/selectfunc/selectfuncparser.h b/cpp_src/core/selectfunc/selectfuncparser.h index 0d7894f9e..ef5c45219 100644 --- a/cpp_src/core/selectfunc/selectfuncparser.h +++ b/cpp_src/core/selectfunc/selectfuncparser.h @@ -22,7 +22,7 @@ struct SelectFuncStruct { std::unordered_map namedArgs; BaseFunctionCtx::Ptr ctx; TagsPath tagsPath; - int indexNo = -1; + int indexNo = IndexValueType::NotSet; int fieldNo = 0; }; diff --git a/cpp_src/core/sorting/sortexpression.cc b/cpp_src/core/sorting/sortexpression.cc index a38482ffa..1003f0cfa 100644 --- a/cpp_src/core/sorting/sortexpression.cc +++ b/cpp_src/core/sorting/sortexpression.cc @@ -72,11 +72,11 @@ VariantArray SortExpression::GetJoinedFieldValues(IdType rowId, const joins::Nam const std::vector& joinedSelectors, size_t nsIdx, std::string_view column, int index) { const auto& js = joinedSelectors[nsIdx]; - std::reference_wrapper pt = - std::visit(overloaded{[](const JoinPreResult::Values& values) noexcept { return std::cref(values.payloadType); }, - Restricted{}( - [&js](const auto&) noexcept { return std::cref(js.rightNs_->payloadType_); })}, - js.PreResult().payload); + std::reference_wrapper pt = std::visit( + overloaded{ + [](const JoinPreResult::Values& values) noexcept { return std::cref(values.payloadType); }, + Restricted{}([&js](const auto&) noexcept { return std::cref(js.rightNs_->payloadType_); })}, + js.PreResult().payload); const ConstPayload pv{pt, getJoinedValue(rowId, joinResults, joinedSelectors, nsIdx)}; VariantArray values; if (index == IndexValueType::SetByJsonPath) { @@ -186,11 +186,11 @@ double DistanceBetweenJoinedIndexes::GetValue(IdType rowId, const joins::Namespa double DistanceBetweenJoinedIndexesSameNs::GetValue(IdType rowId, const joins::NamespaceResults& joinResults, const std::vector& joinedSelectors) const { const auto& js = joinedSelectors[nsIdx]; - std::reference_wrapper pt = - std::visit(overloaded{[](const JoinPreResult::Values& values) noexcept { return std::cref(values.payloadType); }, - Restricted{}( - [&js](const auto&) noexcept { return std::cref(js.rightNs_->payloadType_); })}, - js.PreResult().payload); + std::reference_wrapper pt = std::visit( + overloaded{ + [](const JoinPreResult::Values& values) noexcept { return std::cref(values.payloadType); }, + Restricted{}([&js](const auto&) noexcept { return std::cref(js.rightNs_->payloadType_); })}, + js.PreResult().payload); const ConstPayload pv{pt, SortExpression::getJoinedValue(rowId, joinResults, joinedSelectors, nsIdx)}; TagsMatcher tm = std::visit(overloaded{[](const JoinPreResult::Values& values) noexcept { return std::cref(values.tagsMatcher); }, Restricted{}( diff --git a/cpp_src/debug/backtrace.h b/cpp_src/debug/backtrace.h index d55d9bd38..29c629634 100644 --- a/cpp_src/debug/backtrace.h +++ b/cpp_src/debug/backtrace.h @@ -1,8 +1,8 @@ #pragma once #include -#include #include +#include namespace reindexer { namespace debug { diff --git a/cpp_src/estl/tokenizer.cc b/cpp_src/estl/tokenizer.cc index 37e1f09a9..c434142b2 100644 --- a/cpp_src/estl/tokenizer.cc +++ b/cpp_src/estl/tokenizer.cc @@ -1,4 +1,5 @@ #include "tokenizer.h" +#include "double-conversion/double-conversion.h" #include "tools/stringstools.h" namespace reindexer { @@ -182,4 +183,55 @@ std::string tokenizer::where() const { .append(std::to_string(q_.size())); } +Variant getVariantFromToken(const token& tok) { + const std::string_view str = tok.text(); + if (tok.type != TokenNumber || str.empty()) { + return Variant(make_key_string(str.data(), str.length())); + } + + if (!isdigit(str[0]) && (str.size() == 1 || (str[0] != '+' && str[0] != '-'))) { + return Variant(make_key_string(str.data(), str.length())); + } + + bool isFloat = false; + // INT64_MAX(9'223'372'036'854'775'807) contains 19 digits + 1 for possible sign + const size_t maxSignsInInt = 19 + (isdigit(str[0]) ? 0 : 1); + bool nullDecimalPart = true; + + size_t decPointPos = str.size(); + for (unsigned i = 1; i < str.size(); i++) { + if (str[i] == '.') { + if (isFloat) { + // second point - not a number + return Variant(make_key_string(str.data(), str.length())); + } + + decPointPos = i; + + isFloat = true; + continue; + } + + if (!isdigit(str[i])) { + return Variant(make_key_string(str.data(), str.length())); + } + + if (isFloat) { + nullDecimalPart = nullDecimalPart && str[i] == '0'; + } + } + + isFloat = !nullDecimalPart || (isFloat && decPointPos > maxSignsInInt); + + if (!isFloat) { + auto intPart = str.substr(0, decPointPos); + return intPart.size() <= maxSignsInInt ? Variant(stoll(intPart)) : Variant(make_key_string(str.data(), str.length())); + } + + using double_conversion::StringToDoubleConverter; + static const StringToDoubleConverter converter{StringToDoubleConverter::NO_FLAGS, NAN, NAN, nullptr, nullptr}; + int countOfCharsParsedAsDouble = 0; + return Variant(converter.StringToDouble(str.data(), str.size(), &countOfCharsParsedAsDouble)); +} + } // namespace reindexer diff --git a/cpp_src/estl/tokenizer.h b/cpp_src/estl/tokenizer.h index 5382e93d3..1304e7268 100644 --- a/cpp_src/estl/tokenizer.h +++ b/cpp_src/estl/tokenizer.h @@ -89,5 +89,6 @@ class tokenizer { enum class CompositeAllowed : bool { No = false, Yes = true }; enum class FieldAllowed : bool { No = false, Yes = true }; Variant token2kv(const token& currTok, tokenizer& parser, CompositeAllowed allowComposite, FieldAllowed allowField); +Variant getVariantFromToken(const token& tok); } // namespace reindexer diff --git a/cpp_src/gtests/bench/ft_bench.cc b/cpp_src/gtests/bench/ft_bench.cc index c0bdb667d..4d2b64b6e 100644 --- a/cpp_src/gtests/bench/ft_bench.cc +++ b/cpp_src/gtests/bench/ft_bench.cc @@ -9,8 +9,6 @@ #include "ft_fixture.h" #include "ft_merge_limit.h" -const std::string kStoragePath = "/tmp/reindex/ft_bench_test"; - using std::shared_ptr; using reindexer::Reindexer; @@ -23,15 +21,16 @@ const int kItemsInBenchDataset = 100'000; #endif int main(int argc, char** argv) { - if (reindexer::fs::RmDirAll(kStoragePath) < 0 && errno != ENOENT) { - std::cerr << "Could not clean working dir '" << kStoragePath << "'."; + const auto storagePath = reindexer::fs::JoinPath(reindexer::fs::GetTempDir(), "reindex/ft_bench_test"); + if (reindexer::fs::RmDirAll(storagePath) < 0 && errno != ENOENT) { + std::cerr << "Could not clean working dir '" << storagePath << "'."; std::cerr << "Reason: " << strerror(errno) << std::endl; return 1; } - shared_ptr DB = std::make_shared(); - auto err = DB->Connect("builtin://" + kStoragePath); + auto DB = std::make_shared(); + auto err = DB->Connect("builtin://" + storagePath); if (!err.ok()) { return err.code(); } diff --git a/cpp_src/gtests/bench/reindexer_bench.cc b/cpp_src/gtests/bench/reindexer_bench.cc index 669055241..1a094ac9b 100644 --- a/cpp_src/gtests/bench/reindexer_bench.cc +++ b/cpp_src/gtests/bench/reindexer_bench.cc @@ -16,8 +16,6 @@ #include "core/reindexer.h" -const std::string kStoragePath = "/tmp/reindex/bench_test"; - using std::shared_ptr; using reindexer::Reindexer; @@ -33,15 +31,16 @@ const int kItemsInComparatorsBenchDataset = 100'000; #endif int main(int argc, char** argv) { - if (reindexer::fs::RmDirAll(kStoragePath) < 0 && errno != ENOENT) { - std::cerr << "Could not clean working dir '" << kStoragePath << "'."; + const auto storagePath = reindexer::fs::JoinPath(reindexer::fs::GetTempDir(), "reindex/bench_test"); + if (reindexer::fs::RmDirAll(storagePath) < 0 && errno != ENOENT) { + std::cerr << "Could not clean working dir '" << storagePath << "'."; std::cerr << "Reason: " << strerror(errno) << std::endl; return 1; } - shared_ptr DB = std::make_shared(); - auto err = DB->Connect("builtin://" + kStoragePath); + auto DB = std::make_shared(); + auto err = DB->Connect("builtin://" + storagePath); if (!err.ok()) { return err.code(); } diff --git a/cpp_src/gtests/tests/API/base_tests.cc b/cpp_src/gtests/tests/API/base_tests.cc index c85115c00..9afcf8693 100644 --- a/cpp_src/gtests/tests/API/base_tests.cc +++ b/cpp_src/gtests/tests/API/base_tests.cc @@ -1218,7 +1218,7 @@ TEST_F(ReindexerApi, DslFieldsTest) { } }, { - "op": "OR", + "op": "AND", "join_query": { "type": "left", "namespace": "test2", @@ -2073,9 +2073,11 @@ TEST_F(ReindexerApi, IntFieldConvertToStringIndexTest) { } TEST_F(ReindexerApi, MetaIndexTest) { - const std::string kBaseTestsStoragePath = reindexer::fs::JoinPath(reindexer::fs::GetTempDir(), "reindex/api_meta_storage/"); + const auto storagePath = reindexer::fs::JoinPath(reindexer::fs::GetTempDir(), "reindex/meta_index_test/"); + reindexer::fs::RmDirAll(storagePath); // ignore result + auto rx = std::make_unique(); - auto err = rx->Connect("builtin://" + kBaseTestsStoragePath); + auto err = rx->Connect("builtin://" + storagePath); ASSERT_TRUE(err.ok()) << err.what(); err = rx->OpenNamespace(default_namespace, StorageOpts().Enabled().CreateIfMissing()); @@ -2184,3 +2186,80 @@ TEST_F(ReindexerApi, MetaIndexTest) { ASSERT_TRUE(err.ok()) << err.what(); ASSERT_EQ(readKeys, std::vector{}); } + +TEST_F(ReindexerApi, QueryResultsLSNTest) { + using namespace std::string_view_literals; + constexpr int kDataCount = 10; + + rt.OpenNamespace(default_namespace, StorageOpts().Enabled(false)); + rt.AddIndex(default_namespace, {"id", "hash", "int", IndexOpts().PK()}); + + for (int i = 0; i < kDataCount; ++i) { + auto item = rt.NewItem(default_namespace); + item["id"] = i; + rt.Upsert(default_namespace, item); + } + + // Select and save current LSNs + auto qr = rt.Select(Query(default_namespace)); + ASSERT_EQ(qr.Count(), kDataCount); + auto& local = qr.ToLocalQr(); + std::vector lsns; + lsns.reserve(kDataCount); + for (auto& it : local) { + auto lsn = it.GetLSN(); + ASSERT_FALSE(lsn.isEmpty()); + lsns.emplace_back(lsn); + } + + { + // Modify data in different ways + const auto updated = rt.Update(Query(default_namespace).Where("id", CondEq, 0).Set("data", {Variant{"modified_0"sv}})); + ASSERT_EQ(updated, 1); + const auto deleted = rt.Delete(Query(default_namespace).Where("id", CondEq, 1)); + ASSERT_EQ(deleted, 1); + auto delItem = rt.NewItem(default_namespace); + delItem["id"] = 2; + rt.Delete(default_namespace, delItem); + rt.UpsertJSON(default_namespace, R"j({"id":3, "data":"modified_3"})j"); + } + + { + // Modify data via transaction + auto tx = rt.reindexer->NewTransaction(default_namespace); + ASSERT_TRUE(tx.Status().ok()) << tx.Status().what(); + + auto updQ = Query(default_namespace).Where("id", CondEq, 4).Set("data", {Variant{"modified_4"sv}}); + updQ.type_ = QueryUpdate; + auto err = tx.Modify(std::move(updQ)); + ASSERT_TRUE(err.ok()) << err.what(); + + auto delQ = Query(default_namespace).Where("id", CondEq, 5); + delQ.type_ = QueryDelete; + err = tx.Modify(std::move(delQ)); + ASSERT_TRUE(err.ok()) << err.what(); + + auto delItem = tx.NewItem(); + delItem["id"] = 6; + err = tx.Delete(std::move(delItem)); + ASSERT_TRUE(err.ok()) << err.what(); + auto updItem = tx.NewItem(); + updItem["id"] = 7; + updItem["data"] = "modified_7"; + err = tx.Update(std::move(updItem)); + ASSERT_TRUE(err.ok()) << err.what(); + QueryResults qr; + err = rt.reindexer->CommitTransaction(tx, qr); + ASSERT_TRUE(err.ok()) << err.what(); + } + + // Truncate all remaining data + auto err = rt.reindexer->TruncateNamespace(default_namespace); + ASSERT_TRUE(err.ok()) << err.what(); + + // Check, that LSNs did not changed for the existing Qr + for (size_t i = 0; i < kDataCount; ++i) { + auto lsn = (local.begin() + i).GetLSN(); + ASSERT_EQ(lsn, lsns[i]) << i; + } +} diff --git a/cpp_src/gtests/tests/fixtures/ft_api.cc b/cpp_src/gtests/tests/fixtures/ft_api.cc index 24b9f1c2b..b0e264bd9 100644 --- a/cpp_src/gtests/tests/fixtures/ft_api.cc +++ b/cpp_src/gtests/tests/fixtures/ft_api.cc @@ -1,7 +1,7 @@ #include "ft_api.h" void FTApi::Init(const reindexer::FtFastConfig& ftCfg, unsigned nses, const std::string& storage) { - rt.reindexer.reset(new reindexer::Reindexer); + rt.reindexer = std::make_shared(); if (!storage.empty()) { auto err = rt.reindexer->Connect("builtin://" + storage); ASSERT_TRUE(err.ok()) << err.what(); @@ -148,11 +148,11 @@ void FTApi::AddInBothFields(std::string_view ns, std::string_view w1, std::strin rt.Upsert(ns, item); } -reindexer::QueryResults FTApi::SimpleSelect(std::string word, bool withHighlight) { - auto q{reindexer::Query("nm1").Where("ft3", CondEq, std::move(word)).WithRank()}; +reindexer::QueryResults FTApi::SimpleSelect(std::string_view ns, std::string_view index, std::string_view dsl, bool withHighlight) { + auto q{reindexer::Query(ns).Where(index, CondEq, std::string(dsl)).WithRank()}; reindexer::QueryResults res; if (withHighlight) { - q.AddFunction("ft3 = highlight(!,!)"); + q.AddFunction(fmt::format("{} = highlight(!,!)", index)); } auto err = rt.reindexer->Select(q, res); EXPECT_TRUE(err.ok()) << err.what(); @@ -160,15 +160,6 @@ reindexer::QueryResults FTApi::SimpleSelect(std::string word, bool withHighlight return res; } -reindexer::QueryResults FTApi::SimpleSelect3(std::string word) { - auto qr{reindexer::Query("nm3").Where("ft", CondEq, std::move(word))}; - reindexer::QueryResults res; - qr.AddFunction("ft = highlight(!,!)"); - auto err = rt.reindexer->Select(qr, res); - EXPECT_TRUE(err.ok()) << err.what(); - return res; -} - reindexer::Error FTApi::Delete(int id) { reindexer::Item item = rt.NewItem("nm1"); item["id"] = id; diff --git a/cpp_src/gtests/tests/fixtures/ft_api.h b/cpp_src/gtests/tests/fixtures/ft_api.h index e4e1a7fa4..b9c4655f3 100644 --- a/cpp_src/gtests/tests/fixtures/ft_api.h +++ b/cpp_src/gtests/tests/fixtures/ft_api.h @@ -28,9 +28,11 @@ class FTApi : public ::testing::TestWithParam(); } Data randomItemData() { diff --git a/cpp_src/gtests/tests/fixtures/queries_api.h b/cpp_src/gtests/tests/fixtures/queries_api.h index 06b35b5b1..a5a3d6de5 100644 --- a/cpp_src/gtests/tests/fixtures/queries_api.h +++ b/cpp_src/gtests/tests/fixtures/queries_api.h @@ -736,11 +736,11 @@ class QueriesApi : public ReindexerApi, public QueriesVerifier { .Distinct(distinct.c_str()) .Sort(kFieldNameYear, true)); - ExecuteAndVerifyWithSql(Query(default_namespace) - .Select({distinct.c_str()}) - .Distinct(distinct.c_str()) - .Where(kFieldNameGenre, CondEq, randomGenre) - .Sort(kFieldNameYear, true)); + ExecuteAndVerifyWithSql(Query(default_namespace) + .Select({distinct.c_str()}) + .Distinct(distinct.c_str()) + .Where(kFieldNameGenre, CondEq, randomGenre) + .Sort(kFieldNameYear, true)); } } diff --git a/cpp_src/gtests/tests/fixtures/reindexertestapi.h b/cpp_src/gtests/tests/fixtures/reindexertestapi.h index 9d174717e..fdafd81f8 100644 --- a/cpp_src/gtests/tests/fixtures/reindexertestapi.h +++ b/cpp_src/gtests/tests/fixtures/reindexertestapi.h @@ -78,8 +78,8 @@ class ReindexerTestApi { ASSERT_TRUE(err.ok()) << err.what(); ASSERT_TRUE(item.Status().ok()) << item.Status().what(); } - void OpenNamespace(std::string_view ns) { - auto err = reindexer->WithTimeout(kBasicTimeout).OpenNamespace(ns); + void OpenNamespace(std::string_view ns, const StorageOpts& storage = StorageOpts()) { + auto err = reindexer->WithTimeout(kBasicTimeout).OpenNamespace(ns, storage); ASSERT_TRUE(err.ok()) << err.what() << "; namespace: " << ns; } void AddIndex(std::string_view ns, const reindexer::IndexDef& idef) { @@ -141,6 +141,10 @@ class ReindexerTestApi { EXPECT_TRUE(err.ok()) << err.what() << "; " << q.GetSQL(QueryDelete); return qr.Count(); } + void Delete(const reindexer::Query& q, QueryResultsType& qr) { + auto err = reindexer->Delete(q, qr); + EXPECT_TRUE(err.ok()) << err.what() << "; " << q.GetSQL(QueryDelete); + } reindexer::Error DumpIndex(std::ostream& os, std::string_view ns, std::string_view index) { return reindexer->DumpIndex(os, ns, index); } diff --git a/cpp_src/gtests/tests/fixtures/servercontrol.cc b/cpp_src/gtests/tests/fixtures/servercontrol.cc index 2bc2fb195..2cd149f51 100644 --- a/cpp_src/gtests/tests/fixtures/servercontrol.cc +++ b/cpp_src/gtests/tests/fixtures/servercontrol.cc @@ -60,10 +60,13 @@ ServerControl::ServerControl(ServerControl&& rhs) noexcept { rhs.stopped_ = nullptr; } ServerControl& ServerControl::operator=(ServerControl&& rhs) noexcept { - WLock lock(rhs.mtx_); - interface = std::move(rhs.interface); - stopped_ = rhs.stopped_; - rhs.stopped_ = nullptr; + if (this != &rhs) { + WLock lock(rhs.mtx_); + interface = std::move(rhs.interface); + delete stopped_; + stopped_ = rhs.stopped_; + rhs.stopped_ = nullptr; + } return *this; } diff --git a/cpp_src/gtests/tests/fixtures/storage_lazy_load.h b/cpp_src/gtests/tests/fixtures/storage_lazy_load.h index f6b040af0..1455d0e9b 100644 --- a/cpp_src/gtests/tests/fixtures/storage_lazy_load.h +++ b/cpp_src/gtests/tests/fixtures/storage_lazy_load.h @@ -5,7 +5,7 @@ class DISABLED_StorageLazyLoadApi : public ReindexerApi { public: - DISABLED_StorageLazyLoadApi() : pk_(0), inserted_(0) { rt.reindexer.reset(new Reindexer); } + DISABLED_StorageLazyLoadApi() : pk_(0), inserted_(0) { rt.reindexer = std::make_shared(); } ~DISABLED_StorageLazyLoadApi() { dropNs(); } void SetUp() override { diff --git a/cpp_src/gtests/tests/unit/ft/ft_generic.cc b/cpp_src/gtests/tests/unit/ft/ft_generic.cc index 308fa2c1a..7d8639443 100644 --- a/cpp_src/gtests/tests/unit/ft/ft_generic.cc +++ b/cpp_src/gtests/tests/unit/ft/ft_generic.cc @@ -70,7 +70,7 @@ TEST_P(FTGenericApi, CompositeSelect) { continue; } auto it = data.find(ritem[field].As()); - ASSERT_TRUE(it != data.end()); + ASSERT_TRUE(it != data.end()) << ritem[field].As(); data.erase(it); } } @@ -234,6 +234,7 @@ TEST_P(FTGenericApi, SelectWithDistance) { TEST_P(FTGenericApi, AreasOnSuffix) { auto ftCfg = GetDefaultConfig(); + ftCfg.optimization = reindexer::FtFastConfig::Optimization::CPU; Init(ftCfg); Add("the nos1 the nos2 the nosmn the nose"sv); @@ -249,6 +250,169 @@ TEST_P(FTGenericApi, AreasOnSuffix) { CheckResults("+nos* +*mask ", {{"the !nos1! the !mmask! stop !nos2! table", ""}}, false); } +TEST_P(FTGenericApi, DebugInfo) { + auto ftCfg = GetDefaultConfig(); + Init(ftCfg); + + Add("Маша ела кашу. Каша кушалась сама. Машу ругали."sv); + Add("Коля, Сеня гуляли."sv); + Add("слово простая фраза что то еще."sv); + Add("слово начало простая фраза конец что то еще простая фраза слово слово."sv); + Add("жил пил гулял"sv); + + auto removeLineEnd = [](std::vector& dataCompare) { + for (auto& s : dataCompare) { + s.erase(std::remove(s.begin(), s.end(), '\n'), s.end()); + } + }; + + { + reindexer::Query q("nm1"); + q.Where("ft3", CondEq, "маша"); + q.AddFunction("ft3 = debug_rank()"); + q.Select({"ft1"}); + reindexer::QueryResults res; + auto err = rt.reindexer->Select(q, res); + EXPECT_TRUE(err.ok()) << err.what(); + ASSERT_EQ(res.Count(), 1); + auto it = res.begin(); + reindexer::WrSerializer wrSer; + err = it.GetJSON(wrSer, false); + ASSERT_TRUE(err.ok()) << err.what(); + // clang-format off + std::vector dataCompare={R"({"ft1": +"{term_rank:97, term:маша, pattern:маша, bm25_norm:0.9798439468181269, term_len_boost:1, position_rank:1, norm_dist:0, proc:100, full_match_boost:0} Маша ела кашу. Каша кушалась сама. + {term_rank:77, term:маша, pattern:машу, bm25_norm:0.9798439468181269, term_len_boost:1, position_rank:0.994, norm_dist:0, proc:80, full_match_boost:0} Машу ругали."})"}; + // clang-format on + removeLineEnd(dataCompare); + ASSERT_EQ(wrSer.Slice(), dataCompare[0]); + } + + { + reindexer::Query q("nm1"); + q.Where("ft3", CondEq, "коля сеня"); + q.AddFunction("ft3 = debug_rank()"); + q.Select({"ft1"}); + reindexer::QueryResults res; + auto err = rt.reindexer->Select(q, res); + EXPECT_TRUE(err.ok()) << err.what(); + ASSERT_EQ(res.Count(), 1); + auto it = res.begin(); + reindexer::WrSerializer wrSer; + err = it.GetJSON(wrSer, false); + ASSERT_TRUE(err.ok()) << err.what(); + // clang-format off + std::vector dataCompare={R"({"ft1": +"{term_rank:102, term:коля, pattern:коля, bm25_norm:1.022314131295854, term_len_boost:1, position_rank:1, norm_dist:0, proc:100, full_match_boost:0} Коля, + {term_rank:102, term:сеня, pattern:сеня, bm25_norm:1.022314131295854, term_len_boost:1, position_rank:0.999, norm_dist:0, proc:100, full_match_boost:0} Сеня гуляли."})"}; + // clang-format on + removeLineEnd(dataCompare); + ASSERT_EQ(wrSer.Slice(), dataCompare[0]); + } + + { + reindexer::Query q("nm1"); + q.Where("ft3", CondEq, "'начало простая фраза конец' 'простая фраза'"); + q.AddFunction("ft3 = debug_rank()"); + q.Select({"ft1"}); + q.Sort("id", false); + q.WithRank(); + // clang-format off + std::vector dataCompare={ +R"###({"ft1":"слово + {term_rank:93, term:простая, pattern:простая, bm25_norm:0.9399331930048559, term_len_boost:1, position_rank:0.999, norm_dist:0, proc:100, full_match_boost:0} простая + {term_rank:85, term:фраза, pattern:фраза, bm25_norm:0.9399331930048559, term_len_boost:0.9142857193946838, position_rank:0.998, norm_dist:0, proc:100, full_match_boost:0} фраза + что то еще.","rank()":101.0})###", +R"##({"ft1":"слово + {term_rank:92, term:начало, pattern:начало, bm25_norm:0.9624865670750559, term_len_boost:0.9571428596973419, position_rank:0.999, norm_dist:0, proc:100, full_match_boost:0} начало + {term_rank:94, term:простая, pattern:простая, bm25_norm:0.9436916111700189, term_len_boost:1, position_rank:0.998, norm_dist:0, proc:100, full_match_boost:0} + {term_rank:94, term:простая, pattern:простая, bm25_norm:0.9436916111700189, term_len_boost:1, position_rank:0.998, norm_dist:0, proc:100, full_match_boost:0} простая + {term_rank:86, term:фраза, pattern:фраза, bm25_norm:0.9436916111700189, term_len_boost:0.9142857193946838, position_rank:0.997, norm_dist:0, proc:100, full_match_boost:0} + {term_rank:86, term:фраза, pattern:фраза, bm25_norm:0.9436916111700189, term_len_boost:0.9142857193946838, position_rank:0.997, norm_dist:0, proc:100, full_match_boost:0} фраза + {term_rank:87, term:конец, pattern:конец, bm25_norm:0.9624865670750559, term_len_boost:0.9142857193946838, position_rank:0.996, norm_dist:0, proc:100, full_match_boost:0} конец + что то еще + {term_rank:94, term:простая, pattern:простая, bm25_norm:0.9436916111700189, term_len_boost:1, position_rank:0.998, norm_dist:0, proc:100, full_match_boost:0} простая + {term_rank:86, term:фраза, pattern:фраза, bm25_norm:0.9436916111700189, term_len_boost:0.9142857193946838, position_rank:0.997, norm_dist:0, proc:100, full_match_boost:0} фраза + слово слово.","rank()":255.0})##" + }; + // clang-format on + removeLineEnd(dataCompare); + reindexer::QueryResults res; + auto err = rt.reindexer->Select(q, res); + EXPECT_TRUE(err.ok()) << err.what(); + ASSERT_EQ(res.Count(), 2); + + size_t i = 0; + for (auto it : res) { + reindexer::WrSerializer wrSer; + err = it.GetJSON(wrSer, false); + ASSERT_TRUE(err.ok()) << err.what(); + ASSERT_EQ(dataCompare[i], wrSer.Slice()); + i++; + } + } + + { + reindexer::Query q("nm1"); + q.Where("ft3", CondEq, "'простыми фразами'"); + q.AddFunction("ft3 = debug_rank()"); + q.Select({"ft1"}); + q.Sort("id", false); + // clang-format off + std::vector dataCompare={ +R"###({"ft1":"слово + {term_rank:74, term:простыми, pattern:простая, bm25_norm:0.9399331930048559, term_len_boost:1, position_rank:0.999, norm_dist:0, proc:79, full_match_boost:0} простая + {term_rank:74, term:фразами, pattern:фраза, bm25_norm:0.9399331930048559, term_len_boost:0.9624999999999999, position_rank:0.998, norm_dist:0, proc:82, full_match_boost:0} фраза + что то еще."})###", +R"###({"ft1":"слово начало + {term_rank:74, term:простыми, pattern:простая, bm25_norm:0.9436916111700189, term_len_boost:1, position_rank:0.998, norm_dist:0, proc:79, full_match_boost:0} простая + {term_rank:74, term:фразами, pattern:фраза, bm25_norm:0.9436916111700189, term_len_boost:0.9624999999999999, position_rank:0.997, norm_dist:0, proc:82, full_match_boost:0} фраза + конец что то еще + {term_rank:74, term:простыми, pattern:простая, bm25_norm:0.9436916111700189, term_len_boost:1, position_rank:0.998, norm_dist:0, proc:79, full_match_boost:0} простая + {term_rank:74, term:фразами, pattern:фраза, bm25_norm:0.9436916111700189, term_len_boost:0.9624999999999999, position_rank:0.997, norm_dist:0, proc:82, full_match_boost:0} фраза + слово слово."})###" + }; + // clang-format on + removeLineEnd(dataCompare); + + reindexer::QueryResults res; + auto err = rt.reindexer->Select(q, res); + EXPECT_TRUE(err.ok()) << err.what(); + ASSERT_EQ(res.Count(), 2); + size_t i = 0; + for (auto it : res) { + reindexer::WrSerializer wrSer; + err = it.GetJSON(wrSer, false); + EXPECT_TRUE(err.ok()) << err.what(); + ASSERT_EQ(dataCompare[i], wrSer.Slice()); + i++; + } + } + + { + reindexer::Query q("nm1"); + q.Where("ft3", CondEq, "жил~ пил"); + q.Select({"ft1"}); + q.AddFunction("ft3 = debug_rank()"); + reindexer::QueryResults res; + auto err = rt.reindexer->Select(q, res); + EXPECT_TRUE(err.ok()) << err.what(); + ASSERT_EQ(res.Count(), 1); + auto it = res.begin(); + reindexer::WrSerializer wrSer; + err = it.GetJSON(wrSer, false); + ASSERT_TRUE(err.ok()) << err.what(); + //clang-format off + std::vector dataCompare = { + R"({"ft1":"{term_rank:102, term:жил, pattern:жил, bm25_norm:1.022314131295854, term_len_boost:1, position_rank:1, norm_dist:0, proc:100, full_match_boost:0} жил + {term_rank:71, term:жил, pattern:ил, bm25_norm:1.022314131295854, term_len_boost:1, position_rank:0.999, norm_dist:0, proc:70, full_match_boost:0} + {term_rank:102, term:пил, pattern:пил, bm25_norm:1.022314131295854, term_len_boost:1, position_rank:0.999, norm_dist:0, proc:100, full_match_boost:0} пил гулял"})"}; + //clang-format on + removeLineEnd(dataCompare); + ASSERT_EQ(wrSer.Slice(), dataCompare[0]); + } +} + TEST_P(FTGenericApi, AreasMaxRank) { auto ftCfg = GetDefaultConfig(); ftCfg.maxAreasInDoc = 3; diff --git a/cpp_src/gtests/tests/unit/ft/ft_incremental_build.cc b/cpp_src/gtests/tests/unit/ft/ft_incremental_build.cc index 577422741..10b6c9c42 100644 --- a/cpp_src/gtests/tests/unit/ft/ft_incremental_build.cc +++ b/cpp_src/gtests/tests/unit/ft/ft_incremental_build.cc @@ -29,7 +29,7 @@ class FTIncrementalBuildApi : public FTApi { enum class StrictSuffixValidation { No, Yes }; void Init(const reindexer::FtFastConfig& ftCfg) { - rt.reindexer.reset(new reindexer::Reindexer); + rt.reindexer = std::make_shared(); auto err = rt.reindexer->OpenNamespace(GetDefaultNamespace()); ASSERT_TRUE(err.ok()) << err.what(); rt.DefineNamespaceDataset(GetDefaultNamespace(), {IndexDeclaration{"id", "hash", "int", IndexOpts().PK(), 0}, diff --git a/cpp_src/gtests/tests/unit/ft/ft_min_relevance.cc b/cpp_src/gtests/tests/unit/ft/ft_min_relevance.cc new file mode 100644 index 000000000..a1f831d5f --- /dev/null +++ b/cpp_src/gtests/tests/unit/ft/ft_min_relevance.cc @@ -0,0 +1,78 @@ +#include +#include "ft_api.h" + +class FTMinRelevanceApi : public FTApi { +protected: + std::string_view GetDefaultNamespace() noexcept override { return "ft_min_relevance"; } + void CreateNs() { + const std::string_view nmName = GetDefaultNamespace(); + rt.OpenNamespace(nmName); + rt.DefineNamespaceDataset(nmName, {IndexDeclaration{"id", "hash", "int", IndexOpts().PK(), 0}, + IndexDeclaration{"ft1", "text", "string", IndexOpts(), 0}}); + reindexer::FtFastConfig cfg(0); + cfg.enableNumbersSearch = true; + cfg.logLevel = 5; + cfg.maxStepSize = 100; + auto err = SetFTConfig(cfg, nmName, "ft1", {"ft1"}); + ASSERT_TRUE(err.ok()) << err.what(); + } + std::set SelectIDs(std::string_view str) { + auto qr = SimpleSelect(GetDefaultNamespace(), "ft1", str, false); + std::set selectDocs; + for (auto v : qr) { + reindexer::Item it = v.GetItem(); + selectDocs.insert(it["id"].As()); + } + return selectDocs; + } + void DelDocuments() { + auto deleted = rt.Delete(reindexer::Query(GetDefaultNamespace()).Where("ft1", CondEq, words_[deleteWordIndex_])); + ASSERT_GT(deleted, 0); + } + + const size_t deleteWordIndex_ = 1; + const std::vector words_{"машина", "стол", "велосипед", "автобус"}; +}; + +TEST_F(FTMinRelevanceApi, CorrectDocWithMinRelevanceAndEmptyDoc) { + CreateNs(); + + // Fill namespace + std::map>> docs; + std::set deleteDocs; + int id = 0; + constexpr int vDocCount = 300; + const std::string_view nmName = GetDefaultNamespace(); + for (int i = 0; i < vDocCount; i++) { + auto [it, _] = docs.insert(std::make_pair(i, std::map>())); + for (int k = 0; k < (i % 10) + 1; k++) { + const size_t w1 = rand() % words_.size(); + const size_t w2 = rand() % words_.size(); + if (w1 == deleteWordIndex_ || w2 == deleteWordIndex_) { + deleteDocs.insert(id); + } + std::string doc = words_[w1] + " " + words_[w2] + " " + std::to_string(i); + it->second.insert(std::make_pair(id, std::make_pair(doc, true))); + reindexer::Item item = rt.NewItem(nmName); + item["id"] = id; + item["ft1"] = doc; + rt.Upsert(nmName, item); + id++; + } + SelectIDs("build"); + } + // Delete documents with some unique word + DelDocuments(); + + // Check, that there are no deleted docs in results + const auto selectDocs = SelectIDs("машина автобус"); + std::vector intersection; + std::set_intersection(deleteDocs.begin(), deleteDocs.end(), selectDocs.begin(), selectDocs.end(), std::back_inserter(intersection)); + if (!intersection.empty()) { + std::stringstream ss; + for (auto& v : intersection) { + ss << v << " "; + } + ASSERT_TRUE(false) << "Intersection must be empty: " << ss.str(); + } +} diff --git a/cpp_src/gtests/tests/unit/index_tuple_test.cc b/cpp_src/gtests/tests/unit/index_tuple_test.cc deleted file mode 100644 index e89040f4c..000000000 --- a/cpp_src/gtests/tests/unit/index_tuple_test.cc +++ /dev/null @@ -1,515 +0,0 @@ -#include -#include "reindexer_api.h" -#include "tools/fsops.h" - -class IndexTupleTest : public ReindexerApi { -public: - void SetUp() override { - const std::string kStoragePath = reindexer::fs::JoinPath(reindexer::fs::GetTempDir(), "IndexTupleTest"); - reindexer::fs::RmDirAll(kStoragePath); - auto err = rt.reindexer->Connect(std::string("builtin://") + kStoragePath); - ASSERT_TRUE(err.ok()) << err.what(); - } - - void CreateEmptyNamespace(std::string_view ns) { return createNS(ns, R"json({"id":%d})json"); } - - void CreateNamespace(std::string_view ns) { - static const char pattern[] = - R"json({"id":%d,"objs":[{"fld":1},{"fld":2},{"fld":5}],"obj":{"nested":0},"last":{"text":"OK","1st":{"2nd":{"3rd":3.14}}},"arr":[{"nested_arr":[{"field":[3,2,1]},{"field":11},{"field":[9]}]}]})json"; - createNS(ns, pattern); - } - - void CreateSparseNamespace(std::string_view ns) { return createNS(ns, R"json({"id":%d,"fld1":1,"fld2":{"nested":"test"}})json"); } - - void CreateArrayNamespace(std::string_view ns) { - static const char pattern[] = R"json({"id":%d,"obj":{"val":10},"arr":[1,2,3]})json"; - return createNS(ns, pattern); - } - - void DoTestDefault(const std::shared_ptr& reindexer, std::string_view ns, const reindexer::IndexDef& indexDef, - std::string_view pattern, std::string_view field, const VariantArray& expectedValues, - std::string_view description) const { - auto err = rt.reindexer->AddIndex(ns, indexDef); - ASSERT_TRUE(err.ok()) << err.what() << "\n" << description; - - validateResults(reindexer, ns, pattern, field, expectedValues, description); - } - - void DoTestEmpty(const std::shared_ptr& reindexer, std::string_view ns, const reindexer::IndexDef& indexDef, - std::string_view pattern, std::string_view description) const { - auto err = reindexer->AddIndex(ns, indexDef); - ASSERT_TRUE(err.ok()) << err.what(); - - checkExpectations(reindexer, ns, pattern, description); - } - - void DoCallAndCheckError(const std::shared_ptr& reindexer, std::string_view ns, - const reindexer::IndexDef& indexDef, std::string_view errMsg) const { - std::vector items; - getItems(reindexer, ns, items); - - auto err = reindexer->AddIndex(ns, indexDef); - ASSERT_FALSE(err.ok()); - ASSERT_EQ(err.what(), errMsg); - - checkItems(reindexer, ns, items); - } - - void ValidateReloadState(const std::shared_ptr& reindexer, std::string_view ns, std::string_view pattern, - std::string_view description) const { - auto err = rt.reindexer->CloseNamespace(ns); - ASSERT_TRUE(err.ok()) << err.what(); - - err = rt.reindexer->OpenNamespace(ns, StorageOpts().Enabled().CreateIfMissing().VerifyChecksums()); - ASSERT_TRUE(err.ok()) << err.what(); - - checkExpectations(reindexer, ns, pattern, description); - - // remove storage - err = rt.reindexer->DropNamespace(ns); - ASSERT_TRUE(err.ok()) << err.what(); - } - - void SpecialCheckForNull(const std::shared_ptr& reindexer, std::string_view ns, std::string_view firstItemPattern, - std::string_view itemPattern, std::string_view description) const { - specialCheckForNull(reindexer, ns, firstItemPattern, itemPattern, description); - validateReloadStateForNull(reindexer, ns, firstItemPattern, itemPattern, description); - } - - static constexpr uint32_t IdStart = 2000; - -private: - static constexpr uint32_t itemNumber_ = 5; // NOTE: minimum 2 - - void createNS(std::string_view ns, std::string_view itemPattern) { - createNamespace(ns); - generateItems(ns, itemPattern); - } - - void createNamespace(std::string_view ns) { - auto err = rt.reindexer->OpenNamespace(ns, StorageOpts().Enabled().CreateIfMissing()); - EXPECT_TRUE(err.ok()) << err.what(); - - DefineNamespaceDataset(ns, {IndexDeclaration{"id", "hash", "int", IndexOpts().PK(), 0}}); - } - - void generateItems(std::string_view ns, std::string_view pattern) { - for (uint32_t idx = IdStart, sz = IdStart + itemNumber_; idx < sz; ++idx) { - Item item = NewItem(ns); - EXPECT_TRUE(item.Status().ok()) << item.Status().what(); - - const auto json = fmt::sprintf(pattern.data(), idx); - auto err = item.FromJSON(json); - ASSERT_TRUE(err.ok()) << err.what(); - - Upsert(ns, item); - } - } - - void checkIfItemJSONValid(QueryResults::Iterator& it, bool print = false) const { - reindexer::WrSerializer wrser; - Error err = it.GetJSON(wrser, false); - EXPECT_TRUE(err.ok()) << err.what(); - if (err.ok() && print) { - std::cout << wrser.Slice() << std::endl; - } - } - - void validateResults(const std::shared_ptr& reindexer, std::string_view ns, std::string_view pattern, - std::string_view field, const VariantArray& expectedValues, std::string_view description) const { - SCOPED_TRACE(description); - - QueryResults qr; - auto err = reindexer->Select("SELECT * FROM " + std::string(ns), qr); - EXPECT_TRUE(err.ok()) << err.what(); - ASSERT_EQ(qr.Count(), itemNumber_); - - for (auto it : qr) { - Item item = it.GetItem(false); - checkIfItemJSONValid(it); - const auto json = item.GetJSON(); - ASSERT_NE(json.find(pattern), std::string::npos) << "JSON: " << json << ";\npattern: " << pattern; - const VariantArray values = item[field]; - ASSERT_EQ(values.size(), expectedValues.size()); - ASSERT_EQ(values.IsArrayValue(), expectedValues.IsArrayValue()); - for (size_t i = 0; i < values.size(); ++i) { - ASSERT_TRUE(values[i].Type().IsSame(expectedValues[i].Type())) - << values[i].Type().Name() << "!=" << expectedValues[i].Type().Name(); - if (values[i].Type().IsSame(reindexer::KeyValueType::Null())) { - continue; - } - - ASSERT_EQ(values[i], expectedValues[i]); - } - } - } - - void checkExpectations(const std::shared_ptr& reindexer, std::string_view ns, std::string_view pattern, - std::string_view description) const { - SCOPED_TRACE(description); - - QueryResults qr; - auto err = reindexer->Select("SELECT * FROM " + std::string(ns), qr); - EXPECT_TRUE(err.ok()) << err.what(); - ASSERT_EQ(qr.Count(), itemNumber_); - - uint32_t idx = IdStart; - for (auto it : qr) { - Item item = it.GetItem(false); - checkIfItemJSONValid(it); - - const auto json = item.GetJSON(); - const auto extJson = fmt::sprintf(pattern.data(), idx); - ASSERT_EQ(json, extJson); - - ++idx; - } - } - - void getItems(const std::shared_ptr& reindexer, std::string_view ns, std::vector& items) const { - QueryResults qr; - auto err = reindexer->Select("SELECT * FROM " + std::string(ns), qr); - ASSERT_TRUE(err.ok()) << err.what(); - - items.clear(); - items.reserve(qr.Count()); - for (auto& it : qr) { - auto item = it.GetItem(false); - items.emplace_back(item.GetJSON()); - } - } - - void checkItems(const std::shared_ptr& reindexer, std::string_view ns, - const std::vector& items) const { - QueryResults qr; - auto err = reindexer->Select("SELECT * FROM " + std::string(ns), qr); - ASSERT_TRUE(err.ok()) << err.what(); - - ASSERT_EQ(items.size(), qr.Count()); - auto itItems = items.cbegin(); - auto itQR = qr.begin(); - auto endItems = items.cend(); - auto endQR = qr.end(); - for (; (itItems != endItems) && (itQR != endQR); ++itItems, ++itQR) { - auto item = itQR.GetItem(false); - ASSERT_EQ(*itItems, item.GetJSON()); - } - } - - void specialCheckForNull(const std::shared_ptr& reindexer, std::string_view ns, std::string_view firstItemPattern, - std::string_view itemPattern, std::string_view description) const { - SCOPED_TRACE(description); - - // first element should not update values, all others should be initialized to default values - // Note: but index array updates element type - QueryResults qr; - auto err = reindexer->Select("SELECT * FROM " + std::string(ns), qr); - EXPECT_TRUE(err.ok()) << err.what(); - ASSERT_EQ(qr.Count(), itemNumber_); - - uint32_t idx = IdStart; - for (auto it : qr) { - Item item = it.GetItem(false); - checkIfItemJSONValid(it); - const auto json = item.GetJSON(); - const auto& pattern = (idx == IdStart) ? firstItemPattern : itemPattern; - const auto expJson = fmt::sprintf(pattern.data(), idx); - ASSERT_EQ(json, expJson); - - ++idx; - } - } - - void validateReloadStateForNull(const std::shared_ptr& reindexer, std::string_view ns, - std::string_view firstItemPattern, std::string_view itemPattern, std::string_view description) const { - auto err = rt.reindexer->CloseNamespace(ns); - ASSERT_TRUE(err.ok()) << err.what(); - - err = rt.reindexer->OpenNamespace(ns, StorageOpts().Enabled().VerifyChecksums()); - ASSERT_TRUE(err.ok()) << err.what(); - - specialCheckForNull(reindexer, ns, firstItemPattern, itemPattern, description); - - // remove storage - err = rt.reindexer->DropNamespace(ns); - ASSERT_TRUE(err.ok()) << err.what(); - } -}; - -TEST_F(IndexTupleTest, DISABLED_ScalarTest) { - static const std::string ns = "testNSScalar"; - CreateEmptyNamespace(ns); - - DoTestEmpty(rt.reindexer, ns, {"sparse", "text", "string", IndexOpts().Sparse()}, R"({"id":%d})", "add some sparse index. Do nothing"); - DoTestDefault(rt.reindexer, ns, {"text", "text", "string", IndexOpts()}, R"("text":"")", "text", {Variant("")}, - "add text scalar index. Add default value"); - DoTestEmpty(rt.reindexer, ns, {"text", "text", "string", IndexOpts()}, R"({"id":%d,"text":""})", "update text index. Do nothing"); - DoCallAndCheckError(rt.reindexer, ns, {"text", "hash", "int", IndexOpts()}, - "Index 'testNSScalar.text' already exists with different settings"); - DoTestDefault(rt.reindexer, ns, {"int", "hash", "int", IndexOpts()}, R"("int":0)", "int", {Variant(0)}, - "add int scalar index. Add default value"); - ValidateReloadState(rt.reindexer, ns, R"({"id":%d,"text":"","int":0})", "reload ns (ScalarTest)"); -} - -TEST_F(IndexTupleTest, DISABLED_ScalarNestedTest) { - static const std::string ns = "testNSNested"; - CreateEmptyNamespace(ns); - - DoTestDefault(rt.reindexer, ns, {"obj.more.nested", {"obj.more.nested"}, "hash", "int64", IndexOpts()}, - R"("obj":{"more":{"nested":0}})", "obj.more.nested", {Variant(int64_t(0))}, "add new nested scalar index"); - DoTestEmpty(rt.reindexer, ns, {"obj.more.nested", {"obj.more.nested"}, "hash", "int64", IndexOpts()}, - R"({"id":%d,"obj":{"more":{"nested":0}}})", "update nested index. Do nothing"); - DoTestEmpty(rt.reindexer, ns, {"id+obj.more.nested", {"id", "obj.more.nested"}, "tree", "composite", IndexOpts{}}, - R"({"id":%d,"obj":{"more":{"nested":0}}})", "add new composite index. Do nothing"); - DoCallAndCheckError(rt.reindexer, ns, {"obj.more", {"obj.more"}, "hash", "string", IndexOpts()}, - "Invalid tag type value for KeyValueType: ''"); - DoCallAndCheckError(rt.reindexer, ns, {"obj", "hash", "int64", IndexOpts()}, "Invalid tag type value for KeyValueType: ''"); - DoTestDefault(rt.reindexer, ns, {"obj.near", {"obj.near"}, "tree", "string", IndexOpts()}, R"("obj":{"more":{"nested":0},"near":""})", - "obj.near", {Variant("")}, "add nested scalar index to root"); - DoTestDefault(rt.reindexer, ns, {"obj.nested.text", {"obj.nested.text"}, "hash", "string", IndexOpts()}, - R"("obj":{"more":{"nested":0},"near":"","nested":{"text":""}}})", "obj.nested.text", {Variant("")}, - "add nested another path scalar index"); - DoTestDefault(rt.reindexer, ns, {"obj.idx", {"obj.idx"}, "hash", "int64", IndexOpts()}, - R"("obj":{"more":{"nested":0},"near":"","nested":{"text":""},"idx":0})", "obj.idx", {Variant(int64_t(0))}, - "add nested 2nd level path scalar index"); - DoTestDefault(rt.reindexer, ns, {"obj.new.another.one", {"obj.new.another.one"}, "tree", "double", IndexOpts()}, - R"("obj":{"more":{"nested":0},"near":"","nested":{"text":""},"idx":0,"new":{"another":{"one":0.0}}}})", - "obj.new.another.one", {Variant(0.0)}, "add nested scalar index with multiple new path levels"); - DoCallAndCheckError(rt.reindexer, ns, {"boom", {"obj.new.another.one"}, "tree", "string", IndexOpts()}, - "Cannot add field with name 'boom' to namespace 'testNSNested'. Json path 'obj.new.another.one' already used" - " in field 'obj.new.another.one'"); - DoCallAndCheckError(rt.reindexer, ns, {"boom", {"obj.new.another.one.two"}, "hash", "int64", IndexOpts()}, - "Cannot add field with name 'boom' (jsonpath 'obj.new.another.one.two') and type 'int64' to namespace" - " 'testNSNested'. Already exists json path 'obj.new.another.one' with type 'double' in field" - " 'obj.new.another.one'. Rewriting is impossible"); - DoTestDefault( - rt.reindexer, ns, {"root2.more.nested", {"root2.more.nested"}, "hash", "int64", IndexOpts()}, - R"("obj":{"more":{"nested":0},"near":"","nested":{"text":""},"idx":0,"new":{"another":{"one":0.0}}},"root2":{"more":{"nested":0}})", - "root2.more.nested", {Variant(int64_t(0))}, "add new root with nested"); - DoTestDefault( - rt.reindexer, ns, {"boom", {"obj.new.another.one_ext"}, "hash", "int64", IndexOpts()}, - R"("obj":{"more":{"nested":0},"near":"","nested":{"text":""},"idx":0,"new":{"another":{"one":0.0,"one_ext":0}}},"root2":{"more":{"nested":0}})", - "obj.new.another.one_ext", {Variant(int64_t(0))}, "add new nested scalar index with name extension in last part"); - DoTestDefault( - rt.reindexer, ns, {"a-ha", {"a.ha"}, "hash", "int64", IndexOpts()}, - R"("obj":{"more":{"nested":0},"near":"","nested":{"text":""},"idx":0,"new":{"another":{"one":0.0,"one_ext":0}}},"root2":{"more":{"nested":0}},"a":{"ha":0})", - "a.ha", {Variant(int64_t(0))}, "add another nested scalar index on top level"); - ValidateReloadState( - rt.reindexer, ns, - R"({"id":%d,"obj":{"more":{"nested":0},"near":"","nested":{"text":""},"idx":0,"new":{"another":{"one":0.0,"one_ext":0}}},"root2":{"more":{"nested":0}},"a":{"ha":0}})", - "reload ns (ScalarNestedTest)"); -} - -TEST_F(IndexTupleTest, SparseItemTest) { - static const std::string ns = "testNSSparse"; - CreateSparseNamespace(ns); - - DoTestEmpty(rt.reindexer, ns, {"sparse1", {"fld1"}, "hash", "int", IndexOpts().Sparse()}, - R"({"id":%d,"fld1":1,"fld2":{"nested":"test"}})", "add some sparse index to present nested field. Do nothing"); - DoCallAndCheckError(rt.reindexer, ns, {"sparse2", {"fld2"}, "hash", "int", IndexOpts().Sparse()}, "Can't convert 'test' to number"); - DoCallAndCheckError(rt.reindexer, ns, {"sparse3", {"fld2.nested"}, "hash", "int", IndexOpts().Sparse()}, - "Can't convert 'test' to number"); - DoTestEmpty(rt.reindexer, ns, {"sparse2", {"fld2"}, "hash", "string", IndexOpts().Sparse()}, - R"({"id":%d,"fld1":1,"fld2":{"nested":"test"}})", "add some sparse index to present part path field. Do nothing"); - ValidateReloadState(rt.reindexer, ns, R"({"id":%d,"fld1":1,"fld2":{"nested":"test"}})", "reload ns (SparseItemTest)"); -} - -TEST_F(IndexTupleTest, NestedUpdateTest) { - static const std::string ns = "testNSUpdate"; - CreateNamespace(ns); - - DoTestDefault( - rt.reindexer, ns, {"obj.nested", {"obj.nested"}, "hash", "string", IndexOpts()}, - R"("objs":[{"fld":1},{"fld":2},{"fld":5}],"obj":{"nested":"0"},"last":{"text":"OK","1st":{"2nd":{"3rd":3.14}}},"arr":[{"nested_arr":[{"field":[3,2,1]},{"field":11},{"field":[9]}]}])", - "obj.nested", VariantArray{Variant{"0"}}, "add obj.nested index - update field type"); - DoCallAndCheckError(rt.reindexer, ns, {"try_change_type", {"last.text"}, "hash", "int", IndexOpts()}, "Can't convert 'OK' to number"); - ValidateReloadState( - rt.reindexer, ns, - R"({"id":%d,"objs":[{"fld":1},{"fld":2},{"fld":5}],"obj":{"nested":"0"},"last":{"text":"OK","1st":{"2nd":{"3rd":3.14}}},"arr":[{"nested_arr":[{"field":[3,2,1]},{"field":11},{"field":[9]}]}]})", - "reload ns (NestedUpdateTest)"); -} - -// TODO: This test must be reenabled after #1353 -TEST_F(IndexTupleTest, DISABLED_ArrayTest) { - static const std::string ns = "testNSArray"; - CreateEmptyNamespace(ns); - - DoTestDefault(rt.reindexer, ns, {"array", "hash", "int", IndexOpts().Array()}, R"("array":[])", "array", {}, - "add int array index. Add empty array"); - DoTestDefault(rt.reindexer, ns, - {"obj.some.arr_1st", {"obj.some.array", "arr_fld", "obj.array"}, "hash", "int64", IndexOpts().Array(), 0}, - R"("array":[],"arr_fld":[])", "arr_fld", VariantArray{}.MarkArray(), "add array index. Add empty array"); - DoCallAndCheckError(rt.reindexer, ns, {"obj.some.array", {"obj.array"}, "hash", "int64", IndexOpts().Array(), 0}, - "Cannot add field with name 'obj.some.array' to namespace 'testNSArray'. Json path 'obj.array' already used in " - "field 'obj.some.arr_1st'"); - DoTestDefault(rt.reindexer, ns, - {"obj.some.new_array", {"obj.some.new_array", "arr_fld1", "arr_fld2"}, "hash", "int64", IndexOpts().Array(), 0}, - R"("array":[],"arr_fld":[],"arr_fld2":[])", "arr_fld2", VariantArray{}.MarkArray(), - "add another array index (chooses last of two). Add empty array"); - // TODO: This logic is disabled due to #1819 - DoTestDefault(rt.reindexer, ns, {"obj.new.array", {"obj.new.array"}, "hash", "int64", IndexOpts().Array(), 0}, - R"("array":[],"arr_fld":[],"arr_fld2":[]})" /*,"obj":{"new":{"array":[]}})"*/, "obj.new.array", VariantArray{}, - "add new nested (only) index. Add empty array"); - // TODO: This logic is disabled due to #1819 - DoTestDefault(rt.reindexer, ns, {"arr", "hash", "int64", IndexOpts().Array()}, - R"("array":[],"arr_fld":[],"arr_fld2":[],"arr":[]})" /*,"obj":{"new":{"array":[]}},"arr":[])"*/, "arr", VariantArray{}, - "add new field with nested (only) indexes. Add empty array"); - DoCallAndCheckError(rt.reindexer, ns, - {"arr_restriction", {"arr_fld3", "arr_fld4", "arr.some.arr_1st"}, "hash", "int64", IndexOpts().Array(), 0}, - "Cannot add field with name 'arr_restriction' (jsonpath 'arr.some.arr_1st') and type 'int64' to namespace" - " 'testNSArray'. Already exists json path 'arr' with type 'int64' in field 'arr'. Rewriting is impossible"); - DoTestEmpty(rt.reindexer, ns, {"new_sparse_array", {"new_sparse_array"}, "hash", "int64", IndexOpts().Array().Sparse(), 0}, - R"({"id":%d,"array":[],"arr_fld":[],"arr_fld2":[],"arr":[]})" /*,"obj":{"new":{"array":[]}},"arr":[]})"*/, - "add new sparse array index. Do nothing"); - ValidateReloadState(rt.reindexer, ns, - R"({"id":%d,"array":[],"arr_fld":[],"arr_fld2":[],"arr":[]})" /*,"obj":{"new":{"array":[]}},"arr":[]})"*/, - "reload ns (ArrayTest)"); -} - -// TODO: This test must be reenabled after #1353 -TEST_F(IndexTupleTest, DISABLED_ArrayNestedTest) { - static const std::string ns = "testNSArrayObj"; - CreateNamespace(ns); - - DoCallAndCheckError(rt.reindexer, ns, {"try_change_type", {"last.text"}, "hash", "int", IndexOpts().Array().Sparse()}, - "Can't convert 'OK' to number"); - DoCallAndCheckError(rt.reindexer, ns, {"try_change_type", {"last.text"}, "hash", "int", IndexOpts().Array()}, - "Can't convert 'OK' to number"); - // TODO: This logic is disabled due to #1819 - DoTestDefault( - rt.reindexer, ns, {"next.another.last", {"next.another.last"}, "hash", "string", IndexOpts().Array()}, - R"("objs":[{"fld":1},{"fld":2},{"fld":5}],"obj":{"nested":0},"last":{"text":"OK","1st":{"2nd":{"3rd":3.14}}},"arr":[{"nested_arr":[{"field":[3,2,1]},{"field":11},{"field":[9]}]}]})" /*,"next":{"another":{"last":[]}})"*/ - , - "next.another.last", VariantArray{}, "add nested index to field by new path. Add empty array"); - DoTestDefault( - rt.reindexer, ns, {"obj.alternative", {"obj.alternative"}, "hash", "string", IndexOpts().Array()}, - R"("objs":[{"fld":1},{"fld":2},{"fld":5}],"obj":{"nested":0,"alternative":[]},"last":{"text":"OK","1st":{"2nd":{"3rd":3.14}}},"arr":[{"nested_arr":[{"field":[3,2,1]},{"field":11},{"field":[9]}]}]})" /*,"next":{"another":{"last":[]}})"*/ - , - "obj.alternative", VariantArray{}, "add nested index to field. Add empty array"); - - DoTestDefault( - rt.reindexer, ns, {"last.1st.2nd.ext", {"last.1st.2nd.ext"}, "hash", "string", IndexOpts().Array()}, - R"("objs":[{"fld":1},{"fld":2},{"fld":5}],"obj":{"nested":0,"alternative":[]},"last":{"text":"OK","1st":{"2nd":{"3rd":3.14,"ext":[]}}},"arr":[{"nested_arr":[{"field":[3,2,1]},{"field":11},{"field":[9]}]}]})" /*,"next":{"another":{"last":[]}})"*/ - , - "last.1st.2nd.ext.more", VariantArray{}, "add nested-nested index to field. Add empty array"); - DoCallAndCheckError(rt.reindexer, ns, {"last.1st.2nd.ext", {"last.alt", "last.1st.2nd.ext"}, "hash", "string", IndexOpts().Array()}, - "Index 'testNSArrayObj.last.1st.2nd.ext' already exists with different settings"); - // TODO: This logic is disabled due to #1819 - // DoTestDefault( - // rt.reindexer, ns, {"last.1st.2nd.ext.more", {"last.1st.2nd.ext.more"}, "hash", "string", IndexOpts().Array()}, - // R"("objs":[{"fld":1},{"fld":2},{"fld":5}],"obj":{"nested":0,"alternative":[]},"last":{"text":"OK","1st":{"2nd":{"3rd":3.14,"ext":{"more":[]}}}},"arr":[{"nested_arr":[{"field":[3,2,1]},{"field":11},{"field":[9]}]}],"next":{"another":{"last":[]}})", - // "last.1st.2nd.ext.more", VariantArray{}, "add nested-nested index to field. Add empty array"); - // DoCallAndCheckError(rt.reindexer, ns, - // {"last.1st.2nd.ext.more", {"last.alt", "last.1st.2nd.ext.more"}, "hash", "string", IndexOpts().Array()}, - // "Index 'testNSArrayObj.last.1st.2nd.ext.more' already exists with different settings"); - DoTestDefault( - rt.reindexer, ns, {"last.1st.ext", {"last.1st.ext"}, "hash", "string", IndexOpts().Array()}, - R"("objs":[{"fld":1},{"fld":2},{"fld":5}],"obj":{"nested":0,"alternative":[]},"last":{"text":"OK","1st":{"2nd":{"3rd":3.14,"ext":[]}},"ext":[]},"arr":[{"nested_arr":[{"field":[3,2,1]},{"field":11},{"field":[9]}]}]})" /*,"next":{"another":{"last":[]}})"*/ - , - "last.1st.ext", VariantArray{}, "add array index into the presented nested field. Add empty array"); - ValidateReloadState( - rt.reindexer, ns, - R"({"id":%d,"objs":[{"fld":1},{"fld":2},{"fld":5}],"obj":{"nested":0,"alternative":[]},"last":{"text":"OK","1st":{"2nd":{"3rd":3.14,"ext":[]}},"ext":[]},"arr":[{"nested_arr":[{"field":[3,2,1]},{"field":11},{"field":[9]}]}]})" /*,"next":{"another":{"last":[]}}})"*/ - , - "reload ns (ArrayNestedTest)"); -} - -TEST_F(IndexTupleTest, ArrayInToArrayTest) { - static const std::string ns = "testNSArrayArr"; - CreateNamespace(ns); - - // TODO: This logic is disabled due to #1819 - DoTestDefault( - rt.reindexer, ns, {"objs.more", {"objs.more"}, "hash", "string", IndexOpts().Array()}, - R"("objs":[{"fld":1},{"fld":2},{"fld":5}],"obj":{"nested":0},"last":{"text":"OK","1st":{"2nd":{"3rd":3.14}}},"arr":[{"nested_arr":[{"field":[3,2,1]},{"field":11},{"field":[9]}]}])", - "obj.more", VariantArray{}, "do not add anything into objects array"); - DoTestEmpty( - rt.reindexer, ns, {"arr.nested_arr.field", {"arr.nested_arr.field"}, "hash", "string", IndexOpts().Array()}, - R"({"id":%d,"objs":[{"fld":1},{"fld":2},{"fld":5}],"obj":{"nested":0},"last":{"text":"OK","1st":{"2nd":{"3rd":3.14}}},"arr":[{"nested_arr":[{"field":["3","2","1"]},{"field":"11"},{"field":["9"]}]}]})", - "add nested index to array array (update). Do nothing"); - DoTestEmpty( - rt.reindexer, ns, {"arr.new_fld", {"arr.new_fld"}, "hash", "string", IndexOpts().Array()}, - R"({"id":%d,"objs":[{"fld":1},{"fld":2},{"fld":5}],"obj":{"nested":0},"last":{"text":"OK","1st":{"2nd":{"3rd":3.14}}},"arr":[{"nested_arr":[{"field":["3","2","1"]},{"field":"11"},{"field":["9"]}]}]})", - "add nested index to array array. Do nothing"); - DoTestEmpty( - rt.reindexer, ns, {"arr.nested_arr.ext_fld", {"arr.nested_arr.ext_fld"}, "hash", "string", IndexOpts().Array()}, - R"({"id":%d,"objs":[{"fld":1},{"fld":2},{"fld":5}],"obj":{"nested":0},"last":{"text":"OK","1st":{"2nd":{"3rd":3.14}}},"arr":[{"nested_arr":[{"field":["3","2","1"]},{"field":"11"},{"field":["9"]}]}]})", - "add nested nested index to array array. Do nothing"); - ValidateReloadState( - rt.reindexer, ns, - R"({"id":%d,"objs":[{"fld":1},{"fld":2},{"fld":5}],"obj":{"nested":0},"last":{"text":"OK","1st":{"2nd":{"3rd":3.14}}},"arr":[{"nested_arr":[{"field":["3","2","1"]},{"field":"11"},{"field":["9"]}]}]})", - "reload ns (ArrayInToArrayTest)"); -} - -// TODO: This test must be reenabled after #1353 -TEST_F(IndexTupleTest, DISABLED_NestedOrderingTest) { - static const std::string ns = "testNSNestedOrdering"; - CreateEmptyNamespace(ns); - - DoTestDefault(rt.reindexer, ns, {"nest1", {"obj.more.nested"}, "hash", "int", IndexOpts()}, R"("obj":{"more":{"nested":0}})", "nest1", - VariantArray{Variant{0}}, "add nest1. Add default value"); - DoTestDefault(rt.reindexer, ns, {"nest2", {"obj.near"}, "hash", "int", IndexOpts()}, R"("obj":{"more":{"nested":0},"near":0})", "nest2", - VariantArray{Variant{0}}, "add nest2. Add default value"); - DoTestDefault(rt.reindexer, ns, {"nest3", {"obj.nestd.text"}, "text", "string", IndexOpts()}, - R"("obj":{"more":{"nested":0},"near":0,"nestd":{"text":""}})", "nest3", VariantArray{Variant{""}}, - "add nest3. Add default value"); - DoTestDefault(rt.reindexer, ns, {"nest11", {"obj.more.nested2"}, "hash", "int", IndexOpts()}, - R"("obj":{"more":{"nested":0,"nested2":0},"near":0,"nestd":{"text":""}})", "nest11", VariantArray{Variant{0}}, - "add nest11. Add default value"); - ValidateReloadState(rt.reindexer, ns, R"({"id":%d,"obj":{"more":{"nested":0,"nested2":0},"near":0,"nestd":{"text":""}}})", - "reload ns (NestedDiffOrderingTest)"); -} - -// TODO: This test must be reenabled after #1353 -TEST_F(IndexTupleTest, DISABLED_NullTest) { - static const std::string ns = "testNSNull"; - CreateEmptyNamespace(ns); - - // update only one first item - { - const std::string sql = "UPDATE testNSNull SET fld1 = null, fld2 = [null, null] WHERE id = " + std::to_string(IdStart); - Query query = Query::FromSQL(sql); - QueryResults qr; - auto err = rt.reindexer->Update(query, qr); - ASSERT_TRUE(err.ok()) << err.what(); - ASSERT_EQ(qr.Count(), 1); - } - - // add indexes (simple and array) - { - auto err = rt.reindexer->AddIndex(ns, {"fld1", "hash", "int", IndexOpts()}); - ASSERT_TRUE(err.ok()) << err.what(); - err = rt.reindexer->AddIndex(ns, {"fld2", "hash", "string", IndexOpts().Array()}); - ASSERT_TRUE(err.ok()) << err.what(); - } - - SpecialCheckForNull(rt.reindexer, ns, R"({"id":%d,"fld1":null,"fld2":["null","null"]})", R"({"id":%d,"fld1":0,"fld2":[]})", - "null values test"); -} - -// TODO: This test must be reenabled after #1353 -TEST_F(IndexTupleTest, DISABLED_FailTest) { - static const std::string ns = "testNSFail"; - CreateEmptyNamespace(ns); - - DoTestDefault(rt.reindexer, ns, {"nest", {"obj.nest"}, "hash", "int", IndexOpts()}, R"("obj":{"nest":0})", "nest", - VariantArray{Variant{0}}, "add nest. Add default value"); - DoTestDefault(rt.reindexer, ns, {"idx", {"idx"}, "-", "bool", IndexOpts()}, R"("obj":{"nest":0},"idx":false)", "idx", - VariantArray{Variant{false}}, "add idx. Add default value"); - ValidateReloadState(rt.reindexer, ns, R"({"id":%d,"obj":{"nest":0},"idx":false})", "reload ns (FailTest)"); -} - -// TODO: This test must be reenabled after #1353 -TEST_F(IndexTupleTest, DISABLED_NestedArrayTest) { - static const std::string ns = "testNSNestedArray"; - CreateArrayNamespace(ns); - - // TODO: This logic is disabled due to #1819 - DoTestDefault(rt.reindexer, ns, {"obj.obj1.arr", {"obj.obj1.arr"}, "hash", "int", IndexOpts().Array()}, - R"("obj":{"val":10},"arr":[1,2,3])", "obj.obj1.arr", VariantArray{}, - // R"("obj":{"val":10,"obj1":{"arr":[]}},"arr":[1,2,3])", "obj.obj1.arr", VariantArray{}, - "add obj.obj1.arr. Add default value"); - DoTestDefault(rt.reindexer, ns, {"obj.arr", {"obj.arr"}, "hash", "int", IndexOpts().Array()}, - R"("obj":{"val":10,"arr":[]},"arr":[1,2,3])", "obj.arr", VariantArray{}, "add obj.arr. Add default value"); - ValidateReloadState(rt.reindexer, ns, R"({"id":%d,"obj":{"val":10,"arr":[]},"arr":[1,2,3]})", "reload ns (NestedArrayTest)"); -} diff --git a/cpp_src/gtests/tests/unit/namespace_test.cc b/cpp_src/gtests/tests/unit/namespace_test.cc index 263fb9c73..34769d8fe 100644 --- a/cpp_src/gtests/tests/unit/namespace_test.cc +++ b/cpp_src/gtests/tests/unit/namespace_test.cc @@ -1525,13 +1525,13 @@ TEST_F(NsApi, ArrayRemoveWithSql) { Item item = it.GetItem(false); checkIfItemJSONValid(it); VariantArray values = item["array_field"]; - ASSERT_EQ(values.size(), 1 + 8 + 2); // [0] || [11,22,33,44,55,66,77,88] || [7,9] remove 99 - int i = 0; // 1 - for ( ; i < 9; ++i) { - ASSERT_EQ(values[i].As(), i * 11); // +8 + ASSERT_EQ(values.size(), 1 + 8 + 2); // [0] || [11,22,33,44,55,66,77,88] || [7,9] remove 99 + int i = 0; // 1 + for (; i < 9; ++i) { + ASSERT_EQ(values[i].As(), i * 11); // +8 } ASSERT_EQ(values[i++].As(), 7); - ASSERT_EQ(values[i].As(), 9); // +2 + ASSERT_EQ(values[i].As(), 9); // +2 } } @@ -1545,12 +1545,12 @@ TEST_F(NsApi, ArrayRemoveWithSql) { Item item = it.GetItem(false); checkIfItemJSONValid(it); VariantArray values = item["array_field"]; - ASSERT_EQ(values.size(), 1 + 8 + 1); // [0,11,22,33,44,55,66,77,88,9] remove 7 - int i = 0; // 1 - for ( ; i < 9; ++i) { - ASSERT_EQ(values[i].As(), i * 11); // +8 + ASSERT_EQ(values.size(), 1 + 8 + 1); // [0,11,22,33,44,55,66,77,88,9] remove 7 + int i = 0; // 1 + for (; i < 9; ++i) { + ASSERT_EQ(values[i].As(), i * 11); // +8 } - ASSERT_EQ(values[i].As(), 9); // +1 + ASSERT_EQ(values[i].As(), 9); // +1 } } @@ -1642,12 +1642,12 @@ TEST_F(NsApi, ArrayRemoveWithSql) { Item item = it.GetItem(false); checkIfItemJSONValid(it); VariantArray values = item["array_field"]; - ASSERT_EQ(values.size(), 9); // [11,22,33,44,55,66,77,88,9] remove 0 + ASSERT_EQ(values.size(), 9); // [11,22,33,44,55,66,77,88,9] remove 0 int i = 0; - for ( ; i < 8; ++i) { - ASSERT_EQ(values[i].As(), (i + 1) * 11); // +8 + for (; i < 8; ++i) { + ASSERT_EQ(values[i].As(), (i + 1) * 11); // +8 } - ASSERT_EQ(values[i].As(), 9); // +1 + ASSERT_EQ(values[i].As(), 9); // +1 } } @@ -1661,12 +1661,12 @@ TEST_F(NsApi, ArrayRemoveWithSql) { Item item = it.GetItem(false); checkIfItemJSONValid(it); VariantArray values = item["array_field"]; - ASSERT_EQ(values.size(), 8); // [11,22,33,44,55,66,77,9] remove 88 + ASSERT_EQ(values.size(), 8); // [11,22,33,44,55,66,77,9] remove 88 int i = 0; - for ( ; i < 7; ++i) { - ASSERT_EQ(values[i].As(), (i + 1) * 11); // +7 + for (; i < 7; ++i) { + ASSERT_EQ(values[i].As(), (i + 1) * 11); // +7 } - ASSERT_EQ(values[i].As(), 9); // +1 + ASSERT_EQ(values[i].As(), 9); // +1 } } diff --git a/cpp_src/gtests/tests/unit/protobuf_test.cc b/cpp_src/gtests/tests/unit/protobuf_test.cc index 885f0c65f..a53958b1f 100644 --- a/cpp_src/gtests/tests/unit/protobuf_test.cc +++ b/cpp_src/gtests/tests/unit/protobuf_test.cc @@ -19,10 +19,10 @@ const std::string kStreetValue = "Miracle Street, "; const std::string kPostalCodeValue = "9745 123 "; const double kSalaryValue = 11238761238768.232342342; -TEST_F(ReindexerApi, ProtobufConvesrionTest) { +TEST_F(ReindexerApi, ProtobufConversionTest) { // Check protobuf for basic types (int/double/array) and double <-> int conversion // !!! This test is using schema from cpp_src/gtests/tests/proto/conversion.proto. - // !!! Protobuf indexes are not constant and depend from the internal reindexer::Schema implementation. + // !!! Protobuf indexes are not persistent and depend on the internal implementation of reindexer::Schema. // clang-format off const std::string schema = R"z( { @@ -93,7 +93,7 @@ TEST_F(ReindexerApi, ProtobufConvesrionTest) { TEST_F(ReindexerApi, ProtobufEasyArrayTest) { // Check protobuf for arrays and nested objects // !!! This test is using schema from cpp_src/gtests/tests/proto/easyarrays.proto. - // !!! Protobuf indexes are not constant and depend from the internal reindexer::Schema implementation. + // !!! Protobuf indexes are not persistent and depend on the internal implementation of reindexer::Schema. // clang-format off const std::string schema = R"z( { diff --git a/cpp_src/gtests/tests/unit/rpcclient_test.cc b/cpp_src/gtests/tests/unit/rpcclient_test.cc index 7bb3108a3..974630915 100644 --- a/cpp_src/gtests/tests/unit/rpcclient_test.cc +++ b/cpp_src/gtests/tests/unit/rpcclient_test.cc @@ -159,7 +159,7 @@ TEST_F(RPCClientTestApi, CoroRequestCancels) { ASSERT_TRUE(err.ok()) << err.what(); } -TEST_F(RPCClientTestApi, CoroSuccessfullRequestWithTimeout) { +TEST_F(RPCClientTestApi, CoroSuccessfulRequestWithTimeout) { // Should be able to execute some basic requests with timeout AddFakeServer(); StartServer(); @@ -601,8 +601,8 @@ TEST_F(RPCClientTestApi, ItemJSONWithDouble) { loop.run(); } -TEST_F(RPCClientTestApi, UnknowResultsFlag) { - // Check if server will not resturn unknown result flag +TEST_F(RPCClientTestApi, UnknownResultsFlag) { + // Check if server will not return unknown result flag StartDefaultRealServer(); ev::dynamic_loop loop; bool finished = false; @@ -849,7 +849,7 @@ TEST_F(RPCClientTestApi, QRWithMultipleIterationLoops) { TEST_F(RPCClientTestApi, AggregationsFetching) { // Validate, that distinct results will remain valid after query results fetching. - // Actual aggregation values will be sent for initial 'select' only, but must be available at any point of iterator's lifetime. + // Actual aggregation values will only be sent for initial 'select', but must be available at any point in iterator's lifetime. using namespace reindexer::client; using namespace reindexer::net::ev; @@ -1009,13 +1009,8 @@ TEST_F(RPCClientTestApi, AggregationsWithStrictModeTest) { } TEST_F(RPCClientTestApi, SubQuery) { - using namespace reindexer::client; - using namespace reindexer::net::ev; - using reindexer::coroutine::wait_group; - using reindexer::coroutine::wait_group_guard; - StartDefaultRealServer(); - dynamic_loop loop; + reindexer::net::ev::dynamic_loop loop; loop.spawn([&loop, this]() noexcept { const std::string kLeftNsName = "left_ns"; @@ -1027,7 +1022,7 @@ TEST_F(RPCClientTestApi, SubQuery) { constexpr auto kFetchCount = 50; constexpr auto kNsSize = kFetchCount * 3; cfg.FetchAmount = kFetchCount; - CoroReindexer rx(cfg); + reindexer::client::CoroReindexer rx(cfg); auto err = rx.Connect(dsn, loop, opts); ASSERT_TRUE(err.ok()) << err.what(); @@ -1076,3 +1071,67 @@ TEST_F(RPCClientTestApi, SubQuery) { loop.run(); } + +TEST_F(RPCClientTestApi, CoroTransactionInsertWithPrecepts) { + StartDefaultRealServer(); + reindexer::net::ev::dynamic_loop loop; + + loop.spawn([&loop, this]() noexcept { + const std::string dsn = "cproto://" + kDefaultRPCServerAddr + "/db1"; + reindexer::client::ConnectOpts opts; + opts.CreateDBIfMissing(); + reindexer::client::CoroReindexer rx; + auto err = rx.Connect(dsn, loop, opts); + ASSERT_TRUE(err.ok()) << err.what(); + const std::string kNsName = "TestCoroInsertWithPrecepts"; + CreateNamespace(rx, kNsName); + + constexpr int kNsSize = 5; + + auto insertFn = [&rx, kNsSize](const std::string& nsName) { + std::vector precepts = {"id=SERIAL()"}; + + auto tx = rx.NewTransaction(nsName); + ASSERT_TRUE(tx.Status().ok()) << tx.Status().what(); + + for (size_t i = 0; i < kNsSize; ++i) { + auto item = tx.NewItem(); + ASSERT_TRUE(item.Status().ok()) << item.Status().what(); + + WrSerializer wrser; + JsonBuilder jsonBuilder(wrser, ObjType::TypeObject); + jsonBuilder.Put("id", 100); + jsonBuilder.End(); + + char* endp = nullptr; + auto err = item.Unsafe().FromJSON(wrser.Slice(), &endp); + ASSERT_TRUE(err.ok()) << err.what(); + + item.SetPrecepts(precepts); + + err = tx.Insert(std::move(item)); + ASSERT_TRUE(err.ok()) << err.what(); + } + client::CoroQueryResults qr; + auto err = rx.CommitTransaction(tx, qr); + ASSERT_TRUE(err.ok()) << err.what(); + ASSERT_EQ(qr.Count(), kNsSize); + }; + + insertFn(kNsName); + + { + client::CoroQueryResults qr; + err = rx.Select(Query(kNsName), qr); + ASSERT_TRUE(err.ok()) << err.what(); + ASSERT_EQ(qr.Count(), kNsSize); + for (auto& it : qr) { + ASSERT_TRUE(it.Status().ok()) << it.Status().what(); + } + } + + rx.Stop(); + }); + + loop.run(); +} diff --git a/cpp_src/gtests/tests/unit/stringtools_test.cc b/cpp_src/gtests/tests/unit/stringtools_test.cc index 09b9f3623..9abdcdc79 100644 --- a/cpp_src/gtests/tests/unit/stringtools_test.cc +++ b/cpp_src/gtests/tests/unit/stringtools_test.cc @@ -1,4 +1,5 @@ #include +#include "estl/tokenizer.h" #include "gtest/gtest.h" #include "tools/stringstools.h" @@ -147,3 +148,114 @@ TEST_F(CustomStrCompareApi, IEqual) { ValidateEqualResult(res, cInverted); } } + +TEST(ConversionStringToNumber, DetectValueTypeTest) { + using namespace reindexer; + constexpr auto Int64V = KeyValueType{KeyValueType::Int64{}}; + constexpr auto DoubleV = KeyValueType{KeyValueType::Double{}}; + constexpr auto StringV = KeyValueType{KeyValueType::String{}}; + + struct TestCase { + struct Empty {}; + TestCase(std::string_view value, KeyValueType expectedType, std::variant expectedValue = Empty{}) + : value(value), + expectedType(expectedType), + expectedValue(std::visit(overloaded{[](auto v) { return Variant(v); }, + [value](Empty) { return Variant(make_key_string(value.data(), value.length())); }}, + expectedValue)) {} + + std::string_view value; + KeyValueType expectedType; + Variant expectedValue; + }; + + std::initializer_list values = { + {"9223372036854775807", Int64V, 9223372036854775807}, + {"9223372036854775807.", Int64V, 9223372036854775807}, + {"9223372036854775807.0", Int64V, 9223372036854775807}, + {"9223372036854775807.000", Int64V, 9223372036854775807}, + {"9223372036854775807.00000", Int64V, 9223372036854775807}, + + {"+9223372036854775807", Int64V, 9223372036854775807}, + {"+9223372036854775807.", Int64V, 9223372036854775807}, + {"+9223372036854775807.0", Int64V, 9223372036854775807}, + {"+9223372036854775807.000", Int64V, 9223372036854775807}, + {"+9223372036854775807.00000", Int64V, 9223372036854775807}, + + {"-9223372036854775807", Int64V, -9223372036854775807}, + {"-9223372036854775807.", Int64V, -9223372036854775807}, + {"-9223372036854775807.0", Int64V, -9223372036854775807}, + {"-9223372036854775807.000", Int64V, -9223372036854775807}, + {"-9223372036854775807.00000", Int64V, -9223372036854775807}, + + {"-922337203685477580.7", DoubleV, -922337203685477580.7}, + {"922337203685477580.7", DoubleV, 922337203685477580.7}, + {"92247758070.00456402", DoubleV, 92247758070.00456402}, + {"+92247758070.00456402", DoubleV, 92247758070.00456402}, + {"+922358070.000002", DoubleV, 922358070.000002}, + {"-922358070.000002", DoubleV, -922358070.000002}, + {"92547758070.1", DoubleV, 92547758070.1}, + + {"9223372036854775807.01", DoubleV, 9223372036854775807.01}, + {"92233720368547758070.0002", DoubleV, 92233720368547758070.0002}, + {"9223372036854775807.000002", DoubleV, 9223372036854775807.000002}, + {"92233720368547758070.1", DoubleV, 92233720368547758070.1}, + {"92233720368547758070.01", DoubleV, 92233720368547758070.01}, + {"92233720368547758070.0002", DoubleV, 92233720368547758070.0002}, + {"9223372036854775834257834562345234654324524070.00023452346452345234452", DoubleV, + 9223372036854775834257834562345234654324524070.00023452346452345234452}, + {"92233720368547758070.000012", DoubleV, 92233720368547758070.000012}, + + {"", StringV}, + {"-", StringV}, + {"+", StringV}, + {".", StringV}, + {" ", StringV}, + {"str", StringV}, + {"s", StringV}, + + {"92233720368547758070", StringV}, + {"92233720368547758070.", DoubleV, 92233720368547758070.0}, + {"92233720368547758070.0", DoubleV, 92233720368547758070.0}, + {"92233720368547758070.000", DoubleV, 92233720368547758070.0}, + {"92233720368547758070.00000", DoubleV, 92233720368547758070.0}, + + {"+92233720368547758070", StringV}, + {"+92233720368547758070.", DoubleV, 92233720368547758070.0}, + {"+92233720368547758070.0", DoubleV, 92233720368547758070.0}, + {"+92233720368547758070.000", DoubleV, 92233720368547758070.0}, + {"+92233720368547758070.00000", DoubleV, 92233720368547758070.0}, + + {"-92233720368547758070", StringV}, + {"-92233720368547758070.", DoubleV, -92233720368547758070.0}, + {"-92233720368547758070.0", DoubleV, -92233720368547758070.0}, + {"-92233720368547758070.000", DoubleV, -92233720368547758070.0}, + {"-92233720368547758070.00000", DoubleV, -92233720368547758070.0}, + + {"9'223'372'036'854'775'807", StringV}, + {"9223372802345370L", StringV}, + {"92233728070.0145L", StringV}, + + {"1.35e10", StringV}, + {"1.1e-2", StringV}, + {"123.456.7", StringV}, + }; + + auto genToken = [](std::string_view text) { + token tok{TokenNumber}; + tok.text_ = {text.begin(), text.end()}; + return tok; + }; + + for (const auto& testCase : values) { + auto res = getVariantFromToken(genToken(testCase.value)); + + std::stringstream expected, actual; + testCase.expectedValue.Dump(expected); + res.Dump(actual); + + auto errMessage = fmt::format("token value: {}; expected: {}; get: {}", testCase.value, expected.str(), actual.str()); + EXPECT_EQ(testCase.expectedValue, res) << errMessage; + EXPECT_TRUE(res.Type().IsSame(testCase.expectedType)) << errMessage; + } +} \ No newline at end of file diff --git a/cpp_src/net/cproto/dispatcher.h b/cpp_src/net/cproto/dispatcher.h index f224f0b3a..3b58269e6 100644 --- a/cpp_src/net/cproto/dispatcher.h +++ b/cpp_src/net/cproto/dispatcher.h @@ -107,7 +107,7 @@ class Dispatcher { /// Set closer notifier /// @param object close class object - /// @param func function, to be called on connecion close + /// @param func function, to be called on connection close template void OnClose(K* object, void (K::*func)(Context& ctx, const Error& err)) { onClose_ = [=](Context& ctx, const Error& err) { (static_cast(object)->*func)(ctx, err); }; @@ -131,7 +131,7 @@ class Dispatcher { /// @return OnResponse callback reference const std::function& OnResponseRef() const noexcept { return onResponse_; } - /// Handle RPC fron the context + /// Handle RPC from the context /// @param ctx - RPC context Error Handle(Context& ctx) { if rx_likely (uint32_t(ctx.call->cmd) < uint32_t(handlers_.size())) { @@ -159,7 +159,7 @@ class Dispatcher { template ::value, int> = 0> static T get_arg(const Args& args, size_t index, const Context& ctx) { if (index >= args.size()) { - throw Error(errParams, "Invalid args of %s call; argument %d is not submited", CmdName(ctx.call->cmd), static_cast(index)); + throw Error(errParams, "Invalid args of %s call; argument %d is not submitted", CmdName(ctx.call->cmd), static_cast(index)); } return T(args[index]); } @@ -190,7 +190,7 @@ class Dispatcher { std::function logger_; std::function onClose_; - // This should be called from the connection thread only to prevet access to other connection's ClientData + // This should be called from the connection thread only to prevent access to other connection's ClientData std::function onResponse_; }; } // namespace cproto diff --git a/cpp_src/net/iserverconnection.h b/cpp_src/net/iserverconnection.h index b005a788c..76f0a7beb 100644 --- a/cpp_src/net/iserverconnection.h +++ b/cpp_src/net/iserverconnection.h @@ -32,7 +32,7 @@ class IServerConnection { /// Restart connection /// @param s - socket of the accepted connection. - /// @return true - if successfuly restarted, false - if connection can't be restarted. + /// @return true - if successfully restarted, false - if connection can't be restarted. virtual bool Restart(socket&& s) = 0; /// Attach connection to another listener loop. Must be called from thread of loop /// @param loop - another loop to bind diff --git a/cpp_src/readme.md b/cpp_src/readme.md index 4f4180268..63f9a2767 100644 --- a/cpp_src/readme.md +++ b/cpp_src/readme.md @@ -4,7 +4,7 @@ Reindexer's goal is to provide fast search with complex queries. Reindexer is compact, fast and it does not have heavy dependencies. -reindexer is up to 5x times faster, than mongodb, and 10x times than elastic search. See [benchmaks section](https://github.com/Restream/reindexer-benchmarks) for details. +reindexer is up to 5x times faster, than mongodb, and 10x times than elastic search. See [benchmarks section](https://github.com/Restream/reindexer-benchmarks) for details. # Installation @@ -20,7 +20,7 @@ docker run -p9088:9088 -p6534:6534 -it reindexer/reindexer ### Container configuration -While using docker, you may pass reindexer server config options via envinronment variables: +While using docker, you may pass reindexer server config options via environment variables: - `RX_DATABASE` - path to reindexer's storage. Default value is `/db`. - `RX_CORELOG` - path to core log file (or `none` to disable core logging). Default value is `stdout`. @@ -157,7 +157,7 @@ The simplest way to use reindexer with any program language - is using REST API. ## GRPC API -[GPRC](https://grpc.io) is a modern open-source high-performance RPC framework developed at Google that can run in any environment. It can efficiently connect services in and across data centers with pluggable support for load balancing, tracing, health checking and authentication. It uses HTTP/2 for transport, Protocol Buffers as the interface description language and it is more efficient (and also easier) to use than HTTP API. Reindexer supports GRPC API since version 3.0. +[GRPC](https://grpc.io) is a modern open-source high-performance RPC framework developed at Google that can run in any environment. It can efficiently connect services in and across data centers with pluggable support for load balancing, tracing, health checking and authentication. It uses HTTP/2 for transport, Protocol Buffers as the interface description language, and it is more efficient (and also easier) to use than HTTP API. Reindexer supports GRPC API since version 3.0. Reindexer's GRPC API is defined in [reindexer.proto](server/proto/reindexer.proto) file. @@ -185,20 +185,20 @@ The concept of streaming is described [here](https://grpc.io/docs/what-is-grpc/c ### Prometheus (server-side) -Reindexer has a bunch of prometheus metrics available via http-URL `/metrics` (i.e. `http://localhost:9088/metrics`). This metrics may be enabled by passing `--prometheus` as reindexer_server command line argument or by setting `metrics:prometheus` flag in server yaml-config file. Some of the metrics also require `perfstats` to be enabled in `profiling`-config +Reindexer has a bunch of prometheus metrics available via http-URL `/metrics` (i.e. `http://localhost:9088/metrics`). This metrics may be enabled by passing `--prometheus` as reindexer_server command line argument or by setting `metrics:prometheus` flag in server yaml-config file. Some metrics also require `perfstats` to be enabled in `profiling`-config `reindexer_qps_total` - total queries per second for each database, namespace and query type -`reindexer_avg_latency` - average queryies latency for each database, namespace and query type +`reindexer_avg_latency` - average queries latency for each database, namespace and query type `reindexer_caches_size_bytes`, `reindexer_indexes_size_bytes`, `reindexer_data_size_bytes` - caches, indexes and data size for each namespace `reindexer_items_count` - items count in each namespace -`reindexer_memory_allocated_bytes` - current amount of dynamicly allocated memory according to tcmalloc/jemalloc +`reindexer_memory_allocated_bytes` - current amount of dynamically allocated memory according to tcmalloc/jemalloc `reindexer_rpc_clients_count` - current number of RPC clients for each database `reindexer_input_traffic_total_bytes`, `reindexer_output_traffic_total_bytes` - total input/output RPC/http traffic for each database `reindexer_info` - generic reindexer server info (currently it's just a version number) ### Prometheus (client-side, Go) -Go binding for reindexer is using [prometheus/client_golang](https://github.com/prometheus/client_golang) to collect some metrics (RPS and request's latency) from client's side. Pass `WithPrometheusMetrics()`-option to enable metric's collecting: +Go binding for reindexer is using [prometheus/client_golang](https://github.com/prometheus/client_golang) to collect some metrics (RPS and request's latency) from client's side. Pass `WithPrometheusMetrics()`-option to enable metrics collecting: ``` // Create DB connection for cproto-mode with metrics enabled db := reindexer.NewReindex("cproto://127.0.0.1:6534/testdb", reindex.WithPrometheusMetrics()) @@ -206,10 +206,10 @@ db := reindexer.NewReindex("cproto://127.0.0.1:6534/testdb", reindex.WithPrometh http.Handle("/metrics", promhttp.Handler()) ``` -All of the metricts will be exported into `DefaultRegistry`. Check [this](https://github.com/prometheus/client_golang/blob/main/prometheus/promauto/auto.go#L57-L85) for basic prometheus usage example. +All the metrics will be exported into `DefaultRegistry`. Check [this](https://github.com/prometheus/client_golang/blob/main/prometheus/promauto/auto.go#L57-L85) for basic prometheus usage example. -Both server-side and client-side metrics contain 'latency', however, client-side latency will also count all the time consumed by the binding's queue, network communication (for cproto/ucproto) and deseriallization. -So client-side latency may be more rellevant for user's applications the server-side latency. +Both server-side and client-side metrics contain 'latency', however, client-side latency will also count all the time consumed by the binding's queue, network communication (for cproto/ucproto) and deserialization. +So client-side latency may be more relevant for user's applications the server-side latency. ## Maintenance @@ -280,7 +280,7 @@ Mode may be set via command line options on server startup: reindexer_server --db /tmp/rx --rpc-threading dedicated --http-threading shared ``` -In shared mode server creates fixed number of threads to handle connections (one thread per physical CPU core) and all of the connection will be distributed between those threads. In this mode requests from different connections may be forced to be executed sequentially. +In shared mode server creates fixed number of threads to handle connections (one thread per physical CPU core) and all the connection will be distributed between those threads. In this mode requests from different connections may be forced to be executed sequentially. In dedicated mode server creates one thread per connection. This approach may be inefficient in case of frequent reconnects or large amount of database clients (due to thread creation overhead), however it allows to reach maximum level of concurrency for requests. @@ -307,12 +307,12 @@ storage: engine: leveldb ``` -To configure storage type for Go bindings either `bindings.ConnectOptions` (for builtin) or `confg.ServerConfig` (for builtinserver) structs may be used. +To configure storage type for Go bindings either `bindings.ConnectOptions` (for builtin) or `confg.ServerConfig` (for builtin-server) structs may be used. ### RocksDB Reindexer will try to autodetect RocksDB library and its dependencies at compile time if CMake flag `ENABLE_ROCKSDB` was passed (enabled by default). -If reindexer library was built with rocksdb, it requires Go build tag `rocksdb` in order to link with go-applications and go-bindinds. +If reindexer library was built with rocksdb, it requires Go build tag `rocksdb` in order to link with go-applications and go-bindings. ### Data transport formats @@ -320,10 +320,10 @@ Reindexer supports the following data formats to communicate with other applicat ## Log rotation -There are no builtin mechanis for automatic log rotation, however `reindexer server` is able to reopen logfiles on `SIGHUP`. +There are no builtin mechanism for automatic log rotation, however `reindexer server` is able to reopen logfiles on `SIGHUP`. So, your external log manager (it may be even a simple `cron` script) have to move existing log files somewhere and then send `SIGHUP`-signal to the `reindexer server` process to recreate log files. -#### Protobuf +## Protobuf Protocol buffers are language-neutral, platform-neutral, extensible mechanism for serializing structured data. You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages (https://developers.google.com/protocol-buffers). diff --git a/cpp_src/server/CMakeLists.txt b/cpp_src/server/CMakeLists.txt index 080e3380b..67901ab39 100644 --- a/cpp_src/server/CMakeLists.txt +++ b/cpp_src/server/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.10) project(reindexer_server_library) set (SWAGGER_VERSION "2.x") -set (GH_FACE_VERSION "4.17.2") +set (GH_FACE_VERSION "4.18.0") set (GH_FACE_TAG "v${GH_FACE_VERSION}") set (TARGET reindexer_server_library) set (SERVER_LIB_DIR ${PROJECT_BINARY_DIR} PARENT_SCOPE) diff --git a/cpp_src/server/contrib/server.md b/cpp_src/server/contrib/server.md index 0aab58f38..0b6975eba 100644 --- a/cpp_src/server/contrib/server.md +++ b/cpp_src/server/contrib/server.md @@ -137,7 +137,7 @@ Reindexer is compact, fast and it does not have heavy dependencies. ### Version information -*Version* : 4.17.2 +*Version* : 4.18.0 ### License information diff --git a/cpp_src/server/contrib/server.yml b/cpp_src/server/contrib/server.yml index 1cb0fcc1d..2e9a2abeb 100644 --- a/cpp_src/server/contrib/server.yml +++ b/cpp_src/server/contrib/server.yml @@ -4,7 +4,7 @@ info: **Reindexer** is an embeddable, in-memory, document-oriented database with a high-level Query builder interface. Reindexer's goal is to provide fast search with complex queries. Reindexer is compact, fast and it does not have heavy dependencies. - version: "4.17.2" + version: "4.18.0" title: "Reindexer REST API" license: name: "Apache 2.0" diff --git a/cpp_src/server/grpc/reindexerservice.cc b/cpp_src/server/grpc/reindexerservice.cc index d095db111..b671f31ac 100644 --- a/cpp_src/server/grpc/reindexerservice.cc +++ b/cpp_src/server/grpc/reindexerservice.cc @@ -514,8 +514,6 @@ Error ReindexerService::buildItems(WrSerializer& wrser, reindexer::QueryResults& break; } case EncodingType::PROTOBUF: { - ProtobufBuilder builder(&wrser, ObjType::TypeObject); - ProtobufBuilder array = builder.Array("items"); for (auto& it : qr) { status = it.GetProtobuf(wrser, false); if (!status.ok()) { diff --git a/cpp_src/server/httpserver.cc b/cpp_src/server/httpserver.cc index 39ccd07c2..abf4aed07 100644 --- a/cpp_src/server/httpserver.cc +++ b/cpp_src/server/httpserver.cc @@ -1584,7 +1584,6 @@ int HTTPServer::queryResultsProtobuf(http::Context& ctx, reindexer::QueryResults WrSerializer wrSer(ctx.writer->GetChunk()); ProtobufBuilder protobufBuilder(&wrSer); - int itemsField = kProtoQueryResultsFields.at(kParamItems); auto& lres = res.ToLocalQr(); WrSerializer itemSer; std::vector jsonData; @@ -1596,15 +1595,11 @@ int HTTPServer::queryResultsProtobuf(http::Context& ctx, reindexer::QueryResults jsonData.reserve(size); } for (size_t i = offset; i < lres.Count() && i < offset + limit; i++) { - auto item = protobufBuilder.Object(itemsField); auto it = lres[i]; - auto i1 = item.Object(lres.getNsNumber(it.GetItemRef().Nsid()) + 1); const auto err = it.GetProtobuf(wrSer, false); if (!err.ok()) { return ctx.Protobuf(err.code(), wrSer.DetachChunk()); } - i1.End(); - item.End(); if (withColumns) { itemSer.Reset(); const auto err = it.GetJSON(itemSer, false); diff --git a/cpp_src/server/serverimpl.cc b/cpp_src/server/serverimpl.cc index d70135abd..a15eb4d89 100644 --- a/cpp_src/server/serverimpl.cc +++ b/cpp_src/server/serverimpl.cc @@ -212,7 +212,21 @@ void ServerImpl::ReopenLogFiles() { std::string ServerImpl::GetCoreLogPath() const { return GetDirPath(config_.CoreLog); } +#if defined(WITH_GRPC) && defined(REINDEX_WITH_LIBDL) +static void* tryToOpenGRPCLib(bool enabled) noexcept { +#ifdef __APPLE__ + return enabled ? dlopen("libreindexer_grpc_library.dylib", RTLD_NOW) : nullptr; +#else // __APPLE__ + return enabled ? dlopen("libreindexer_grpc_library.so", RTLD_NOW) : nullptr; +#endif // __APPLE__ +} +#endif // defined(WITH_GRPC) && defined(REINDEX_WITH_LIBDL) + int ServerImpl::run() { +#if defined(WITH_GRPC) && defined(REINDEX_WITH_LIBDL) + void* hGRPCServiceLib = tryToOpenGRPCLib(config_.EnableGRPC); +#endif // defined(WITH_GRPC) && defined(REINDEX_WITH_LIBDL) + auto err = loggerConfigure(); (void)err; // ingore; In case of the multiple builtin servers, we will get errors here @@ -356,29 +370,23 @@ int ServerImpl::run() { #ifdef WITH_GRPC void* hGRPCService = nullptr; -#if REINDEX_WITH_LIBDL -#ifdef __APPLE__ - auto hGRPCServiceLib = dlopen("libreindexer_grpc_library.dylib", RTLD_NOW); -#else - auto hGRPCServiceLib = dlopen("libreindexer_grpc_library.so", RTLD_NOW); -#endif - if (hGRPCServiceLib && config_.EnableGRPC) { - auto start_grpc = reinterpret_cast(dlsym(hGRPCServiceLib, "start_reindexer_grpc")); - - hGRPCService = start_grpc(*dbMgr_, config_.TxIdleTimeout, loop_, config_.GRPCAddr); - logger_.info("Listening gRPC service on {0}", config_.GRPCAddr); - } else if (config_.EnableGRPC) { - logger_.error("Can't load libreindexer_grpc_library. gRPC will not work: {}", dlerror()); - return EXIT_FAILURE; - } -#else if (config_.EnableGRPC) { +#if REINDEX_WITH_LIBDL + if (hGRPCServiceLib) { + auto start_grpc = reinterpret_cast(dlsym(hGRPCServiceLib, "start_reindexer_grpc")); + hGRPCService = start_grpc(*dbMgr_, config_.TxIdleTimeout, loop_, config_.GRPCAddr); + logger_.info("Listening gRPC service on {0}", config_.GRPCAddr); + } else { + logger_.error("Can't load libreindexer_grpc_library. gRPC will not work: {}", dlerror()); + return EXIT_FAILURE; + } +#else // REINDEX_WITH_LIBDL hGRPCService = start_reindexer_grpc(*dbMgr_, config_.TxIdleTimeout, loop_, config_.GRPCAddr); logger_.info("Listening gRPC service on {0}", config_.GRPCAddr); +#endif // REINDEX_WITH_LIBDL } +#endif // WITH_GRPC -#endif -#endif auto sigCallback = [&](ev::sig& sig) { logger_.info("Signal received. Terminating..."); #ifndef REINDEX_WITH_ASAN @@ -438,20 +446,19 @@ int ServerImpl::run() { rpcServerTCP->Stop(); logger_.info("RPC Server(TCP) shutdown completed."); #ifdef WITH_GRPC -#if REINDEX_WITH_LIBDL - if (hGRPCServiceLib && config_.EnableGRPC) { - auto stop_grpc = reinterpret_cast(dlsym(hGRPCServiceLib, "stop_reindexer_grpc")); - stop_grpc(hGRPCService); - logger_.info("gRPC Server shutdown completed."); - } -#else if (config_.EnableGRPC) { +#if REINDEX_WITH_LIBDL + if (hGRPCServiceLib) { + auto stop_grpc = reinterpret_cast(dlsym(hGRPCServiceLib, "stop_reindexer_grpc")); + stop_grpc(hGRPCService); + logger_.info("gRPC Server shutdown completed."); + } +#else // REINDEX_WITH_LIBDL stop_reindexer_grpc(hGRPCService); logger_.info("gRPC Server shutdown completed."); +#endif // REINDEX_WITH_LIBDL } - -#endif -#endif +#endif // WITH_GRPC } catch (const Error& err) { logger_.error("Unhandled exception occurred: {0}", err.what()); } diff --git a/cpp_src/tools/customlocal.cc b/cpp_src/tools/customlocal.cc index 4761e6cbe..fd42ced55 100644 --- a/cpp_src/tools/customlocal.cc +++ b/cpp_src/tools/customlocal.cc @@ -191,6 +191,3020 @@ constexpr std::pair kAlphabet[] = { {0x24D7, 0x24BD}, {0x24D8, 0x24BE}, {0x24D9, 0x24BF}, {0x24DA, 0x24C0}, {0x24DB, 0x24C1}, {0x24DC, 0x24C2}, {0x24DD, 0x24C3}, {0x24DE, 0x24C4}, {0x24DF, 0x24C5}, {0x24E0, 0x24C6}, {0x24E1, 0x24C7}, {0x24E2, 0x24C8}, {0x24E3, 0x24C9}, {0x24E4, 0x24CA}, {0x24E5, 0x24CB}, {0x24E6, 0x24CC}, {0x24E7, 0x24CD}, {0x24E8, 0x24CE}, {0x24E9, 0x24CF}, + //Hiragana + {0x3041, 0x3041}, {0x3042, 0x3042}, {0x3043, 0x3043}, {0x3044, 0x3044}, {0x3045, 0x3045}, {0x3046, 0x3046}, {0x3047, 0x3047}, + {0x3048, 0x3048}, {0x3049, 0x3049}, {0x304A, 0x304A}, {0x304B, 0x304B}, {0x304C, 0x304C}, {0x304D, 0x304D}, {0x304E, 0x304E}, + {0x304F, 0x304F}, {0x3050, 0x3050}, {0x3051, 0x3051}, {0x3052, 0x3052}, {0x3053, 0x3053}, {0x3054, 0x3054}, {0x3055, 0x3055}, + {0x3056, 0x3056}, {0x3057, 0x3057}, {0x3058, 0x3058}, {0x3059, 0x3059}, {0x305A, 0x305A}, {0x305B, 0x305B}, {0x305C, 0x305C}, + {0x305D, 0x305D}, {0x305E, 0x305E}, {0x305F, 0x305F}, {0x3060, 0x3060}, {0x3061, 0x3061}, {0x3062, 0x3062}, {0x3063, 0x3063}, + {0x3064, 0x3064}, {0x3065, 0x3065}, {0x3066, 0x3066}, {0x3067, 0x3067}, {0x3068, 0x3068}, {0x3069, 0x3069}, {0x306A, 0x306A}, + {0x306B, 0x306B}, {0x306C, 0x306C}, {0x306D, 0x306D}, {0x306E, 0x306E}, {0x306F, 0x306F}, {0x3070, 0x3070}, {0x3071, 0x3071}, + {0x3072, 0x3072}, {0x3073, 0x3073}, {0x3074, 0x3074}, {0x3075, 0x3075}, {0x3076, 0x3076}, {0x3077, 0x3077}, {0x3078, 0x3078}, + {0x3079, 0x3079}, {0x307A, 0x307A}, {0x307B, 0x307B}, {0x307C, 0x307C}, {0x307D, 0x307D}, {0x307E, 0x307E}, {0x307F, 0x307F}, + {0x3080, 0x3080}, {0x3081, 0x3081}, {0x3082, 0x3082}, {0x3083, 0x3083}, {0x3084, 0x3084}, {0x3085, 0x3085}, {0x3086, 0x3086}, + {0x3087, 0x3087}, {0x3088, 0x3088}, {0x3089, 0x3089}, {0x308A, 0x308A}, {0x308B, 0x308B}, {0x308C, 0x308C}, {0x308D, 0x308D}, + {0x308E, 0x308E}, {0x308F, 0x308F}, {0x3090, 0x3090}, {0x3091, 0x3091}, {0x3092, 0x3092}, {0x3093, 0x3093}, {0x3094, 0x3094}, + {0x3095, 0x3095}, {0x3096, 0x3096}, {0x3099, 0x3099}, {0x309A, 0x309A}, {0x309D, 0x309D}, {0x309E, 0x309E}, {0x309F, 0x309F}, + //CJK Unified Ideographs + {0x4E00, 0x4E00}, {0x4E01, 0x4E01}, {0x4E02, 0x4E02}, {0x4E03, 0x4E03}, {0x4E04, 0x4E04}, {0x4E05, 0x4E05}, {0x4E06, 0x4E06}, + {0x4E07, 0x4E07}, {0x4E08, 0x4E08}, {0x4E09, 0x4E09}, {0x4E0A, 0x4E0A}, {0x4E0B, 0x4E0B}, {0x4E0C, 0x4E0C}, {0x4E0D, 0x4E0D}, + {0x4E0E, 0x4E0E}, {0x4E0F, 0x4E0F}, {0x4E10, 0x4E10}, {0x4E11, 0x4E11}, {0x4E12, 0x4E12}, {0x4E13, 0x4E13}, {0x4E14, 0x4E14}, + {0x4E15, 0x4E15}, {0x4E16, 0x4E16}, {0x4E17, 0x4E17}, {0x4E18, 0x4E18}, {0x4E19, 0x4E19}, {0x4E1A, 0x4E1A}, {0x4E1B, 0x4E1B}, + {0x4E1C, 0x4E1C}, {0x4E1D, 0x4E1D}, {0x4E1E, 0x4E1E}, {0x4E1F, 0x4E1F}, {0x4E20, 0x4E20}, {0x4E21, 0x4E21}, {0x4E22, 0x4E22}, + {0x4E23, 0x4E23}, {0x4E24, 0x4E24}, {0x4E25, 0x4E25}, {0x4E26, 0x4E26}, {0x4E27, 0x4E27}, {0x4E28, 0x4E28}, {0x4E29, 0x4E29}, + {0x4E2A, 0x4E2A}, {0x4E2B, 0x4E2B}, {0x4E2C, 0x4E2C}, {0x4E2D, 0x4E2D}, {0x4E2E, 0x4E2E}, {0x4E2F, 0x4E2F}, {0x4E30, 0x4E30}, + {0x4E31, 0x4E31}, {0x4E32, 0x4E32}, {0x4E33, 0x4E33}, {0x4E34, 0x4E34}, {0x4E35, 0x4E35}, {0x4E36, 0x4E36}, {0x4E37, 0x4E37}, + {0x4E38, 0x4E38}, {0x4E39, 0x4E39}, {0x4E3A, 0x4E3A}, {0x4E3B, 0x4E3B}, {0x4E3C, 0x4E3C}, {0x4E3D, 0x4E3D}, {0x4E3E, 0x4E3E}, + {0x4E3F, 0x4E3F}, {0x4E40, 0x4E40}, {0x4E41, 0x4E41}, {0x4E42, 0x4E42}, {0x4E43, 0x4E43}, {0x4E44, 0x4E44}, {0x4E45, 0x4E45}, + {0x4E46, 0x4E46}, {0x4E47, 0x4E47}, {0x4E48, 0x4E48}, {0x4E49, 0x4E49}, {0x4E4A, 0x4E4A}, {0x4E4B, 0x4E4B}, {0x4E4C, 0x4E4C}, + {0x4E4D, 0x4E4D}, {0x4E4E, 0x4E4E}, {0x4E4F, 0x4E4F}, {0x4E50, 0x4E50}, {0x4E51, 0x4E51}, {0x4E52, 0x4E52}, {0x4E53, 0x4E53}, + {0x4E54, 0x4E54}, {0x4E55, 0x4E55}, {0x4E56, 0x4E56}, {0x4E57, 0x4E57}, {0x4E58, 0x4E58}, {0x4E59, 0x4E59}, {0x4E5A, 0x4E5A}, + {0x4E5B, 0x4E5B}, {0x4E5C, 0x4E5C}, {0x4E5D, 0x4E5D}, {0x4E5E, 0x4E5E}, {0x4E5F, 0x4E5F}, {0x4E60, 0x4E60}, {0x4E61, 0x4E61}, + {0x4E62, 0x4E62}, {0x4E63, 0x4E63}, {0x4E64, 0x4E64}, {0x4E65, 0x4E65}, {0x4E66, 0x4E66}, {0x4E67, 0x4E67}, {0x4E68, 0x4E68}, + {0x4E69, 0x4E69}, {0x4E6A, 0x4E6A}, {0x4E6B, 0x4E6B}, {0x4E6C, 0x4E6C}, {0x4E6D, 0x4E6D}, {0x4E6E, 0x4E6E}, {0x4E6F, 0x4E6F}, + {0x4E70, 0x4E70}, {0x4E71, 0x4E71}, {0x4E72, 0x4E72}, {0x4E73, 0x4E73}, {0x4E74, 0x4E74}, {0x4E75, 0x4E75}, {0x4E76, 0x4E76}, + {0x4E77, 0x4E77}, {0x4E78, 0x4E78}, {0x4E79, 0x4E79}, {0x4E7A, 0x4E7A}, {0x4E7B, 0x4E7B}, {0x4E7C, 0x4E7C}, {0x4E7D, 0x4E7D}, + {0x4E7E, 0x4E7E}, {0x4E7F, 0x4E7F}, {0x4E80, 0x4E80}, {0x4E81, 0x4E81}, {0x4E82, 0x4E82}, {0x4E83, 0x4E83}, {0x4E84, 0x4E84}, + {0x4E85, 0x4E85}, {0x4E86, 0x4E86}, {0x4E87, 0x4E87}, {0x4E88, 0x4E88}, {0x4E89, 0x4E89}, {0x4E8A, 0x4E8A}, {0x4E8B, 0x4E8B}, + {0x4E8C, 0x4E8C}, {0x4E8D, 0x4E8D}, {0x4E8E, 0x4E8E}, {0x4E8F, 0x4E8F}, {0x4E90, 0x4E90}, {0x4E91, 0x4E91}, {0x4E92, 0x4E92}, + {0x4E93, 0x4E93}, {0x4E94, 0x4E94}, {0x4E95, 0x4E95}, {0x4E96, 0x4E96}, {0x4E97, 0x4E97}, {0x4E98, 0x4E98}, {0x4E99, 0x4E99}, + {0x4E9A, 0x4E9A}, {0x4E9B, 0x4E9B}, {0x4E9C, 0x4E9C}, {0x4E9D, 0x4E9D}, {0x4E9E, 0x4E9E}, {0x4E9F, 0x4E9F}, {0x4EA0, 0x4EA0}, + {0x4EA1, 0x4EA1}, {0x4EA2, 0x4EA2}, {0x4EA3, 0x4EA3}, {0x4EA4, 0x4EA4}, {0x4EA5, 0x4EA5}, {0x4EA6, 0x4EA6}, {0x4EA7, 0x4EA7}, + {0x4EA8, 0x4EA8}, {0x4EA9, 0x4EA9}, {0x4EAA, 0x4EAA}, {0x4EAB, 0x4EAB}, {0x4EAC, 0x4EAC}, {0x4EAD, 0x4EAD}, {0x4EAE, 0x4EAE}, + {0x4EAF, 0x4EAF}, {0x4EB0, 0x4EB0}, {0x4EB1, 0x4EB1}, {0x4EB2, 0x4EB2}, {0x4EB3, 0x4EB3}, {0x4EB4, 0x4EB4}, {0x4EB5, 0x4EB5}, + {0x4EB6, 0x4EB6}, {0x4EB7, 0x4EB7}, {0x4EB8, 0x4EB8}, {0x4EB9, 0x4EB9}, {0x4EBA, 0x4EBA}, {0x4EBB, 0x4EBB}, {0x4EBC, 0x4EBC}, + {0x4EBD, 0x4EBD}, {0x4EBE, 0x4EBE}, {0x4EBF, 0x4EBF}, {0x4EC0, 0x4EC0}, {0x4EC1, 0x4EC1}, {0x4EC2, 0x4EC2}, {0x4EC3, 0x4EC3}, + {0x4EC4, 0x4EC4}, {0x4EC5, 0x4EC5}, {0x4EC6, 0x4EC6}, {0x4EC7, 0x4EC7}, {0x4EC8, 0x4EC8}, {0x4EC9, 0x4EC9}, {0x4ECA, 0x4ECA}, + {0x4ECB, 0x4ECB}, {0x4ECC, 0x4ECC}, {0x4ECD, 0x4ECD}, {0x4ECE, 0x4ECE}, {0x4ECF, 0x4ECF}, {0x4ED0, 0x4ED0}, {0x4ED1, 0x4ED1}, + {0x4ED2, 0x4ED2}, {0x4ED3, 0x4ED3}, {0x4ED4, 0x4ED4}, {0x4ED5, 0x4ED5}, {0x4ED6, 0x4ED6}, {0x4ED7, 0x4ED7}, {0x4ED8, 0x4ED8}, + {0x4ED9, 0x4ED9}, {0x4EDA, 0x4EDA}, {0x4EDB, 0x4EDB}, {0x4EDC, 0x4EDC}, {0x4EDD, 0x4EDD}, {0x4EDE, 0x4EDE}, {0x4EDF, 0x4EDF}, + {0x4EE0, 0x4EE0}, {0x4EE1, 0x4EE1}, {0x4EE2, 0x4EE2}, {0x4EE3, 0x4EE3}, {0x4EE4, 0x4EE4}, {0x4EE5, 0x4EE5}, {0x4EE6, 0x4EE6}, + {0x4EE7, 0x4EE7}, {0x4EE8, 0x4EE8}, {0x4EE9, 0x4EE9}, {0x4EEA, 0x4EEA}, {0x4EEB, 0x4EEB}, {0x4EEC, 0x4EEC}, {0x4EED, 0x4EED}, + {0x4EEE, 0x4EEE}, {0x4EEF, 0x4EEF}, {0x4EF0, 0x4EF0}, {0x4EF1, 0x4EF1}, {0x4EF2, 0x4EF2}, {0x4EF3, 0x4EF3}, {0x4EF4, 0x4EF4}, + {0x4EF5, 0x4EF5}, {0x4EF6, 0x4EF6}, {0x4EF7, 0x4EF7}, {0x4EF8, 0x4EF8}, {0x4EF9, 0x4EF9}, {0x4EFA, 0x4EFA}, {0x4EFB, 0x4EFB}, + {0x4EFC, 0x4EFC}, {0x4EFD, 0x4EFD}, {0x4EFE, 0x4EFE}, {0x4EFF, 0x4EFF}, {0x4F00, 0x4F00}, {0x4F01, 0x4F01}, {0x4F02, 0x4F02}, + {0x4F03, 0x4F03}, {0x4F04, 0x4F04}, {0x4F05, 0x4F05}, {0x4F06, 0x4F06}, {0x4F07, 0x4F07}, {0x4F08, 0x4F08}, {0x4F09, 0x4F09}, + {0x4F0A, 0x4F0A}, {0x4F0B, 0x4F0B}, {0x4F0C, 0x4F0C}, {0x4F0D, 0x4F0D}, {0x4F0E, 0x4F0E}, {0x4F0F, 0x4F0F}, {0x4F10, 0x4F10}, + {0x4F11, 0x4F11}, {0x4F12, 0x4F12}, {0x4F13, 0x4F13}, {0x4F14, 0x4F14}, {0x4F15, 0x4F15}, {0x4F16, 0x4F16}, {0x4F17, 0x4F17}, + {0x4F18, 0x4F18}, {0x4F19, 0x4F19}, {0x4F1A, 0x4F1A}, {0x4F1B, 0x4F1B}, {0x4F1C, 0x4F1C}, {0x4F1D, 0x4F1D}, {0x4F1E, 0x4F1E}, + {0x4F1F, 0x4F1F}, {0x4F20, 0x4F20}, {0x4F21, 0x4F21}, {0x4F22, 0x4F22}, {0x4F23, 0x4F23}, {0x4F24, 0x4F24}, {0x4F25, 0x4F25}, + {0x4F26, 0x4F26}, {0x4F27, 0x4F27}, {0x4F28, 0x4F28}, {0x4F29, 0x4F29}, {0x4F2A, 0x4F2A}, {0x4F2B, 0x4F2B}, {0x4F2C, 0x4F2C}, + {0x4F2D, 0x4F2D}, {0x4F2E, 0x4F2E}, {0x4F2F, 0x4F2F}, {0x4F30, 0x4F30}, {0x4F31, 0x4F31}, {0x4F32, 0x4F32}, {0x4F33, 0x4F33}, + {0x4F34, 0x4F34}, {0x4F35, 0x4F35}, {0x4F36, 0x4F36}, {0x4F37, 0x4F37}, {0x4F38, 0x4F38}, {0x4F39, 0x4F39}, {0x4F3A, 0x4F3A}, + {0x4F3B, 0x4F3B}, {0x4F3C, 0x4F3C}, {0x4F3D, 0x4F3D}, {0x4F3E, 0x4F3E}, {0x4F3F, 0x4F3F}, {0x4F40, 0x4F40}, {0x4F41, 0x4F41}, + {0x4F42, 0x4F42}, {0x4F43, 0x4F43}, {0x4F44, 0x4F44}, {0x4F45, 0x4F45}, {0x4F46, 0x4F46}, {0x4F47, 0x4F47}, {0x4F48, 0x4F48}, + {0x4F49, 0x4F49}, {0x4F4A, 0x4F4A}, {0x4F4B, 0x4F4B}, {0x4F4C, 0x4F4C}, {0x4F4D, 0x4F4D}, {0x4F4E, 0x4F4E}, {0x4F4F, 0x4F4F}, + {0x4F50, 0x4F50}, {0x4F51, 0x4F51}, {0x4F52, 0x4F52}, {0x4F53, 0x4F53}, {0x4F54, 0x4F54}, {0x4F55, 0x4F55}, {0x4F56, 0x4F56}, + {0x4F57, 0x4F57}, {0x4F58, 0x4F58}, {0x4F59, 0x4F59}, {0x4F5A, 0x4F5A}, {0x4F5B, 0x4F5B}, {0x4F5C, 0x4F5C}, {0x4F5D, 0x4F5D}, + {0x4F5E, 0x4F5E}, {0x4F5F, 0x4F5F}, {0x4F60, 0x4F60}, {0x4F61, 0x4F61}, {0x4F62, 0x4F62}, {0x4F63, 0x4F63}, {0x4F64, 0x4F64}, + {0x4F65, 0x4F65}, {0x4F66, 0x4F66}, {0x4F67, 0x4F67}, {0x4F68, 0x4F68}, {0x4F69, 0x4F69}, {0x4F6A, 0x4F6A}, {0x4F6B, 0x4F6B}, + {0x4F6C, 0x4F6C}, {0x4F6D, 0x4F6D}, {0x4F6E, 0x4F6E}, {0x4F6F, 0x4F6F}, {0x4F70, 0x4F70}, {0x4F71, 0x4F71}, {0x4F72, 0x4F72}, + {0x4F73, 0x4F73}, {0x4F74, 0x4F74}, {0x4F75, 0x4F75}, {0x4F76, 0x4F76}, {0x4F77, 0x4F77}, {0x4F78, 0x4F78}, {0x4F79, 0x4F79}, + {0x4F7A, 0x4F7A}, {0x4F7B, 0x4F7B}, {0x4F7C, 0x4F7C}, {0x4F7D, 0x4F7D}, {0x4F7E, 0x4F7E}, {0x4F7F, 0x4F7F}, {0x4F80, 0x4F80}, + {0x4F81, 0x4F81}, {0x4F82, 0x4F82}, {0x4F83, 0x4F83}, {0x4F84, 0x4F84}, {0x4F85, 0x4F85}, {0x4F86, 0x4F86}, {0x4F87, 0x4F87}, + {0x4F88, 0x4F88}, {0x4F89, 0x4F89}, {0x4F8A, 0x4F8A}, {0x4F8B, 0x4F8B}, {0x4F8C, 0x4F8C}, {0x4F8D, 0x4F8D}, {0x4F8E, 0x4F8E}, + {0x4F8F, 0x4F8F}, {0x4F90, 0x4F90}, {0x4F91, 0x4F91}, {0x4F92, 0x4F92}, {0x4F93, 0x4F93}, {0x4F94, 0x4F94}, {0x4F95, 0x4F95}, + {0x4F96, 0x4F96}, {0x4F97, 0x4F97}, {0x4F98, 0x4F98}, {0x4F99, 0x4F99}, {0x4F9A, 0x4F9A}, {0x4F9B, 0x4F9B}, {0x4F9C, 0x4F9C}, + {0x4F9D, 0x4F9D}, {0x4F9E, 0x4F9E}, {0x4F9F, 0x4F9F}, {0x4FA0, 0x4FA0}, {0x4FA1, 0x4FA1}, {0x4FA2, 0x4FA2}, {0x4FA3, 0x4FA3}, + {0x4FA4, 0x4FA4}, {0x4FA5, 0x4FA5}, {0x4FA6, 0x4FA6}, {0x4FA7, 0x4FA7}, {0x4FA8, 0x4FA8}, {0x4FA9, 0x4FA9}, {0x4FAA, 0x4FAA}, + {0x4FAB, 0x4FAB}, {0x4FAC, 0x4FAC}, {0x4FAD, 0x4FAD}, {0x4FAE, 0x4FAE}, {0x4FAF, 0x4FAF}, {0x4FB0, 0x4FB0}, {0x4FB1, 0x4FB1}, + {0x4FB2, 0x4FB2}, {0x4FB3, 0x4FB3}, {0x4FB4, 0x4FB4}, {0x4FB5, 0x4FB5}, {0x4FB6, 0x4FB6}, {0x4FB7, 0x4FB7}, {0x4FB8, 0x4FB8}, + {0x4FB9, 0x4FB9}, {0x4FBA, 0x4FBA}, {0x4FBB, 0x4FBB}, {0x4FBC, 0x4FBC}, {0x4FBD, 0x4FBD}, {0x4FBE, 0x4FBE}, {0x4FBF, 0x4FBF}, + {0x4FC0, 0x4FC0}, {0x4FC1, 0x4FC1}, {0x4FC2, 0x4FC2}, {0x4FC3, 0x4FC3}, {0x4FC4, 0x4FC4}, {0x4FC5, 0x4FC5}, {0x4FC6, 0x4FC6}, + {0x4FC7, 0x4FC7}, {0x4FC8, 0x4FC8}, {0x4FC9, 0x4FC9}, {0x4FCA, 0x4FCA}, {0x4FCB, 0x4FCB}, {0x4FCC, 0x4FCC}, {0x4FCD, 0x4FCD}, + {0x4FCE, 0x4FCE}, {0x4FCF, 0x4FCF}, {0x4FD0, 0x4FD0}, {0x4FD1, 0x4FD1}, {0x4FD2, 0x4FD2}, {0x4FD3, 0x4FD3}, {0x4FD4, 0x4FD4}, + {0x4FD5, 0x4FD5}, {0x4FD6, 0x4FD6}, {0x4FD7, 0x4FD7}, {0x4FD8, 0x4FD8}, {0x4FD9, 0x4FD9}, {0x4FDA, 0x4FDA}, {0x4FDB, 0x4FDB}, + {0x4FDC, 0x4FDC}, {0x4FDD, 0x4FDD}, {0x4FDE, 0x4FDE}, {0x4FDF, 0x4FDF}, {0x4FE0, 0x4FE0}, {0x4FE1, 0x4FE1}, {0x4FE2, 0x4FE2}, + {0x4FE3, 0x4FE3}, {0x4FE4, 0x4FE4}, {0x4FE5, 0x4FE5}, {0x4FE6, 0x4FE6}, {0x4FE7, 0x4FE7}, {0x4FE8, 0x4FE8}, {0x4FE9, 0x4FE9}, + {0x4FEA, 0x4FEA}, {0x4FEB, 0x4FEB}, {0x4FEC, 0x4FEC}, {0x4FED, 0x4FED}, {0x4FEE, 0x4FEE}, {0x4FEF, 0x4FEF}, {0x4FF0, 0x4FF0}, + {0x4FF1, 0x4FF1}, {0x4FF2, 0x4FF2}, {0x4FF3, 0x4FF3}, {0x4FF4, 0x4FF4}, {0x4FF5, 0x4FF5}, {0x4FF6, 0x4FF6}, {0x4FF7, 0x4FF7}, + {0x4FF8, 0x4FF8}, {0x4FF9, 0x4FF9}, {0x4FFA, 0x4FFA}, {0x4FFB, 0x4FFB}, {0x4FFC, 0x4FFC}, {0x4FFD, 0x4FFD}, {0x4FFE, 0x4FFE}, + {0x4FFF, 0x4FFF}, {0x5000, 0x5000}, {0x5001, 0x5001}, {0x5002, 0x5002}, {0x5003, 0x5003}, {0x5004, 0x5004}, {0x5005, 0x5005}, + {0x5006, 0x5006}, {0x5007, 0x5007}, {0x5008, 0x5008}, {0x5009, 0x5009}, {0x500A, 0x500A}, {0x500B, 0x500B}, {0x500C, 0x500C}, + {0x500D, 0x500D}, {0x500E, 0x500E}, {0x500F, 0x500F}, {0x5010, 0x5010}, {0x5011, 0x5011}, {0x5012, 0x5012}, {0x5013, 0x5013}, + {0x5014, 0x5014}, {0x5015, 0x5015}, {0x5016, 0x5016}, {0x5017, 0x5017}, {0x5018, 0x5018}, {0x5019, 0x5019}, {0x501A, 0x501A}, + {0x501B, 0x501B}, {0x501C, 0x501C}, {0x501D, 0x501D}, {0x501E, 0x501E}, {0x501F, 0x501F}, {0x5020, 0x5020}, {0x5021, 0x5021}, + {0x5022, 0x5022}, {0x5023, 0x5023}, {0x5024, 0x5024}, {0x5025, 0x5025}, {0x5026, 0x5026}, {0x5027, 0x5027}, {0x5028, 0x5028}, + {0x5029, 0x5029}, {0x502A, 0x502A}, {0x502B, 0x502B}, {0x502C, 0x502C}, {0x502D, 0x502D}, {0x502E, 0x502E}, {0x502F, 0x502F}, + {0x5030, 0x5030}, {0x5031, 0x5031}, {0x5032, 0x5032}, {0x5033, 0x5033}, {0x5034, 0x5034}, {0x5035, 0x5035}, {0x5036, 0x5036}, + {0x5037, 0x5037}, {0x5038, 0x5038}, {0x5039, 0x5039}, {0x503A, 0x503A}, {0x503B, 0x503B}, {0x503C, 0x503C}, {0x503D, 0x503D}, + {0x503E, 0x503E}, {0x503F, 0x503F}, {0x5040, 0x5040}, {0x5041, 0x5041}, {0x5042, 0x5042}, {0x5043, 0x5043}, {0x5044, 0x5044}, + {0x5045, 0x5045}, {0x5046, 0x5046}, {0x5047, 0x5047}, {0x5048, 0x5048}, {0x5049, 0x5049}, {0x504A, 0x504A}, {0x504B, 0x504B}, + {0x504C, 0x504C}, {0x504D, 0x504D}, {0x504E, 0x504E}, {0x504F, 0x504F}, {0x5050, 0x5050}, {0x5051, 0x5051}, {0x5052, 0x5052}, + {0x5053, 0x5053}, {0x5054, 0x5054}, {0x5055, 0x5055}, {0x5056, 0x5056}, {0x5057, 0x5057}, {0x5058, 0x5058}, {0x5059, 0x5059}, + {0x505A, 0x505A}, {0x505B, 0x505B}, {0x505C, 0x505C}, {0x505D, 0x505D}, {0x505E, 0x505E}, {0x505F, 0x505F}, {0x5060, 0x5060}, + {0x5061, 0x5061}, {0x5062, 0x5062}, {0x5063, 0x5063}, {0x5064, 0x5064}, {0x5065, 0x5065}, {0x5066, 0x5066}, {0x5067, 0x5067}, + {0x5068, 0x5068}, {0x5069, 0x5069}, {0x506A, 0x506A}, {0x506B, 0x506B}, {0x506C, 0x506C}, {0x506D, 0x506D}, {0x506E, 0x506E}, + {0x506F, 0x506F}, {0x5070, 0x5070}, {0x5071, 0x5071}, {0x5072, 0x5072}, {0x5073, 0x5073}, {0x5074, 0x5074}, {0x5075, 0x5075}, + {0x5076, 0x5076}, {0x5077, 0x5077}, {0x5078, 0x5078}, {0x5079, 0x5079}, {0x507A, 0x507A}, {0x507B, 0x507B}, {0x507C, 0x507C}, + {0x507D, 0x507D}, {0x507E, 0x507E}, {0x507F, 0x507F}, {0x5080, 0x5080}, {0x5081, 0x5081}, {0x5082, 0x5082}, {0x5083, 0x5083}, + {0x5084, 0x5084}, {0x5085, 0x5085}, {0x5086, 0x5086}, {0x5087, 0x5087}, {0x5088, 0x5088}, {0x5089, 0x5089}, {0x508A, 0x508A}, + {0x508B, 0x508B}, {0x508C, 0x508C}, {0x508D, 0x508D}, {0x508E, 0x508E}, {0x508F, 0x508F}, {0x5090, 0x5090}, {0x5091, 0x5091}, + {0x5092, 0x5092}, {0x5093, 0x5093}, {0x5094, 0x5094}, {0x5095, 0x5095}, {0x5096, 0x5096}, {0x5097, 0x5097}, {0x5098, 0x5098}, + {0x5099, 0x5099}, {0x509A, 0x509A}, {0x509B, 0x509B}, {0x509C, 0x509C}, {0x509D, 0x509D}, {0x509E, 0x509E}, {0x509F, 0x509F}, + {0x50A0, 0x50A0}, {0x50A1, 0x50A1}, {0x50A2, 0x50A2}, {0x50A3, 0x50A3}, {0x50A4, 0x50A4}, {0x50A5, 0x50A5}, {0x50A6, 0x50A6}, + {0x50A7, 0x50A7}, {0x50A8, 0x50A8}, {0x50A9, 0x50A9}, {0x50AA, 0x50AA}, {0x50AB, 0x50AB}, {0x50AC, 0x50AC}, {0x50AD, 0x50AD}, + {0x50AE, 0x50AE}, {0x50AF, 0x50AF}, {0x50B0, 0x50B0}, {0x50B1, 0x50B1}, {0x50B2, 0x50B2}, {0x50B3, 0x50B3}, {0x50B4, 0x50B4}, + {0x50B5, 0x50B5}, {0x50B6, 0x50B6}, {0x50B7, 0x50B7}, {0x50B8, 0x50B8}, {0x50B9, 0x50B9}, {0x50BA, 0x50BA}, {0x50BB, 0x50BB}, + {0x50BC, 0x50BC}, {0x50BD, 0x50BD}, {0x50BE, 0x50BE}, {0x50BF, 0x50BF}, {0x50C0, 0x50C0}, {0x50C1, 0x50C1}, {0x50C2, 0x50C2}, + {0x50C3, 0x50C3}, {0x50C4, 0x50C4}, {0x50C5, 0x50C5}, {0x50C6, 0x50C6}, {0x50C7, 0x50C7}, {0x50C8, 0x50C8}, {0x50C9, 0x50C9}, + {0x50CA, 0x50CA}, {0x50CB, 0x50CB}, {0x50CC, 0x50CC}, {0x50CD, 0x50CD}, {0x50CE, 0x50CE}, {0x50CF, 0x50CF}, {0x50D0, 0x50D0}, + {0x50D1, 0x50D1}, {0x50D2, 0x50D2}, {0x50D3, 0x50D3}, {0x50D4, 0x50D4}, {0x50D5, 0x50D5}, {0x50D6, 0x50D6}, {0x50D7, 0x50D7}, + {0x50D8, 0x50D8}, {0x50D9, 0x50D9}, {0x50DA, 0x50DA}, {0x50DB, 0x50DB}, {0x50DC, 0x50DC}, {0x50DD, 0x50DD}, {0x50DE, 0x50DE}, + {0x50DF, 0x50DF}, {0x50E0, 0x50E0}, {0x50E1, 0x50E1}, {0x50E2, 0x50E2}, {0x50E3, 0x50E3}, {0x50E4, 0x50E4}, {0x50E5, 0x50E5}, + {0x50E6, 0x50E6}, {0x50E7, 0x50E7}, {0x50E8, 0x50E8}, {0x50E9, 0x50E9}, {0x50EA, 0x50EA}, {0x50EB, 0x50EB}, {0x50EC, 0x50EC}, + {0x50ED, 0x50ED}, {0x50EE, 0x50EE}, {0x50EF, 0x50EF}, {0x50F0, 0x50F0}, {0x50F1, 0x50F1}, {0x50F2, 0x50F2}, {0x50F3, 0x50F3}, + {0x50F4, 0x50F4}, {0x50F5, 0x50F5}, {0x50F6, 0x50F6}, {0x50F7, 0x50F7}, {0x50F8, 0x50F8}, {0x50F9, 0x50F9}, {0x50FA, 0x50FA}, + {0x50FB, 0x50FB}, {0x50FC, 0x50FC}, {0x50FD, 0x50FD}, {0x50FE, 0x50FE}, {0x50FF, 0x50FF}, {0x5100, 0x5100}, {0x5101, 0x5101}, + {0x5102, 0x5102}, {0x5103, 0x5103}, {0x5104, 0x5104}, {0x5105, 0x5105}, {0x5106, 0x5106}, {0x5107, 0x5107}, {0x5108, 0x5108}, + {0x5109, 0x5109}, {0x510A, 0x510A}, {0x510B, 0x510B}, {0x510C, 0x510C}, {0x510D, 0x510D}, {0x510E, 0x510E}, {0x510F, 0x510F}, + {0x5110, 0x5110}, {0x5111, 0x5111}, {0x5112, 0x5112}, {0x5113, 0x5113}, {0x5114, 0x5114}, {0x5115, 0x5115}, {0x5116, 0x5116}, + {0x5117, 0x5117}, {0x5118, 0x5118}, {0x5119, 0x5119}, {0x511A, 0x511A}, {0x511B, 0x511B}, {0x511C, 0x511C}, {0x511D, 0x511D}, + {0x511E, 0x511E}, {0x511F, 0x511F}, {0x5120, 0x5120}, {0x5121, 0x5121}, {0x5122, 0x5122}, {0x5123, 0x5123}, {0x5124, 0x5124}, + {0x5125, 0x5125}, {0x5126, 0x5126}, {0x5127, 0x5127}, {0x5128, 0x5128}, {0x5129, 0x5129}, {0x512A, 0x512A}, {0x512B, 0x512B}, + {0x512C, 0x512C}, {0x512D, 0x512D}, {0x512E, 0x512E}, {0x512F, 0x512F}, {0x5130, 0x5130}, {0x5131, 0x5131}, {0x5132, 0x5132}, + {0x5133, 0x5133}, {0x5134, 0x5134}, {0x5135, 0x5135}, {0x5136, 0x5136}, {0x5137, 0x5137}, {0x5138, 0x5138}, {0x5139, 0x5139}, + {0x513A, 0x513A}, {0x513B, 0x513B}, {0x513C, 0x513C}, {0x513D, 0x513D}, {0x513E, 0x513E}, {0x513F, 0x513F}, {0x5140, 0x5140}, + {0x5141, 0x5141}, {0x5142, 0x5142}, {0x5143, 0x5143}, {0x5144, 0x5144}, {0x5145, 0x5145}, {0x5146, 0x5146}, {0x5147, 0x5147}, + {0x5148, 0x5148}, {0x5149, 0x5149}, {0x514A, 0x514A}, {0x514B, 0x514B}, {0x514C, 0x514C}, {0x514D, 0x514D}, {0x514E, 0x514E}, + {0x514F, 0x514F}, {0x5150, 0x5150}, {0x5151, 0x5151}, {0x5152, 0x5152}, {0x5153, 0x5153}, {0x5154, 0x5154}, {0x5155, 0x5155}, + {0x5156, 0x5156}, {0x5157, 0x5157}, {0x5158, 0x5158}, {0x5159, 0x5159}, {0x515A, 0x515A}, {0x515B, 0x515B}, {0x515C, 0x515C}, + {0x515D, 0x515D}, {0x515E, 0x515E}, {0x515F, 0x515F}, {0x5160, 0x5160}, {0x5161, 0x5161}, {0x5162, 0x5162}, {0x5163, 0x5163}, + {0x5164, 0x5164}, {0x5165, 0x5165}, {0x5166, 0x5166}, {0x5167, 0x5167}, {0x5168, 0x5168}, {0x5169, 0x5169}, {0x516A, 0x516A}, + {0x516B, 0x516B}, {0x516C, 0x516C}, {0x516D, 0x516D}, {0x516E, 0x516E}, {0x516F, 0x516F}, {0x5170, 0x5170}, {0x5171, 0x5171}, + {0x5172, 0x5172}, {0x5173, 0x5173}, {0x5174, 0x5174}, {0x5175, 0x5175}, {0x5176, 0x5176}, {0x5177, 0x5177}, {0x5178, 0x5178}, + {0x5179, 0x5179}, {0x517A, 0x517A}, {0x517B, 0x517B}, {0x517C, 0x517C}, {0x517D, 0x517D}, {0x517E, 0x517E}, {0x517F, 0x517F}, + {0x5180, 0x5180}, {0x5181, 0x5181}, {0x5182, 0x5182}, {0x5183, 0x5183}, {0x5184, 0x5184}, {0x5185, 0x5185}, {0x5186, 0x5186}, + {0x5187, 0x5187}, {0x5188, 0x5188}, {0x5189, 0x5189}, {0x518A, 0x518A}, {0x518B, 0x518B}, {0x518C, 0x518C}, {0x518D, 0x518D}, + {0x518E, 0x518E}, {0x518F, 0x518F}, {0x5190, 0x5190}, {0x5191, 0x5191}, {0x5192, 0x5192}, {0x5193, 0x5193}, {0x5194, 0x5194}, + {0x5195, 0x5195}, {0x5196, 0x5196}, {0x5197, 0x5197}, {0x5198, 0x5198}, {0x5199, 0x5199}, {0x519A, 0x519A}, {0x519B, 0x519B}, + {0x519C, 0x519C}, {0x519D, 0x519D}, {0x519E, 0x519E}, {0x519F, 0x519F}, {0x51A0, 0x51A0}, {0x51A1, 0x51A1}, {0x51A2, 0x51A2}, + {0x51A3, 0x51A3}, {0x51A4, 0x51A4}, {0x51A5, 0x51A5}, {0x51A6, 0x51A6}, {0x51A7, 0x51A7}, {0x51A8, 0x51A8}, {0x51A9, 0x51A9}, + {0x51AA, 0x51AA}, {0x51AB, 0x51AB}, {0x51AC, 0x51AC}, {0x51AD, 0x51AD}, {0x51AE, 0x51AE}, {0x51AF, 0x51AF}, {0x51B0, 0x51B0}, + {0x51B1, 0x51B1}, {0x51B2, 0x51B2}, {0x51B3, 0x51B3}, {0x51B4, 0x51B4}, {0x51B5, 0x51B5}, {0x51B6, 0x51B6}, {0x51B7, 0x51B7}, + {0x51B8, 0x51B8}, {0x51B9, 0x51B9}, {0x51BA, 0x51BA}, {0x51BB, 0x51BB}, {0x51BC, 0x51BC}, {0x51BD, 0x51BD}, {0x51BE, 0x51BE}, + {0x51BF, 0x51BF}, {0x51C0, 0x51C0}, {0x51C1, 0x51C1}, {0x51C2, 0x51C2}, {0x51C3, 0x51C3}, {0x51C4, 0x51C4}, {0x51C5, 0x51C5}, + {0x51C6, 0x51C6}, {0x51C7, 0x51C7}, {0x51C8, 0x51C8}, {0x51C9, 0x51C9}, {0x51CA, 0x51CA}, {0x51CB, 0x51CB}, {0x51CC, 0x51CC}, + {0x51CD, 0x51CD}, {0x51CE, 0x51CE}, {0x51CF, 0x51CF}, {0x51D0, 0x51D0}, {0x51D1, 0x51D1}, {0x51D2, 0x51D2}, {0x51D3, 0x51D3}, + {0x51D4, 0x51D4}, {0x51D5, 0x51D5}, {0x51D6, 0x51D6}, {0x51D7, 0x51D7}, {0x51D8, 0x51D8}, {0x51D9, 0x51D9}, {0x51DA, 0x51DA}, + {0x51DB, 0x51DB}, {0x51DC, 0x51DC}, {0x51DD, 0x51DD}, {0x51DE, 0x51DE}, {0x51DF, 0x51DF}, {0x51E0, 0x51E0}, {0x51E1, 0x51E1}, + {0x51E2, 0x51E2}, {0x51E3, 0x51E3}, {0x51E4, 0x51E4}, {0x51E5, 0x51E5}, {0x51E6, 0x51E6}, {0x51E7, 0x51E7}, {0x51E8, 0x51E8}, + {0x51E9, 0x51E9}, {0x51EA, 0x51EA}, {0x51EB, 0x51EB}, {0x51EC, 0x51EC}, {0x51ED, 0x51ED}, {0x51EE, 0x51EE}, {0x51EF, 0x51EF}, + {0x51F0, 0x51F0}, {0x51F1, 0x51F1}, {0x51F2, 0x51F2}, {0x51F3, 0x51F3}, {0x51F4, 0x51F4}, {0x51F5, 0x51F5}, {0x51F6, 0x51F6}, + {0x51F7, 0x51F7}, {0x51F8, 0x51F8}, {0x51F9, 0x51F9}, {0x51FA, 0x51FA}, {0x51FB, 0x51FB}, {0x51FC, 0x51FC}, {0x51FD, 0x51FD}, + {0x51FE, 0x51FE}, {0x51FF, 0x51FF}, {0x5200, 0x5200}, {0x5201, 0x5201}, {0x5202, 0x5202}, {0x5203, 0x5203}, {0x5204, 0x5204}, + {0x5205, 0x5205}, {0x5206, 0x5206}, {0x5207, 0x5207}, {0x5208, 0x5208}, {0x5209, 0x5209}, {0x520A, 0x520A}, {0x520B, 0x520B}, + {0x520C, 0x520C}, {0x520D, 0x520D}, {0x520E, 0x520E}, {0x520F, 0x520F}, {0x5210, 0x5210}, {0x5211, 0x5211}, {0x5212, 0x5212}, + {0x5213, 0x5213}, {0x5214, 0x5214}, {0x5215, 0x5215}, {0x5216, 0x5216}, {0x5217, 0x5217}, {0x5218, 0x5218}, {0x5219, 0x5219}, + {0x521A, 0x521A}, {0x521B, 0x521B}, {0x521C, 0x521C}, {0x521D, 0x521D}, {0x521E, 0x521E}, {0x521F, 0x521F}, {0x5220, 0x5220}, + {0x5221, 0x5221}, {0x5222, 0x5222}, {0x5223, 0x5223}, {0x5224, 0x5224}, {0x5225, 0x5225}, {0x5226, 0x5226}, {0x5227, 0x5227}, + {0x5228, 0x5228}, {0x5229, 0x5229}, {0x522A, 0x522A}, {0x522B, 0x522B}, {0x522C, 0x522C}, {0x522D, 0x522D}, {0x522E, 0x522E}, + {0x522F, 0x522F}, {0x5230, 0x5230}, {0x5231, 0x5231}, {0x5232, 0x5232}, {0x5233, 0x5233}, {0x5234, 0x5234}, {0x5235, 0x5235}, + {0x5236, 0x5236}, {0x5237, 0x5237}, {0x5238, 0x5238}, {0x5239, 0x5239}, {0x523A, 0x523A}, {0x523B, 0x523B}, {0x523C, 0x523C}, + {0x523D, 0x523D}, {0x523E, 0x523E}, {0x523F, 0x523F}, {0x5240, 0x5240}, {0x5241, 0x5241}, {0x5242, 0x5242}, {0x5243, 0x5243}, + {0x5244, 0x5244}, {0x5245, 0x5245}, {0x5246, 0x5246}, {0x5247, 0x5247}, {0x5248, 0x5248}, {0x5249, 0x5249}, {0x524A, 0x524A}, + {0x524B, 0x524B}, {0x524C, 0x524C}, {0x524D, 0x524D}, {0x524E, 0x524E}, {0x524F, 0x524F}, {0x5250, 0x5250}, {0x5251, 0x5251}, + {0x5252, 0x5252}, {0x5253, 0x5253}, {0x5254, 0x5254}, {0x5255, 0x5255}, {0x5256, 0x5256}, {0x5257, 0x5257}, {0x5258, 0x5258}, + {0x5259, 0x5259}, {0x525A, 0x525A}, {0x525B, 0x525B}, {0x525C, 0x525C}, {0x525D, 0x525D}, {0x525E, 0x525E}, {0x525F, 0x525F}, + {0x5260, 0x5260}, {0x5261, 0x5261}, {0x5262, 0x5262}, {0x5263, 0x5263}, {0x5264, 0x5264}, {0x5265, 0x5265}, {0x5266, 0x5266}, + {0x5267, 0x5267}, {0x5268, 0x5268}, {0x5269, 0x5269}, {0x526A, 0x526A}, {0x526B, 0x526B}, {0x526C, 0x526C}, {0x526D, 0x526D}, + {0x526E, 0x526E}, {0x526F, 0x526F}, {0x5270, 0x5270}, {0x5271, 0x5271}, {0x5272, 0x5272}, {0x5273, 0x5273}, {0x5274, 0x5274}, + {0x5275, 0x5275}, {0x5276, 0x5276}, {0x5277, 0x5277}, {0x5278, 0x5278}, {0x5279, 0x5279}, {0x527A, 0x527A}, {0x527B, 0x527B}, + {0x527C, 0x527C}, {0x527D, 0x527D}, {0x527E, 0x527E}, {0x527F, 0x527F}, {0x5280, 0x5280}, {0x5281, 0x5281}, {0x5282, 0x5282}, + {0x5283, 0x5283}, {0x5284, 0x5284}, {0x5285, 0x5285}, {0x5286, 0x5286}, {0x5287, 0x5287}, {0x5288, 0x5288}, {0x5289, 0x5289}, + {0x528A, 0x528A}, {0x528B, 0x528B}, {0x528C, 0x528C}, {0x528D, 0x528D}, {0x528E, 0x528E}, {0x528F, 0x528F}, {0x5290, 0x5290}, + {0x5291, 0x5291}, {0x5292, 0x5292}, {0x5293, 0x5293}, {0x5294, 0x5294}, {0x5295, 0x5295}, {0x5296, 0x5296}, {0x5297, 0x5297}, + {0x5298, 0x5298}, {0x5299, 0x5299}, {0x529A, 0x529A}, {0x529B, 0x529B}, {0x529C, 0x529C}, {0x529D, 0x529D}, {0x529E, 0x529E}, + {0x529F, 0x529F}, {0x52A0, 0x52A0}, {0x52A1, 0x52A1}, {0x52A2, 0x52A2}, {0x52A3, 0x52A3}, {0x52A4, 0x52A4}, {0x52A5, 0x52A5}, + {0x52A6, 0x52A6}, {0x52A7, 0x52A7}, {0x52A8, 0x52A8}, {0x52A9, 0x52A9}, {0x52AA, 0x52AA}, {0x52AB, 0x52AB}, {0x52AC, 0x52AC}, + {0x52AD, 0x52AD}, {0x52AE, 0x52AE}, {0x52AF, 0x52AF}, {0x52B0, 0x52B0}, {0x52B1, 0x52B1}, {0x52B2, 0x52B2}, {0x52B3, 0x52B3}, + {0x52B4, 0x52B4}, {0x52B5, 0x52B5}, {0x52B6, 0x52B6}, {0x52B7, 0x52B7}, {0x52B8, 0x52B8}, {0x52B9, 0x52B9}, {0x52BA, 0x52BA}, + {0x52BB, 0x52BB}, {0x52BC, 0x52BC}, {0x52BD, 0x52BD}, {0x52BE, 0x52BE}, {0x52BF, 0x52BF}, {0x52C0, 0x52C0}, {0x52C1, 0x52C1}, + {0x52C2, 0x52C2}, {0x52C3, 0x52C3}, {0x52C4, 0x52C4}, {0x52C5, 0x52C5}, {0x52C6, 0x52C6}, {0x52C7, 0x52C7}, {0x52C8, 0x52C8}, + {0x52C9, 0x52C9}, {0x52CA, 0x52CA}, {0x52CB, 0x52CB}, {0x52CC, 0x52CC}, {0x52CD, 0x52CD}, {0x52CE, 0x52CE}, {0x52CF, 0x52CF}, + {0x52D0, 0x52D0}, {0x52D1, 0x52D1}, {0x52D2, 0x52D2}, {0x52D3, 0x52D3}, {0x52D4, 0x52D4}, {0x52D5, 0x52D5}, {0x52D6, 0x52D6}, + {0x52D7, 0x52D7}, {0x52D8, 0x52D8}, {0x52D9, 0x52D9}, {0x52DA, 0x52DA}, {0x52DB, 0x52DB}, {0x52DC, 0x52DC}, {0x52DD, 0x52DD}, + {0x52DE, 0x52DE}, {0x52DF, 0x52DF}, {0x52E0, 0x52E0}, {0x52E1, 0x52E1}, {0x52E2, 0x52E2}, {0x52E3, 0x52E3}, {0x52E4, 0x52E4}, + {0x52E5, 0x52E5}, {0x52E6, 0x52E6}, {0x52E7, 0x52E7}, {0x52E8, 0x52E8}, {0x52E9, 0x52E9}, {0x52EA, 0x52EA}, {0x52EB, 0x52EB}, + {0x52EC, 0x52EC}, {0x52ED, 0x52ED}, {0x52EE, 0x52EE}, {0x52EF, 0x52EF}, {0x52F0, 0x52F0}, {0x52F1, 0x52F1}, {0x52F2, 0x52F2}, + {0x52F3, 0x52F3}, {0x52F4, 0x52F4}, {0x52F5, 0x52F5}, {0x52F6, 0x52F6}, {0x52F7, 0x52F7}, {0x52F8, 0x52F8}, {0x52F9, 0x52F9}, + {0x52FA, 0x52FA}, {0x52FB, 0x52FB}, {0x52FC, 0x52FC}, {0x52FD, 0x52FD}, {0x52FE, 0x52FE}, {0x52FF, 0x52FF}, {0x5300, 0x5300}, + {0x5301, 0x5301}, {0x5302, 0x5302}, {0x5303, 0x5303}, {0x5304, 0x5304}, {0x5305, 0x5305}, {0x5306, 0x5306}, {0x5307, 0x5307}, + {0x5308, 0x5308}, {0x5309, 0x5309}, {0x530A, 0x530A}, {0x530B, 0x530B}, {0x530C, 0x530C}, {0x530D, 0x530D}, {0x530E, 0x530E}, + {0x530F, 0x530F}, {0x5310, 0x5310}, {0x5311, 0x5311}, {0x5312, 0x5312}, {0x5313, 0x5313}, {0x5314, 0x5314}, {0x5315, 0x5315}, + {0x5316, 0x5316}, {0x5317, 0x5317}, {0x5318, 0x5318}, {0x5319, 0x5319}, {0x531A, 0x531A}, {0x531B, 0x531B}, {0x531C, 0x531C}, + {0x531D, 0x531D}, {0x531E, 0x531E}, {0x531F, 0x531F}, {0x5320, 0x5320}, {0x5321, 0x5321}, {0x5322, 0x5322}, {0x5323, 0x5323}, + {0x5324, 0x5324}, {0x5325, 0x5325}, {0x5326, 0x5326}, {0x5327, 0x5327}, {0x5328, 0x5328}, {0x5329, 0x5329}, {0x532A, 0x532A}, + {0x532B, 0x532B}, {0x532C, 0x532C}, {0x532D, 0x532D}, {0x532E, 0x532E}, {0x532F, 0x532F}, {0x5330, 0x5330}, {0x5331, 0x5331}, + {0x5332, 0x5332}, {0x5333, 0x5333}, {0x5334, 0x5334}, {0x5335, 0x5335}, {0x5336, 0x5336}, {0x5337, 0x5337}, {0x5338, 0x5338}, + {0x5339, 0x5339}, {0x533A, 0x533A}, {0x533B, 0x533B}, {0x533C, 0x533C}, {0x533D, 0x533D}, {0x533E, 0x533E}, {0x533F, 0x533F}, + {0x5340, 0x5340}, {0x5341, 0x5341}, {0x5342, 0x5342}, {0x5343, 0x5343}, {0x5344, 0x5344}, {0x5345, 0x5345}, {0x5346, 0x5346}, + {0x5347, 0x5347}, {0x5348, 0x5348}, {0x5349, 0x5349}, {0x534A, 0x534A}, {0x534B, 0x534B}, {0x534C, 0x534C}, {0x534D, 0x534D}, + {0x534E, 0x534E}, {0x534F, 0x534F}, {0x5350, 0x5350}, {0x5351, 0x5351}, {0x5352, 0x5352}, {0x5353, 0x5353}, {0x5354, 0x5354}, + {0x5355, 0x5355}, {0x5356, 0x5356}, {0x5357, 0x5357}, {0x5358, 0x5358}, {0x5359, 0x5359}, {0x535A, 0x535A}, {0x535B, 0x535B}, + {0x535C, 0x535C}, {0x535D, 0x535D}, {0x535E, 0x535E}, {0x535F, 0x535F}, {0x5360, 0x5360}, {0x5361, 0x5361}, {0x5362, 0x5362}, + {0x5363, 0x5363}, {0x5364, 0x5364}, {0x5365, 0x5365}, {0x5366, 0x5366}, {0x5367, 0x5367}, {0x5368, 0x5368}, {0x5369, 0x5369}, + {0x536A, 0x536A}, {0x536B, 0x536B}, {0x536C, 0x536C}, {0x536D, 0x536D}, {0x536E, 0x536E}, {0x536F, 0x536F}, {0x5370, 0x5370}, + {0x5371, 0x5371}, {0x5372, 0x5372}, {0x5373, 0x5373}, {0x5374, 0x5374}, {0x5375, 0x5375}, {0x5376, 0x5376}, {0x5377, 0x5377}, + {0x5378, 0x5378}, {0x5379, 0x5379}, {0x537A, 0x537A}, {0x537B, 0x537B}, {0x537C, 0x537C}, {0x537D, 0x537D}, {0x537E, 0x537E}, + {0x537F, 0x537F}, {0x5380, 0x5380}, {0x5381, 0x5381}, {0x5382, 0x5382}, {0x5383, 0x5383}, {0x5384, 0x5384}, {0x5385, 0x5385}, + {0x5386, 0x5386}, {0x5387, 0x5387}, {0x5388, 0x5388}, {0x5389, 0x5389}, {0x538A, 0x538A}, {0x538B, 0x538B}, {0x538C, 0x538C}, + {0x538D, 0x538D}, {0x538E, 0x538E}, {0x538F, 0x538F}, {0x5390, 0x5390}, {0x5391, 0x5391}, {0x5392, 0x5392}, {0x5393, 0x5393}, + {0x5394, 0x5394}, {0x5395, 0x5395}, {0x5396, 0x5396}, {0x5397, 0x5397}, {0x5398, 0x5398}, {0x5399, 0x5399}, {0x539A, 0x539A}, + {0x539B, 0x539B}, {0x539C, 0x539C}, {0x539D, 0x539D}, {0x539E, 0x539E}, {0x539F, 0x539F}, {0x53A0, 0x53A0}, {0x53A1, 0x53A1}, + {0x53A2, 0x53A2}, {0x53A3, 0x53A3}, {0x53A4, 0x53A4}, {0x53A5, 0x53A5}, {0x53A6, 0x53A6}, {0x53A7, 0x53A7}, {0x53A8, 0x53A8}, + {0x53A9, 0x53A9}, {0x53AA, 0x53AA}, {0x53AB, 0x53AB}, {0x53AC, 0x53AC}, {0x53AD, 0x53AD}, {0x53AE, 0x53AE}, {0x53AF, 0x53AF}, + {0x53B0, 0x53B0}, {0x53B1, 0x53B1}, {0x53B2, 0x53B2}, {0x53B3, 0x53B3}, {0x53B4, 0x53B4}, {0x53B5, 0x53B5}, {0x53B6, 0x53B6}, + {0x53B7, 0x53B7}, {0x53B8, 0x53B8}, {0x53B9, 0x53B9}, {0x53BA, 0x53BA}, {0x53BB, 0x53BB}, {0x53BC, 0x53BC}, {0x53BD, 0x53BD}, + {0x53BE, 0x53BE}, {0x53BF, 0x53BF}, {0x53C0, 0x53C0}, {0x53C1, 0x53C1}, {0x53C2, 0x53C2}, {0x53C3, 0x53C3}, {0x53C4, 0x53C4}, + {0x53C5, 0x53C5}, {0x53C6, 0x53C6}, {0x53C7, 0x53C7}, {0x53C8, 0x53C8}, {0x53C9, 0x53C9}, {0x53CA, 0x53CA}, {0x53CB, 0x53CB}, + {0x53CC, 0x53CC}, {0x53CD, 0x53CD}, {0x53CE, 0x53CE}, {0x53CF, 0x53CF}, {0x53D0, 0x53D0}, {0x53D1, 0x53D1}, {0x53D2, 0x53D2}, + {0x53D3, 0x53D3}, {0x53D4, 0x53D4}, {0x53D5, 0x53D5}, {0x53D6, 0x53D6}, {0x53D7, 0x53D7}, {0x53D8, 0x53D8}, {0x53D9, 0x53D9}, + {0x53DA, 0x53DA}, {0x53DB, 0x53DB}, {0x53DC, 0x53DC}, {0x53DD, 0x53DD}, {0x53DE, 0x53DE}, {0x53DF, 0x53DF}, {0x53E0, 0x53E0}, + {0x53E1, 0x53E1}, {0x53E2, 0x53E2}, {0x53E3, 0x53E3}, {0x53E4, 0x53E4}, {0x53E5, 0x53E5}, {0x53E6, 0x53E6}, {0x53E7, 0x53E7}, + {0x53E8, 0x53E8}, {0x53E9, 0x53E9}, {0x53EA, 0x53EA}, {0x53EB, 0x53EB}, {0x53EC, 0x53EC}, {0x53ED, 0x53ED}, {0x53EE, 0x53EE}, + {0x53EF, 0x53EF}, {0x53F0, 0x53F0}, {0x53F1, 0x53F1}, {0x53F2, 0x53F2}, {0x53F3, 0x53F3}, {0x53F4, 0x53F4}, {0x53F5, 0x53F5}, + {0x53F6, 0x53F6}, {0x53F7, 0x53F7}, {0x53F8, 0x53F8}, {0x53F9, 0x53F9}, {0x53FA, 0x53FA}, {0x53FB, 0x53FB}, {0x53FC, 0x53FC}, + {0x53FD, 0x53FD}, {0x53FE, 0x53FE}, {0x53FF, 0x53FF}, {0x5400, 0x5400}, {0x5401, 0x5401}, {0x5402, 0x5402}, {0x5403, 0x5403}, + {0x5404, 0x5404}, {0x5405, 0x5405}, {0x5406, 0x5406}, {0x5407, 0x5407}, {0x5408, 0x5408}, {0x5409, 0x5409}, {0x540A, 0x540A}, + {0x540B, 0x540B}, {0x540C, 0x540C}, {0x540D, 0x540D}, {0x540E, 0x540E}, {0x540F, 0x540F}, {0x5410, 0x5410}, {0x5411, 0x5411}, + {0x5412, 0x5412}, {0x5413, 0x5413}, {0x5414, 0x5414}, {0x5415, 0x5415}, {0x5416, 0x5416}, {0x5417, 0x5417}, {0x5418, 0x5418}, + {0x5419, 0x5419}, {0x541A, 0x541A}, {0x541B, 0x541B}, {0x541C, 0x541C}, {0x541D, 0x541D}, {0x541E, 0x541E}, {0x541F, 0x541F}, + {0x5420, 0x5420}, {0x5421, 0x5421}, {0x5422, 0x5422}, {0x5423, 0x5423}, {0x5424, 0x5424}, {0x5425, 0x5425}, {0x5426, 0x5426}, + {0x5427, 0x5427}, {0x5428, 0x5428}, {0x5429, 0x5429}, {0x542A, 0x542A}, {0x542B, 0x542B}, {0x542C, 0x542C}, {0x542D, 0x542D}, + {0x542E, 0x542E}, {0x542F, 0x542F}, {0x5430, 0x5430}, {0x5431, 0x5431}, {0x5432, 0x5432}, {0x5433, 0x5433}, {0x5434, 0x5434}, + {0x5435, 0x5435}, {0x5436, 0x5436}, {0x5437, 0x5437}, {0x5438, 0x5438}, {0x5439, 0x5439}, {0x543A, 0x543A}, {0x543B, 0x543B}, + {0x543C, 0x543C}, {0x543D, 0x543D}, {0x543E, 0x543E}, {0x543F, 0x543F}, {0x5440, 0x5440}, {0x5441, 0x5441}, {0x5442, 0x5442}, + {0x5443, 0x5443}, {0x5444, 0x5444}, {0x5445, 0x5445}, {0x5446, 0x5446}, {0x5447, 0x5447}, {0x5448, 0x5448}, {0x5449, 0x5449}, + {0x544A, 0x544A}, {0x544B, 0x544B}, {0x544C, 0x544C}, {0x544D, 0x544D}, {0x544E, 0x544E}, {0x544F, 0x544F}, {0x5450, 0x5450}, + {0x5451, 0x5451}, {0x5452, 0x5452}, {0x5453, 0x5453}, {0x5454, 0x5454}, {0x5455, 0x5455}, {0x5456, 0x5456}, {0x5457, 0x5457}, + {0x5458, 0x5458}, {0x5459, 0x5459}, {0x545A, 0x545A}, {0x545B, 0x545B}, {0x545C, 0x545C}, {0x545D, 0x545D}, {0x545E, 0x545E}, + {0x545F, 0x545F}, {0x5460, 0x5460}, {0x5461, 0x5461}, {0x5462, 0x5462}, {0x5463, 0x5463}, {0x5464, 0x5464}, {0x5465, 0x5465}, + {0x5466, 0x5466}, {0x5467, 0x5467}, {0x5468, 0x5468}, {0x5469, 0x5469}, {0x546A, 0x546A}, {0x546B, 0x546B}, {0x546C, 0x546C}, + {0x546D, 0x546D}, {0x546E, 0x546E}, {0x546F, 0x546F}, {0x5470, 0x5470}, {0x5471, 0x5471}, {0x5472, 0x5472}, {0x5473, 0x5473}, + {0x5474, 0x5474}, {0x5475, 0x5475}, {0x5476, 0x5476}, {0x5477, 0x5477}, {0x5478, 0x5478}, {0x5479, 0x5479}, {0x547A, 0x547A}, + {0x547B, 0x547B}, {0x547C, 0x547C}, {0x547D, 0x547D}, {0x547E, 0x547E}, {0x547F, 0x547F}, {0x5480, 0x5480}, {0x5481, 0x5481}, + {0x5482, 0x5482}, {0x5483, 0x5483}, {0x5484, 0x5484}, {0x5485, 0x5485}, {0x5486, 0x5486}, {0x5487, 0x5487}, {0x5488, 0x5488}, + {0x5489, 0x5489}, {0x548A, 0x548A}, {0x548B, 0x548B}, {0x548C, 0x548C}, {0x548D, 0x548D}, {0x548E, 0x548E}, {0x548F, 0x548F}, + {0x5490, 0x5490}, {0x5491, 0x5491}, {0x5492, 0x5492}, {0x5493, 0x5493}, {0x5494, 0x5494}, {0x5495, 0x5495}, {0x5496, 0x5496}, + {0x5497, 0x5497}, {0x5498, 0x5498}, {0x5499, 0x5499}, {0x549A, 0x549A}, {0x549B, 0x549B}, {0x549C, 0x549C}, {0x549D, 0x549D}, + {0x549E, 0x549E}, {0x549F, 0x549F}, {0x54A0, 0x54A0}, {0x54A1, 0x54A1}, {0x54A2, 0x54A2}, {0x54A3, 0x54A3}, {0x54A4, 0x54A4}, + {0x54A5, 0x54A5}, {0x54A6, 0x54A6}, {0x54A7, 0x54A7}, {0x54A8, 0x54A8}, {0x54A9, 0x54A9}, {0x54AA, 0x54AA}, {0x54AB, 0x54AB}, + {0x54AC, 0x54AC}, {0x54AD, 0x54AD}, {0x54AE, 0x54AE}, {0x54AF, 0x54AF}, {0x54B0, 0x54B0}, {0x54B1, 0x54B1}, {0x54B2, 0x54B2}, + {0x54B3, 0x54B3}, {0x54B4, 0x54B4}, {0x54B5, 0x54B5}, {0x54B6, 0x54B6}, {0x54B7, 0x54B7}, {0x54B8, 0x54B8}, {0x54B9, 0x54B9}, + {0x54BA, 0x54BA}, {0x54BB, 0x54BB}, {0x54BC, 0x54BC}, {0x54BD, 0x54BD}, {0x54BE, 0x54BE}, {0x54BF, 0x54BF}, {0x54C0, 0x54C0}, + {0x54C1, 0x54C1}, {0x54C2, 0x54C2}, {0x54C3, 0x54C3}, {0x54C4, 0x54C4}, {0x54C5, 0x54C5}, {0x54C6, 0x54C6}, {0x54C7, 0x54C7}, + {0x54C8, 0x54C8}, {0x54C9, 0x54C9}, {0x54CA, 0x54CA}, {0x54CB, 0x54CB}, {0x54CC, 0x54CC}, {0x54CD, 0x54CD}, {0x54CE, 0x54CE}, + {0x54CF, 0x54CF}, {0x54D0, 0x54D0}, {0x54D1, 0x54D1}, {0x54D2, 0x54D2}, {0x54D3, 0x54D3}, {0x54D4, 0x54D4}, {0x54D5, 0x54D5}, + {0x54D6, 0x54D6}, {0x54D7, 0x54D7}, {0x54D8, 0x54D8}, {0x54D9, 0x54D9}, {0x54DA, 0x54DA}, {0x54DB, 0x54DB}, {0x54DC, 0x54DC}, + {0x54DD, 0x54DD}, {0x54DE, 0x54DE}, {0x54DF, 0x54DF}, {0x54E0, 0x54E0}, {0x54E1, 0x54E1}, {0x54E2, 0x54E2}, {0x54E3, 0x54E3}, + {0x54E4, 0x54E4}, {0x54E5, 0x54E5}, {0x54E6, 0x54E6}, {0x54E7, 0x54E7}, {0x54E8, 0x54E8}, {0x54E9, 0x54E9}, {0x54EA, 0x54EA}, + {0x54EB, 0x54EB}, {0x54EC, 0x54EC}, {0x54ED, 0x54ED}, {0x54EE, 0x54EE}, {0x54EF, 0x54EF}, {0x54F0, 0x54F0}, {0x54F1, 0x54F1}, + {0x54F2, 0x54F2}, {0x54F3, 0x54F3}, {0x54F4, 0x54F4}, {0x54F5, 0x54F5}, {0x54F6, 0x54F6}, {0x54F7, 0x54F7}, {0x54F8, 0x54F8}, + {0x54F9, 0x54F9}, {0x54FA, 0x54FA}, {0x54FB, 0x54FB}, {0x54FC, 0x54FC}, {0x54FD, 0x54FD}, {0x54FE, 0x54FE}, {0x54FF, 0x54FF}, + {0x5500, 0x5500}, {0x5501, 0x5501}, {0x5502, 0x5502}, {0x5503, 0x5503}, {0x5504, 0x5504}, {0x5505, 0x5505}, {0x5506, 0x5506}, + {0x5507, 0x5507}, {0x5508, 0x5508}, {0x5509, 0x5509}, {0x550A, 0x550A}, {0x550B, 0x550B}, {0x550C, 0x550C}, {0x550D, 0x550D}, + {0x550E, 0x550E}, {0x550F, 0x550F}, {0x5510, 0x5510}, {0x5511, 0x5511}, {0x5512, 0x5512}, {0x5513, 0x5513}, {0x5514, 0x5514}, + {0x5515, 0x5515}, {0x5516, 0x5516}, {0x5517, 0x5517}, {0x5518, 0x5518}, {0x5519, 0x5519}, {0x551A, 0x551A}, {0x551B, 0x551B}, + {0x551C, 0x551C}, {0x551D, 0x551D}, {0x551E, 0x551E}, {0x551F, 0x551F}, {0x5520, 0x5520}, {0x5521, 0x5521}, {0x5522, 0x5522}, + {0x5523, 0x5523}, {0x5524, 0x5524}, {0x5525, 0x5525}, {0x5526, 0x5526}, {0x5527, 0x5527}, {0x5528, 0x5528}, {0x5529, 0x5529}, + {0x552A, 0x552A}, {0x552B, 0x552B}, {0x552C, 0x552C}, {0x552D, 0x552D}, {0x552E, 0x552E}, {0x552F, 0x552F}, {0x5530, 0x5530}, + {0x5531, 0x5531}, {0x5532, 0x5532}, {0x5533, 0x5533}, {0x5534, 0x5534}, {0x5535, 0x5535}, {0x5536, 0x5536}, {0x5537, 0x5537}, + {0x5538, 0x5538}, {0x5539, 0x5539}, {0x553A, 0x553A}, {0x553B, 0x553B}, {0x553C, 0x553C}, {0x553D, 0x553D}, {0x553E, 0x553E}, + {0x553F, 0x553F}, {0x5540, 0x5540}, {0x5541, 0x5541}, {0x5542, 0x5542}, {0x5543, 0x5543}, {0x5544, 0x5544}, {0x5545, 0x5545}, + {0x5546, 0x5546}, {0x5547, 0x5547}, {0x5548, 0x5548}, {0x5549, 0x5549}, {0x554A, 0x554A}, {0x554B, 0x554B}, {0x554C, 0x554C}, + {0x554D, 0x554D}, {0x554E, 0x554E}, {0x554F, 0x554F}, {0x5550, 0x5550}, {0x5551, 0x5551}, {0x5552, 0x5552}, {0x5553, 0x5553}, + {0x5554, 0x5554}, {0x5555, 0x5555}, {0x5556, 0x5556}, {0x5557, 0x5557}, {0x5558, 0x5558}, {0x5559, 0x5559}, {0x555A, 0x555A}, + {0x555B, 0x555B}, {0x555C, 0x555C}, {0x555D, 0x555D}, {0x555E, 0x555E}, {0x555F, 0x555F}, {0x5560, 0x5560}, {0x5561, 0x5561}, + {0x5562, 0x5562}, {0x5563, 0x5563}, {0x5564, 0x5564}, {0x5565, 0x5565}, {0x5566, 0x5566}, {0x5567, 0x5567}, {0x5568, 0x5568}, + {0x5569, 0x5569}, {0x556A, 0x556A}, {0x556B, 0x556B}, {0x556C, 0x556C}, {0x556D, 0x556D}, {0x556E, 0x556E}, {0x556F, 0x556F}, + {0x5570, 0x5570}, {0x5571, 0x5571}, {0x5572, 0x5572}, {0x5573, 0x5573}, {0x5574, 0x5574}, {0x5575, 0x5575}, {0x5576, 0x5576}, + {0x5577, 0x5577}, {0x5578, 0x5578}, {0x5579, 0x5579}, {0x557A, 0x557A}, {0x557B, 0x557B}, {0x557C, 0x557C}, {0x557D, 0x557D}, + {0x557E, 0x557E}, {0x557F, 0x557F}, {0x5580, 0x5580}, {0x5581, 0x5581}, {0x5582, 0x5582}, {0x5583, 0x5583}, {0x5584, 0x5584}, + {0x5585, 0x5585}, {0x5586, 0x5586}, {0x5587, 0x5587}, {0x5588, 0x5588}, {0x5589, 0x5589}, {0x558A, 0x558A}, {0x558B, 0x558B}, + {0x558C, 0x558C}, {0x558D, 0x558D}, {0x558E, 0x558E}, {0x558F, 0x558F}, {0x5590, 0x5590}, {0x5591, 0x5591}, {0x5592, 0x5592}, + {0x5593, 0x5593}, {0x5594, 0x5594}, {0x5595, 0x5595}, {0x5596, 0x5596}, {0x5597, 0x5597}, {0x5598, 0x5598}, {0x5599, 0x5599}, + {0x559A, 0x559A}, {0x559B, 0x559B}, {0x559C, 0x559C}, {0x559D, 0x559D}, {0x559E, 0x559E}, {0x559F, 0x559F}, {0x55A0, 0x55A0}, + {0x55A1, 0x55A1}, {0x55A2, 0x55A2}, {0x55A3, 0x55A3}, {0x55A4, 0x55A4}, {0x55A5, 0x55A5}, {0x55A6, 0x55A6}, {0x55A7, 0x55A7}, + {0x55A8, 0x55A8}, {0x55A9, 0x55A9}, {0x55AA, 0x55AA}, {0x55AB, 0x55AB}, {0x55AC, 0x55AC}, {0x55AD, 0x55AD}, {0x55AE, 0x55AE}, + {0x55AF, 0x55AF}, {0x55B0, 0x55B0}, {0x55B1, 0x55B1}, {0x55B2, 0x55B2}, {0x55B3, 0x55B3}, {0x55B4, 0x55B4}, {0x55B5, 0x55B5}, + {0x55B6, 0x55B6}, {0x55B7, 0x55B7}, {0x55B8, 0x55B8}, {0x55B9, 0x55B9}, {0x55BA, 0x55BA}, {0x55BB, 0x55BB}, {0x55BC, 0x55BC}, + {0x55BD, 0x55BD}, {0x55BE, 0x55BE}, {0x55BF, 0x55BF}, {0x55C0, 0x55C0}, {0x55C1, 0x55C1}, {0x55C2, 0x55C2}, {0x55C3, 0x55C3}, + {0x55C4, 0x55C4}, {0x55C5, 0x55C5}, {0x55C6, 0x55C6}, {0x55C7, 0x55C7}, {0x55C8, 0x55C8}, {0x55C9, 0x55C9}, {0x55CA, 0x55CA}, + {0x55CB, 0x55CB}, {0x55CC, 0x55CC}, {0x55CD, 0x55CD}, {0x55CE, 0x55CE}, {0x55CF, 0x55CF}, {0x55D0, 0x55D0}, {0x55D1, 0x55D1}, + {0x55D2, 0x55D2}, {0x55D3, 0x55D3}, {0x55D4, 0x55D4}, {0x55D5, 0x55D5}, {0x55D6, 0x55D6}, {0x55D7, 0x55D7}, {0x55D8, 0x55D8}, + {0x55D9, 0x55D9}, {0x55DA, 0x55DA}, {0x55DB, 0x55DB}, {0x55DC, 0x55DC}, {0x55DD, 0x55DD}, {0x55DE, 0x55DE}, {0x55DF, 0x55DF}, + {0x55E0, 0x55E0}, {0x55E1, 0x55E1}, {0x55E2, 0x55E2}, {0x55E3, 0x55E3}, {0x55E4, 0x55E4}, {0x55E5, 0x55E5}, {0x55E6, 0x55E6}, + {0x55E7, 0x55E7}, {0x55E8, 0x55E8}, {0x55E9, 0x55E9}, {0x55EA, 0x55EA}, {0x55EB, 0x55EB}, {0x55EC, 0x55EC}, {0x55ED, 0x55ED}, + {0x55EE, 0x55EE}, {0x55EF, 0x55EF}, {0x55F0, 0x55F0}, {0x55F1, 0x55F1}, {0x55F2, 0x55F2}, {0x55F3, 0x55F3}, {0x55F4, 0x55F4}, + {0x55F5, 0x55F5}, {0x55F6, 0x55F6}, {0x55F7, 0x55F7}, {0x55F8, 0x55F8}, {0x55F9, 0x55F9}, {0x55FA, 0x55FA}, {0x55FB, 0x55FB}, + {0x55FC, 0x55FC}, {0x55FD, 0x55FD}, {0x55FE, 0x55FE}, {0x55FF, 0x55FF}, {0x5600, 0x5600}, {0x5601, 0x5601}, {0x5602, 0x5602}, + {0x5603, 0x5603}, {0x5604, 0x5604}, {0x5605, 0x5605}, {0x5606, 0x5606}, {0x5607, 0x5607}, {0x5608, 0x5608}, {0x5609, 0x5609}, + {0x560A, 0x560A}, {0x560B, 0x560B}, {0x560C, 0x560C}, {0x560D, 0x560D}, {0x560E, 0x560E}, {0x560F, 0x560F}, {0x5610, 0x5610}, + {0x5611, 0x5611}, {0x5612, 0x5612}, {0x5613, 0x5613}, {0x5614, 0x5614}, {0x5615, 0x5615}, {0x5616, 0x5616}, {0x5617, 0x5617}, + {0x5618, 0x5618}, {0x5619, 0x5619}, {0x561A, 0x561A}, {0x561B, 0x561B}, {0x561C, 0x561C}, {0x561D, 0x561D}, {0x561E, 0x561E}, + {0x561F, 0x561F}, {0x5620, 0x5620}, {0x5621, 0x5621}, {0x5622, 0x5622}, {0x5623, 0x5623}, {0x5624, 0x5624}, {0x5625, 0x5625}, + {0x5626, 0x5626}, {0x5627, 0x5627}, {0x5628, 0x5628}, {0x5629, 0x5629}, {0x562A, 0x562A}, {0x562B, 0x562B}, {0x562C, 0x562C}, + {0x562D, 0x562D}, {0x562E, 0x562E}, {0x562F, 0x562F}, {0x5630, 0x5630}, {0x5631, 0x5631}, {0x5632, 0x5632}, {0x5633, 0x5633}, + {0x5634, 0x5634}, {0x5635, 0x5635}, {0x5636, 0x5636}, {0x5637, 0x5637}, {0x5638, 0x5638}, {0x5639, 0x5639}, {0x563A, 0x563A}, + {0x563B, 0x563B}, {0x563C, 0x563C}, {0x563D, 0x563D}, {0x563E, 0x563E}, {0x563F, 0x563F}, {0x5640, 0x5640}, {0x5641, 0x5641}, + {0x5642, 0x5642}, {0x5643, 0x5643}, {0x5644, 0x5644}, {0x5645, 0x5645}, {0x5646, 0x5646}, {0x5647, 0x5647}, {0x5648, 0x5648}, + {0x5649, 0x5649}, {0x564A, 0x564A}, {0x564B, 0x564B}, {0x564C, 0x564C}, {0x564D, 0x564D}, {0x564E, 0x564E}, {0x564F, 0x564F}, + {0x5650, 0x5650}, {0x5651, 0x5651}, {0x5652, 0x5652}, {0x5653, 0x5653}, {0x5654, 0x5654}, {0x5655, 0x5655}, {0x5656, 0x5656}, + {0x5657, 0x5657}, {0x5658, 0x5658}, {0x5659, 0x5659}, {0x565A, 0x565A}, {0x565B, 0x565B}, {0x565C, 0x565C}, {0x565D, 0x565D}, + {0x565E, 0x565E}, {0x565F, 0x565F}, {0x5660, 0x5660}, {0x5661, 0x5661}, {0x5662, 0x5662}, {0x5663, 0x5663}, {0x5664, 0x5664}, + {0x5665, 0x5665}, {0x5666, 0x5666}, {0x5667, 0x5667}, {0x5668, 0x5668}, {0x5669, 0x5669}, {0x566A, 0x566A}, {0x566B, 0x566B}, + {0x566C, 0x566C}, {0x566D, 0x566D}, {0x566E, 0x566E}, {0x566F, 0x566F}, {0x5670, 0x5670}, {0x5671, 0x5671}, {0x5672, 0x5672}, + {0x5673, 0x5673}, {0x5674, 0x5674}, {0x5675, 0x5675}, {0x5676, 0x5676}, {0x5677, 0x5677}, {0x5678, 0x5678}, {0x5679, 0x5679}, + {0x567A, 0x567A}, {0x567B, 0x567B}, {0x567C, 0x567C}, {0x567D, 0x567D}, {0x567E, 0x567E}, {0x567F, 0x567F}, {0x5680, 0x5680}, + {0x5681, 0x5681}, {0x5682, 0x5682}, {0x5683, 0x5683}, {0x5684, 0x5684}, {0x5685, 0x5685}, {0x5686, 0x5686}, {0x5687, 0x5687}, + {0x5688, 0x5688}, {0x5689, 0x5689}, {0x568A, 0x568A}, {0x568B, 0x568B}, {0x568C, 0x568C}, {0x568D, 0x568D}, {0x568E, 0x568E}, + {0x568F, 0x568F}, {0x5690, 0x5690}, {0x5691, 0x5691}, {0x5692, 0x5692}, {0x5693, 0x5693}, {0x5694, 0x5694}, {0x5695, 0x5695}, + {0x5696, 0x5696}, {0x5697, 0x5697}, {0x5698, 0x5698}, {0x5699, 0x5699}, {0x569A, 0x569A}, {0x569B, 0x569B}, {0x569C, 0x569C}, + {0x569D, 0x569D}, {0x569E, 0x569E}, {0x569F, 0x569F}, {0x56A0, 0x56A0}, {0x56A1, 0x56A1}, {0x56A2, 0x56A2}, {0x56A3, 0x56A3}, + {0x56A4, 0x56A4}, {0x56A5, 0x56A5}, {0x56A6, 0x56A6}, {0x56A7, 0x56A7}, {0x56A8, 0x56A8}, {0x56A9, 0x56A9}, {0x56AA, 0x56AA}, + {0x56AB, 0x56AB}, {0x56AC, 0x56AC}, {0x56AD, 0x56AD}, {0x56AE, 0x56AE}, {0x56AF, 0x56AF}, {0x56B0, 0x56B0}, {0x56B1, 0x56B1}, + {0x56B2, 0x56B2}, {0x56B3, 0x56B3}, {0x56B4, 0x56B4}, {0x56B5, 0x56B5}, {0x56B6, 0x56B6}, {0x56B7, 0x56B7}, {0x56B8, 0x56B8}, + {0x56B9, 0x56B9}, {0x56BA, 0x56BA}, {0x56BB, 0x56BB}, {0x56BC, 0x56BC}, {0x56BD, 0x56BD}, {0x56BE, 0x56BE}, {0x56BF, 0x56BF}, + {0x56C0, 0x56C0}, {0x56C1, 0x56C1}, {0x56C2, 0x56C2}, {0x56C3, 0x56C3}, {0x56C4, 0x56C4}, {0x56C5, 0x56C5}, {0x56C6, 0x56C6}, + {0x56C7, 0x56C7}, {0x56C8, 0x56C8}, {0x56C9, 0x56C9}, {0x56CA, 0x56CA}, {0x56CB, 0x56CB}, {0x56CC, 0x56CC}, {0x56CD, 0x56CD}, + {0x56CE, 0x56CE}, {0x56CF, 0x56CF}, {0x56D0, 0x56D0}, {0x56D1, 0x56D1}, {0x56D2, 0x56D2}, {0x56D3, 0x56D3}, {0x56D4, 0x56D4}, + {0x56D5, 0x56D5}, {0x56D6, 0x56D6}, {0x56D7, 0x56D7}, {0x56D8, 0x56D8}, {0x56D9, 0x56D9}, {0x56DA, 0x56DA}, {0x56DB, 0x56DB}, + {0x56DC, 0x56DC}, {0x56DD, 0x56DD}, {0x56DE, 0x56DE}, {0x56DF, 0x56DF}, {0x56E0, 0x56E0}, {0x56E1, 0x56E1}, {0x56E2, 0x56E2}, + {0x56E3, 0x56E3}, {0x56E4, 0x56E4}, {0x56E5, 0x56E5}, {0x56E6, 0x56E6}, {0x56E7, 0x56E7}, {0x56E8, 0x56E8}, {0x56E9, 0x56E9}, + {0x56EA, 0x56EA}, {0x56EB, 0x56EB}, {0x56EC, 0x56EC}, {0x56ED, 0x56ED}, {0x56EE, 0x56EE}, {0x56EF, 0x56EF}, {0x56F0, 0x56F0}, + {0x56F1, 0x56F1}, {0x56F2, 0x56F2}, {0x56F3, 0x56F3}, {0x56F4, 0x56F4}, {0x56F5, 0x56F5}, {0x56F6, 0x56F6}, {0x56F7, 0x56F7}, + {0x56F8, 0x56F8}, {0x56F9, 0x56F9}, {0x56FA, 0x56FA}, {0x56FB, 0x56FB}, {0x56FC, 0x56FC}, {0x56FD, 0x56FD}, {0x56FE, 0x56FE}, + {0x56FF, 0x56FF}, {0x5700, 0x5700}, {0x5701, 0x5701}, {0x5702, 0x5702}, {0x5703, 0x5703}, {0x5704, 0x5704}, {0x5705, 0x5705}, + {0x5706, 0x5706}, {0x5707, 0x5707}, {0x5708, 0x5708}, {0x5709, 0x5709}, {0x570A, 0x570A}, {0x570B, 0x570B}, {0x570C, 0x570C}, + {0x570D, 0x570D}, {0x570E, 0x570E}, {0x570F, 0x570F}, {0x5710, 0x5710}, {0x5711, 0x5711}, {0x5712, 0x5712}, {0x5713, 0x5713}, + {0x5714, 0x5714}, {0x5715, 0x5715}, {0x5716, 0x5716}, {0x5717, 0x5717}, {0x5718, 0x5718}, {0x5719, 0x5719}, {0x571A, 0x571A}, + {0x571B, 0x571B}, {0x571C, 0x571C}, {0x571D, 0x571D}, {0x571E, 0x571E}, {0x571F, 0x571F}, {0x5720, 0x5720}, {0x5721, 0x5721}, + {0x5722, 0x5722}, {0x5723, 0x5723}, {0x5724, 0x5724}, {0x5725, 0x5725}, {0x5726, 0x5726}, {0x5727, 0x5727}, {0x5728, 0x5728}, + {0x5729, 0x5729}, {0x572A, 0x572A}, {0x572B, 0x572B}, {0x572C, 0x572C}, {0x572D, 0x572D}, {0x572E, 0x572E}, {0x572F, 0x572F}, + {0x5730, 0x5730}, {0x5731, 0x5731}, {0x5732, 0x5732}, {0x5733, 0x5733}, {0x5734, 0x5734}, {0x5735, 0x5735}, {0x5736, 0x5736}, + {0x5737, 0x5737}, {0x5738, 0x5738}, {0x5739, 0x5739}, {0x573A, 0x573A}, {0x573B, 0x573B}, {0x573C, 0x573C}, {0x573D, 0x573D}, + {0x573E, 0x573E}, {0x573F, 0x573F}, {0x5740, 0x5740}, {0x5741, 0x5741}, {0x5742, 0x5742}, {0x5743, 0x5743}, {0x5744, 0x5744}, + {0x5745, 0x5745}, {0x5746, 0x5746}, {0x5747, 0x5747}, {0x5748, 0x5748}, {0x5749, 0x5749}, {0x574A, 0x574A}, {0x574B, 0x574B}, + {0x574C, 0x574C}, {0x574D, 0x574D}, {0x574E, 0x574E}, {0x574F, 0x574F}, {0x5750, 0x5750}, {0x5751, 0x5751}, {0x5752, 0x5752}, + {0x5753, 0x5753}, {0x5754, 0x5754}, {0x5755, 0x5755}, {0x5756, 0x5756}, {0x5757, 0x5757}, {0x5758, 0x5758}, {0x5759, 0x5759}, + {0x575A, 0x575A}, {0x575B, 0x575B}, {0x575C, 0x575C}, {0x575D, 0x575D}, {0x575E, 0x575E}, {0x575F, 0x575F}, {0x5760, 0x5760}, + {0x5761, 0x5761}, {0x5762, 0x5762}, {0x5763, 0x5763}, {0x5764, 0x5764}, {0x5765, 0x5765}, {0x5766, 0x5766}, {0x5767, 0x5767}, + {0x5768, 0x5768}, {0x5769, 0x5769}, {0x576A, 0x576A}, {0x576B, 0x576B}, {0x576C, 0x576C}, {0x576D, 0x576D}, {0x576E, 0x576E}, + {0x576F, 0x576F}, {0x5770, 0x5770}, {0x5771, 0x5771}, {0x5772, 0x5772}, {0x5773, 0x5773}, {0x5774, 0x5774}, {0x5775, 0x5775}, + {0x5776, 0x5776}, {0x5777, 0x5777}, {0x5778, 0x5778}, {0x5779, 0x5779}, {0x577A, 0x577A}, {0x577B, 0x577B}, {0x577C, 0x577C}, + {0x577D, 0x577D}, {0x577E, 0x577E}, {0x577F, 0x577F}, {0x5780, 0x5780}, {0x5781, 0x5781}, {0x5782, 0x5782}, {0x5783, 0x5783}, + {0x5784, 0x5784}, {0x5785, 0x5785}, {0x5786, 0x5786}, {0x5787, 0x5787}, {0x5788, 0x5788}, {0x5789, 0x5789}, {0x578A, 0x578A}, + {0x578B, 0x578B}, {0x578C, 0x578C}, {0x578D, 0x578D}, {0x578E, 0x578E}, {0x578F, 0x578F}, {0x5790, 0x5790}, {0x5791, 0x5791}, + {0x5792, 0x5792}, {0x5793, 0x5793}, {0x5794, 0x5794}, {0x5795, 0x5795}, {0x5796, 0x5796}, {0x5797, 0x5797}, {0x5798, 0x5798}, + {0x5799, 0x5799}, {0x579A, 0x579A}, {0x579B, 0x579B}, {0x579C, 0x579C}, {0x579D, 0x579D}, {0x579E, 0x579E}, {0x579F, 0x579F}, + {0x57A0, 0x57A0}, {0x57A1, 0x57A1}, {0x57A2, 0x57A2}, {0x57A3, 0x57A3}, {0x57A4, 0x57A4}, {0x57A5, 0x57A5}, {0x57A6, 0x57A6}, + {0x57A7, 0x57A7}, {0x57A8, 0x57A8}, {0x57A9, 0x57A9}, {0x57AA, 0x57AA}, {0x57AB, 0x57AB}, {0x57AC, 0x57AC}, {0x57AD, 0x57AD}, + {0x57AE, 0x57AE}, {0x57AF, 0x57AF}, {0x57B0, 0x57B0}, {0x57B1, 0x57B1}, {0x57B2, 0x57B2}, {0x57B3, 0x57B3}, {0x57B4, 0x57B4}, + {0x57B5, 0x57B5}, {0x57B6, 0x57B6}, {0x57B7, 0x57B7}, {0x57B8, 0x57B8}, {0x57B9, 0x57B9}, {0x57BA, 0x57BA}, {0x57BB, 0x57BB}, + {0x57BC, 0x57BC}, {0x57BD, 0x57BD}, {0x57BE, 0x57BE}, {0x57BF, 0x57BF}, {0x57C0, 0x57C0}, {0x57C1, 0x57C1}, {0x57C2, 0x57C2}, + {0x57C3, 0x57C3}, {0x57C4, 0x57C4}, {0x57C5, 0x57C5}, {0x57C6, 0x57C6}, {0x57C7, 0x57C7}, {0x57C8, 0x57C8}, {0x57C9, 0x57C9}, + {0x57CA, 0x57CA}, {0x57CB, 0x57CB}, {0x57CC, 0x57CC}, {0x57CD, 0x57CD}, {0x57CE, 0x57CE}, {0x57CF, 0x57CF}, {0x57D0, 0x57D0}, + {0x57D1, 0x57D1}, {0x57D2, 0x57D2}, {0x57D3, 0x57D3}, {0x57D4, 0x57D4}, {0x57D5, 0x57D5}, {0x57D6, 0x57D6}, {0x57D7, 0x57D7}, + {0x57D8, 0x57D8}, {0x57D9, 0x57D9}, {0x57DA, 0x57DA}, {0x57DB, 0x57DB}, {0x57DC, 0x57DC}, {0x57DD, 0x57DD}, {0x57DE, 0x57DE}, + {0x57DF, 0x57DF}, {0x57E0, 0x57E0}, {0x57E1, 0x57E1}, {0x57E2, 0x57E2}, {0x57E3, 0x57E3}, {0x57E4, 0x57E4}, {0x57E5, 0x57E5}, + {0x57E6, 0x57E6}, {0x57E7, 0x57E7}, {0x57E8, 0x57E8}, {0x57E9, 0x57E9}, {0x57EA, 0x57EA}, {0x57EB, 0x57EB}, {0x57EC, 0x57EC}, + {0x57ED, 0x57ED}, {0x57EE, 0x57EE}, {0x57EF, 0x57EF}, {0x57F0, 0x57F0}, {0x57F1, 0x57F1}, {0x57F2, 0x57F2}, {0x57F3, 0x57F3}, + {0x57F4, 0x57F4}, {0x57F5, 0x57F5}, {0x57F6, 0x57F6}, {0x57F7, 0x57F7}, {0x57F8, 0x57F8}, {0x57F9, 0x57F9}, {0x57FA, 0x57FA}, + {0x57FB, 0x57FB}, {0x57FC, 0x57FC}, {0x57FD, 0x57FD}, {0x57FE, 0x57FE}, {0x57FF, 0x57FF}, {0x5800, 0x5800}, {0x5801, 0x5801}, + {0x5802, 0x5802}, {0x5803, 0x5803}, {0x5804, 0x5804}, {0x5805, 0x5805}, {0x5806, 0x5806}, {0x5807, 0x5807}, {0x5808, 0x5808}, + {0x5809, 0x5809}, {0x580A, 0x580A}, {0x580B, 0x580B}, {0x580C, 0x580C}, {0x580D, 0x580D}, {0x580E, 0x580E}, {0x580F, 0x580F}, + {0x5810, 0x5810}, {0x5811, 0x5811}, {0x5812, 0x5812}, {0x5813, 0x5813}, {0x5814, 0x5814}, {0x5815, 0x5815}, {0x5816, 0x5816}, + {0x5817, 0x5817}, {0x5818, 0x5818}, {0x5819, 0x5819}, {0x581A, 0x581A}, {0x581B, 0x581B}, {0x581C, 0x581C}, {0x581D, 0x581D}, + {0x581E, 0x581E}, {0x581F, 0x581F}, {0x5820, 0x5820}, {0x5821, 0x5821}, {0x5822, 0x5822}, {0x5823, 0x5823}, {0x5824, 0x5824}, + {0x5825, 0x5825}, {0x5826, 0x5826}, {0x5827, 0x5827}, {0x5828, 0x5828}, {0x5829, 0x5829}, {0x582A, 0x582A}, {0x582B, 0x582B}, + {0x582C, 0x582C}, {0x582D, 0x582D}, {0x582E, 0x582E}, {0x582F, 0x582F}, {0x5830, 0x5830}, {0x5831, 0x5831}, {0x5832, 0x5832}, + {0x5833, 0x5833}, {0x5834, 0x5834}, {0x5835, 0x5835}, {0x5836, 0x5836}, {0x5837, 0x5837}, {0x5838, 0x5838}, {0x5839, 0x5839}, + {0x583A, 0x583A}, {0x583B, 0x583B}, {0x583C, 0x583C}, {0x583D, 0x583D}, {0x583E, 0x583E}, {0x583F, 0x583F}, {0x5840, 0x5840}, + {0x5841, 0x5841}, {0x5842, 0x5842}, {0x5843, 0x5843}, {0x5844, 0x5844}, {0x5845, 0x5845}, {0x5846, 0x5846}, {0x5847, 0x5847}, + {0x5848, 0x5848}, {0x5849, 0x5849}, {0x584A, 0x584A}, {0x584B, 0x584B}, {0x584C, 0x584C}, {0x584D, 0x584D}, {0x584E, 0x584E}, + {0x584F, 0x584F}, {0x5850, 0x5850}, {0x5851, 0x5851}, {0x5852, 0x5852}, {0x5853, 0x5853}, {0x5854, 0x5854}, {0x5855, 0x5855}, + {0x5856, 0x5856}, {0x5857, 0x5857}, {0x5858, 0x5858}, {0x5859, 0x5859}, {0x585A, 0x585A}, {0x585B, 0x585B}, {0x585C, 0x585C}, + {0x585D, 0x585D}, {0x585E, 0x585E}, {0x585F, 0x585F}, {0x5860, 0x5860}, {0x5861, 0x5861}, {0x5862, 0x5862}, {0x5863, 0x5863}, + {0x5864, 0x5864}, {0x5865, 0x5865}, {0x5866, 0x5866}, {0x5867, 0x5867}, {0x5868, 0x5868}, {0x5869, 0x5869}, {0x586A, 0x586A}, + {0x586B, 0x586B}, {0x586C, 0x586C}, {0x586D, 0x586D}, {0x586E, 0x586E}, {0x586F, 0x586F}, {0x5870, 0x5870}, {0x5871, 0x5871}, + {0x5872, 0x5872}, {0x5873, 0x5873}, {0x5874, 0x5874}, {0x5875, 0x5875}, {0x5876, 0x5876}, {0x5877, 0x5877}, {0x5878, 0x5878}, + {0x5879, 0x5879}, {0x587A, 0x587A}, {0x587B, 0x587B}, {0x587C, 0x587C}, {0x587D, 0x587D}, {0x587E, 0x587E}, {0x587F, 0x587F}, + {0x5880, 0x5880}, {0x5881, 0x5881}, {0x5882, 0x5882}, {0x5883, 0x5883}, {0x5884, 0x5884}, {0x5885, 0x5885}, {0x5886, 0x5886}, + {0x5887, 0x5887}, {0x5888, 0x5888}, {0x5889, 0x5889}, {0x588A, 0x588A}, {0x588B, 0x588B}, {0x588C, 0x588C}, {0x588D, 0x588D}, + {0x588E, 0x588E}, {0x588F, 0x588F}, {0x5890, 0x5890}, {0x5891, 0x5891}, {0x5892, 0x5892}, {0x5893, 0x5893}, {0x5894, 0x5894}, + {0x5895, 0x5895}, {0x5896, 0x5896}, {0x5897, 0x5897}, {0x5898, 0x5898}, {0x5899, 0x5899}, {0x589A, 0x589A}, {0x589B, 0x589B}, + {0x589C, 0x589C}, {0x589D, 0x589D}, {0x589E, 0x589E}, {0x589F, 0x589F}, {0x58A0, 0x58A0}, {0x58A1, 0x58A1}, {0x58A2, 0x58A2}, + {0x58A3, 0x58A3}, {0x58A4, 0x58A4}, {0x58A5, 0x58A5}, {0x58A6, 0x58A6}, {0x58A7, 0x58A7}, {0x58A8, 0x58A8}, {0x58A9, 0x58A9}, + {0x58AA, 0x58AA}, {0x58AB, 0x58AB}, {0x58AC, 0x58AC}, {0x58AD, 0x58AD}, {0x58AE, 0x58AE}, {0x58AF, 0x58AF}, {0x58B0, 0x58B0}, + {0x58B1, 0x58B1}, {0x58B2, 0x58B2}, {0x58B3, 0x58B3}, {0x58B4, 0x58B4}, {0x58B5, 0x58B5}, {0x58B6, 0x58B6}, {0x58B7, 0x58B7}, + {0x58B8, 0x58B8}, {0x58B9, 0x58B9}, {0x58BA, 0x58BA}, {0x58BB, 0x58BB}, {0x58BC, 0x58BC}, {0x58BD, 0x58BD}, {0x58BE, 0x58BE}, + {0x58BF, 0x58BF}, {0x58C0, 0x58C0}, {0x58C1, 0x58C1}, {0x58C2, 0x58C2}, {0x58C3, 0x58C3}, {0x58C4, 0x58C4}, {0x58C5, 0x58C5}, + {0x58C6, 0x58C6}, {0x58C7, 0x58C7}, {0x58C8, 0x58C8}, {0x58C9, 0x58C9}, {0x58CA, 0x58CA}, {0x58CB, 0x58CB}, {0x58CC, 0x58CC}, + {0x58CD, 0x58CD}, {0x58CE, 0x58CE}, {0x58CF, 0x58CF}, {0x58D0, 0x58D0}, {0x58D1, 0x58D1}, {0x58D2, 0x58D2}, {0x58D3, 0x58D3}, + {0x58D4, 0x58D4}, {0x58D5, 0x58D5}, {0x58D6, 0x58D6}, {0x58D7, 0x58D7}, {0x58D8, 0x58D8}, {0x58D9, 0x58D9}, {0x58DA, 0x58DA}, + {0x58DB, 0x58DB}, {0x58DC, 0x58DC}, {0x58DD, 0x58DD}, {0x58DE, 0x58DE}, {0x58DF, 0x58DF}, {0x58E0, 0x58E0}, {0x58E1, 0x58E1}, + {0x58E2, 0x58E2}, {0x58E3, 0x58E3}, {0x58E4, 0x58E4}, {0x58E5, 0x58E5}, {0x58E6, 0x58E6}, {0x58E7, 0x58E7}, {0x58E8, 0x58E8}, + {0x58E9, 0x58E9}, {0x58EA, 0x58EA}, {0x58EB, 0x58EB}, {0x58EC, 0x58EC}, {0x58ED, 0x58ED}, {0x58EE, 0x58EE}, {0x58EF, 0x58EF}, + {0x58F0, 0x58F0}, {0x58F1, 0x58F1}, {0x58F2, 0x58F2}, {0x58F3, 0x58F3}, {0x58F4, 0x58F4}, {0x58F5, 0x58F5}, {0x58F6, 0x58F6}, + {0x58F7, 0x58F7}, {0x58F8, 0x58F8}, {0x58F9, 0x58F9}, {0x58FA, 0x58FA}, {0x58FB, 0x58FB}, {0x58FC, 0x58FC}, {0x58FD, 0x58FD}, + {0x58FE, 0x58FE}, {0x58FF, 0x58FF}, {0x5900, 0x5900}, {0x5901, 0x5901}, {0x5902, 0x5902}, {0x5903, 0x5903}, {0x5904, 0x5904}, + {0x5905, 0x5905}, {0x5906, 0x5906}, {0x5907, 0x5907}, {0x5908, 0x5908}, {0x5909, 0x5909}, {0x590A, 0x590A}, {0x590B, 0x590B}, + {0x590C, 0x590C}, {0x590D, 0x590D}, {0x590E, 0x590E}, {0x590F, 0x590F}, {0x5910, 0x5910}, {0x5911, 0x5911}, {0x5912, 0x5912}, + {0x5913, 0x5913}, {0x5914, 0x5914}, {0x5915, 0x5915}, {0x5916, 0x5916}, {0x5917, 0x5917}, {0x5918, 0x5918}, {0x5919, 0x5919}, + {0x591A, 0x591A}, {0x591B, 0x591B}, {0x591C, 0x591C}, {0x591D, 0x591D}, {0x591E, 0x591E}, {0x591F, 0x591F}, {0x5920, 0x5920}, + {0x5921, 0x5921}, {0x5922, 0x5922}, {0x5923, 0x5923}, {0x5924, 0x5924}, {0x5925, 0x5925}, {0x5926, 0x5926}, {0x5927, 0x5927}, + {0x5928, 0x5928}, {0x5929, 0x5929}, {0x592A, 0x592A}, {0x592B, 0x592B}, {0x592C, 0x592C}, {0x592D, 0x592D}, {0x592E, 0x592E}, + {0x592F, 0x592F}, {0x5930, 0x5930}, {0x5931, 0x5931}, {0x5932, 0x5932}, {0x5933, 0x5933}, {0x5934, 0x5934}, {0x5935, 0x5935}, + {0x5936, 0x5936}, {0x5937, 0x5937}, {0x5938, 0x5938}, {0x5939, 0x5939}, {0x593A, 0x593A}, {0x593B, 0x593B}, {0x593C, 0x593C}, + {0x593D, 0x593D}, {0x593E, 0x593E}, {0x593F, 0x593F}, {0x5940, 0x5940}, {0x5941, 0x5941}, {0x5942, 0x5942}, {0x5943, 0x5943}, + {0x5944, 0x5944}, {0x5945, 0x5945}, {0x5946, 0x5946}, {0x5947, 0x5947}, {0x5948, 0x5948}, {0x5949, 0x5949}, {0x594A, 0x594A}, + {0x594B, 0x594B}, {0x594C, 0x594C}, {0x594D, 0x594D}, {0x594E, 0x594E}, {0x594F, 0x594F}, {0x5950, 0x5950}, {0x5951, 0x5951}, + {0x5952, 0x5952}, {0x5953, 0x5953}, {0x5954, 0x5954}, {0x5955, 0x5955}, {0x5956, 0x5956}, {0x5957, 0x5957}, {0x5958, 0x5958}, + {0x5959, 0x5959}, {0x595A, 0x595A}, {0x595B, 0x595B}, {0x595C, 0x595C}, {0x595D, 0x595D}, {0x595E, 0x595E}, {0x595F, 0x595F}, + {0x5960, 0x5960}, {0x5961, 0x5961}, {0x5962, 0x5962}, {0x5963, 0x5963}, {0x5964, 0x5964}, {0x5965, 0x5965}, {0x5966, 0x5966}, + {0x5967, 0x5967}, {0x5968, 0x5968}, {0x5969, 0x5969}, {0x596A, 0x596A}, {0x596B, 0x596B}, {0x596C, 0x596C}, {0x596D, 0x596D}, + {0x596E, 0x596E}, {0x596F, 0x596F}, {0x5970, 0x5970}, {0x5971, 0x5971}, {0x5972, 0x5972}, {0x5973, 0x5973}, {0x5974, 0x5974}, + {0x5975, 0x5975}, {0x5976, 0x5976}, {0x5977, 0x5977}, {0x5978, 0x5978}, {0x5979, 0x5979}, {0x597A, 0x597A}, {0x597B, 0x597B}, + {0x597C, 0x597C}, {0x597D, 0x597D}, {0x597E, 0x597E}, {0x597F, 0x597F}, {0x5980, 0x5980}, {0x5981, 0x5981}, {0x5982, 0x5982}, + {0x5983, 0x5983}, {0x5984, 0x5984}, {0x5985, 0x5985}, {0x5986, 0x5986}, {0x5987, 0x5987}, {0x5988, 0x5988}, {0x5989, 0x5989}, + {0x598A, 0x598A}, {0x598B, 0x598B}, {0x598C, 0x598C}, {0x598D, 0x598D}, {0x598E, 0x598E}, {0x598F, 0x598F}, {0x5990, 0x5990}, + {0x5991, 0x5991}, {0x5992, 0x5992}, {0x5993, 0x5993}, {0x5994, 0x5994}, {0x5995, 0x5995}, {0x5996, 0x5996}, {0x5997, 0x5997}, + {0x5998, 0x5998}, {0x5999, 0x5999}, {0x599A, 0x599A}, {0x599B, 0x599B}, {0x599C, 0x599C}, {0x599D, 0x599D}, {0x599E, 0x599E}, + {0x599F, 0x599F}, {0x59A0, 0x59A0}, {0x59A1, 0x59A1}, {0x59A2, 0x59A2}, {0x59A3, 0x59A3}, {0x59A4, 0x59A4}, {0x59A5, 0x59A5}, + {0x59A6, 0x59A6}, {0x59A7, 0x59A7}, {0x59A8, 0x59A8}, {0x59A9, 0x59A9}, {0x59AA, 0x59AA}, {0x59AB, 0x59AB}, {0x59AC, 0x59AC}, + {0x59AD, 0x59AD}, {0x59AE, 0x59AE}, {0x59AF, 0x59AF}, {0x59B0, 0x59B0}, {0x59B1, 0x59B1}, {0x59B2, 0x59B2}, {0x59B3, 0x59B3}, + {0x59B4, 0x59B4}, {0x59B5, 0x59B5}, {0x59B6, 0x59B6}, {0x59B7, 0x59B7}, {0x59B8, 0x59B8}, {0x59B9, 0x59B9}, {0x59BA, 0x59BA}, + {0x59BB, 0x59BB}, {0x59BC, 0x59BC}, {0x59BD, 0x59BD}, {0x59BE, 0x59BE}, {0x59BF, 0x59BF}, {0x59C0, 0x59C0}, {0x59C1, 0x59C1}, + {0x59C2, 0x59C2}, {0x59C3, 0x59C3}, {0x59C4, 0x59C4}, {0x59C5, 0x59C5}, {0x59C6, 0x59C6}, {0x59C7, 0x59C7}, {0x59C8, 0x59C8}, + {0x59C9, 0x59C9}, {0x59CA, 0x59CA}, {0x59CB, 0x59CB}, {0x59CC, 0x59CC}, {0x59CD, 0x59CD}, {0x59CE, 0x59CE}, {0x59CF, 0x59CF}, + {0x59D0, 0x59D0}, {0x59D1, 0x59D1}, {0x59D2, 0x59D2}, {0x59D3, 0x59D3}, {0x59D4, 0x59D4}, {0x59D5, 0x59D5}, {0x59D6, 0x59D6}, + {0x59D7, 0x59D7}, {0x59D8, 0x59D8}, {0x59D9, 0x59D9}, {0x59DA, 0x59DA}, {0x59DB, 0x59DB}, {0x59DC, 0x59DC}, {0x59DD, 0x59DD}, + {0x59DE, 0x59DE}, {0x59DF, 0x59DF}, {0x59E0, 0x59E0}, {0x59E1, 0x59E1}, {0x59E2, 0x59E2}, {0x59E3, 0x59E3}, {0x59E4, 0x59E4}, + {0x59E5, 0x59E5}, {0x59E6, 0x59E6}, {0x59E7, 0x59E7}, {0x59E8, 0x59E8}, {0x59E9, 0x59E9}, {0x59EA, 0x59EA}, {0x59EB, 0x59EB}, + {0x59EC, 0x59EC}, {0x59ED, 0x59ED}, {0x59EE, 0x59EE}, {0x59EF, 0x59EF}, {0x59F0, 0x59F0}, {0x59F1, 0x59F1}, {0x59F2, 0x59F2}, + {0x59F3, 0x59F3}, {0x59F4, 0x59F4}, {0x59F5, 0x59F5}, {0x59F6, 0x59F6}, {0x59F7, 0x59F7}, {0x59F8, 0x59F8}, {0x59F9, 0x59F9}, + {0x59FA, 0x59FA}, {0x59FB, 0x59FB}, {0x59FC, 0x59FC}, {0x59FD, 0x59FD}, {0x59FE, 0x59FE}, {0x59FF, 0x59FF}, {0x5A00, 0x5A00}, + {0x5A01, 0x5A01}, {0x5A02, 0x5A02}, {0x5A03, 0x5A03}, {0x5A04, 0x5A04}, {0x5A05, 0x5A05}, {0x5A06, 0x5A06}, {0x5A07, 0x5A07}, + {0x5A08, 0x5A08}, {0x5A09, 0x5A09}, {0x5A0A, 0x5A0A}, {0x5A0B, 0x5A0B}, {0x5A0C, 0x5A0C}, {0x5A0D, 0x5A0D}, {0x5A0E, 0x5A0E}, + {0x5A0F, 0x5A0F}, {0x5A10, 0x5A10}, {0x5A11, 0x5A11}, {0x5A12, 0x5A12}, {0x5A13, 0x5A13}, {0x5A14, 0x5A14}, {0x5A15, 0x5A15}, + {0x5A16, 0x5A16}, {0x5A17, 0x5A17}, {0x5A18, 0x5A18}, {0x5A19, 0x5A19}, {0x5A1A, 0x5A1A}, {0x5A1B, 0x5A1B}, {0x5A1C, 0x5A1C}, + {0x5A1D, 0x5A1D}, {0x5A1E, 0x5A1E}, {0x5A1F, 0x5A1F}, {0x5A20, 0x5A20}, {0x5A21, 0x5A21}, {0x5A22, 0x5A22}, {0x5A23, 0x5A23}, + {0x5A24, 0x5A24}, {0x5A25, 0x5A25}, {0x5A26, 0x5A26}, {0x5A27, 0x5A27}, {0x5A28, 0x5A28}, {0x5A29, 0x5A29}, {0x5A2A, 0x5A2A}, + {0x5A2B, 0x5A2B}, {0x5A2C, 0x5A2C}, {0x5A2D, 0x5A2D}, {0x5A2E, 0x5A2E}, {0x5A2F, 0x5A2F}, {0x5A30, 0x5A30}, {0x5A31, 0x5A31}, + {0x5A32, 0x5A32}, {0x5A33, 0x5A33}, {0x5A34, 0x5A34}, {0x5A35, 0x5A35}, {0x5A36, 0x5A36}, {0x5A37, 0x5A37}, {0x5A38, 0x5A38}, + {0x5A39, 0x5A39}, {0x5A3A, 0x5A3A}, {0x5A3B, 0x5A3B}, {0x5A3C, 0x5A3C}, {0x5A3D, 0x5A3D}, {0x5A3E, 0x5A3E}, {0x5A3F, 0x5A3F}, + {0x5A40, 0x5A40}, {0x5A41, 0x5A41}, {0x5A42, 0x5A42}, {0x5A43, 0x5A43}, {0x5A44, 0x5A44}, {0x5A45, 0x5A45}, {0x5A46, 0x5A46}, + {0x5A47, 0x5A47}, {0x5A48, 0x5A48}, {0x5A49, 0x5A49}, {0x5A4A, 0x5A4A}, {0x5A4B, 0x5A4B}, {0x5A4C, 0x5A4C}, {0x5A4D, 0x5A4D}, + {0x5A4E, 0x5A4E}, {0x5A4F, 0x5A4F}, {0x5A50, 0x5A50}, {0x5A51, 0x5A51}, {0x5A52, 0x5A52}, {0x5A53, 0x5A53}, {0x5A54, 0x5A54}, + {0x5A55, 0x5A55}, {0x5A56, 0x5A56}, {0x5A57, 0x5A57}, {0x5A58, 0x5A58}, {0x5A59, 0x5A59}, {0x5A5A, 0x5A5A}, {0x5A5B, 0x5A5B}, + {0x5A5C, 0x5A5C}, {0x5A5D, 0x5A5D}, {0x5A5E, 0x5A5E}, {0x5A5F, 0x5A5F}, {0x5A60, 0x5A60}, {0x5A61, 0x5A61}, {0x5A62, 0x5A62}, + {0x5A63, 0x5A63}, {0x5A64, 0x5A64}, {0x5A65, 0x5A65}, {0x5A66, 0x5A66}, {0x5A67, 0x5A67}, {0x5A68, 0x5A68}, {0x5A69, 0x5A69}, + {0x5A6A, 0x5A6A}, {0x5A6B, 0x5A6B}, {0x5A6C, 0x5A6C}, {0x5A6D, 0x5A6D}, {0x5A6E, 0x5A6E}, {0x5A6F, 0x5A6F}, {0x5A70, 0x5A70}, + {0x5A71, 0x5A71}, {0x5A72, 0x5A72}, {0x5A73, 0x5A73}, {0x5A74, 0x5A74}, {0x5A75, 0x5A75}, {0x5A76, 0x5A76}, {0x5A77, 0x5A77}, + {0x5A78, 0x5A78}, {0x5A79, 0x5A79}, {0x5A7A, 0x5A7A}, {0x5A7B, 0x5A7B}, {0x5A7C, 0x5A7C}, {0x5A7D, 0x5A7D}, {0x5A7E, 0x5A7E}, + {0x5A7F, 0x5A7F}, {0x5A80, 0x5A80}, {0x5A81, 0x5A81}, {0x5A82, 0x5A82}, {0x5A83, 0x5A83}, {0x5A84, 0x5A84}, {0x5A85, 0x5A85}, + {0x5A86, 0x5A86}, {0x5A87, 0x5A87}, {0x5A88, 0x5A88}, {0x5A89, 0x5A89}, {0x5A8A, 0x5A8A}, {0x5A8B, 0x5A8B}, {0x5A8C, 0x5A8C}, + {0x5A8D, 0x5A8D}, {0x5A8E, 0x5A8E}, {0x5A8F, 0x5A8F}, {0x5A90, 0x5A90}, {0x5A91, 0x5A91}, {0x5A92, 0x5A92}, {0x5A93, 0x5A93}, + {0x5A94, 0x5A94}, {0x5A95, 0x5A95}, {0x5A96, 0x5A96}, {0x5A97, 0x5A97}, {0x5A98, 0x5A98}, {0x5A99, 0x5A99}, {0x5A9A, 0x5A9A}, + {0x5A9B, 0x5A9B}, {0x5A9C, 0x5A9C}, {0x5A9D, 0x5A9D}, {0x5A9E, 0x5A9E}, {0x5A9F, 0x5A9F}, {0x5AA0, 0x5AA0}, {0x5AA1, 0x5AA1}, + {0x5AA2, 0x5AA2}, {0x5AA3, 0x5AA3}, {0x5AA4, 0x5AA4}, {0x5AA5, 0x5AA5}, {0x5AA6, 0x5AA6}, {0x5AA7, 0x5AA7}, {0x5AA8, 0x5AA8}, + {0x5AA9, 0x5AA9}, {0x5AAA, 0x5AAA}, {0x5AAB, 0x5AAB}, {0x5AAC, 0x5AAC}, {0x5AAD, 0x5AAD}, {0x5AAE, 0x5AAE}, {0x5AAF, 0x5AAF}, + {0x5AB0, 0x5AB0}, {0x5AB1, 0x5AB1}, {0x5AB2, 0x5AB2}, {0x5AB3, 0x5AB3}, {0x5AB4, 0x5AB4}, {0x5AB5, 0x5AB5}, {0x5AB6, 0x5AB6}, + {0x5AB7, 0x5AB7}, {0x5AB8, 0x5AB8}, {0x5AB9, 0x5AB9}, {0x5ABA, 0x5ABA}, {0x5ABB, 0x5ABB}, {0x5ABC, 0x5ABC}, {0x5ABD, 0x5ABD}, + {0x5ABE, 0x5ABE}, {0x5ABF, 0x5ABF}, {0x5AC0, 0x5AC0}, {0x5AC1, 0x5AC1}, {0x5AC2, 0x5AC2}, {0x5AC3, 0x5AC3}, {0x5AC4, 0x5AC4}, + {0x5AC5, 0x5AC5}, {0x5AC6, 0x5AC6}, {0x5AC7, 0x5AC7}, {0x5AC8, 0x5AC8}, {0x5AC9, 0x5AC9}, {0x5ACA, 0x5ACA}, {0x5ACB, 0x5ACB}, + {0x5ACC, 0x5ACC}, {0x5ACD, 0x5ACD}, {0x5ACE, 0x5ACE}, {0x5ACF, 0x5ACF}, {0x5AD0, 0x5AD0}, {0x5AD1, 0x5AD1}, {0x5AD2, 0x5AD2}, + {0x5AD3, 0x5AD3}, {0x5AD4, 0x5AD4}, {0x5AD5, 0x5AD5}, {0x5AD6, 0x5AD6}, {0x5AD7, 0x5AD7}, {0x5AD8, 0x5AD8}, {0x5AD9, 0x5AD9}, + {0x5ADA, 0x5ADA}, {0x5ADB, 0x5ADB}, {0x5ADC, 0x5ADC}, {0x5ADD, 0x5ADD}, {0x5ADE, 0x5ADE}, {0x5ADF, 0x5ADF}, {0x5AE0, 0x5AE0}, + {0x5AE1, 0x5AE1}, {0x5AE2, 0x5AE2}, {0x5AE3, 0x5AE3}, {0x5AE4, 0x5AE4}, {0x5AE5, 0x5AE5}, {0x5AE6, 0x5AE6}, {0x5AE7, 0x5AE7}, + {0x5AE8, 0x5AE8}, {0x5AE9, 0x5AE9}, {0x5AEA, 0x5AEA}, {0x5AEB, 0x5AEB}, {0x5AEC, 0x5AEC}, {0x5AED, 0x5AED}, {0x5AEE, 0x5AEE}, + {0x5AEF, 0x5AEF}, {0x5AF0, 0x5AF0}, {0x5AF1, 0x5AF1}, {0x5AF2, 0x5AF2}, {0x5AF3, 0x5AF3}, {0x5AF4, 0x5AF4}, {0x5AF5, 0x5AF5}, + {0x5AF6, 0x5AF6}, {0x5AF7, 0x5AF7}, {0x5AF8, 0x5AF8}, {0x5AF9, 0x5AF9}, {0x5AFA, 0x5AFA}, {0x5AFB, 0x5AFB}, {0x5AFC, 0x5AFC}, + {0x5AFD, 0x5AFD}, {0x5AFE, 0x5AFE}, {0x5AFF, 0x5AFF}, {0x5B00, 0x5B00}, {0x5B01, 0x5B01}, {0x5B02, 0x5B02}, {0x5B03, 0x5B03}, + {0x5B04, 0x5B04}, {0x5B05, 0x5B05}, {0x5B06, 0x5B06}, {0x5B07, 0x5B07}, {0x5B08, 0x5B08}, {0x5B09, 0x5B09}, {0x5B0A, 0x5B0A}, + {0x5B0B, 0x5B0B}, {0x5B0C, 0x5B0C}, {0x5B0D, 0x5B0D}, {0x5B0E, 0x5B0E}, {0x5B0F, 0x5B0F}, {0x5B10, 0x5B10}, {0x5B11, 0x5B11}, + {0x5B12, 0x5B12}, {0x5B13, 0x5B13}, {0x5B14, 0x5B14}, {0x5B15, 0x5B15}, {0x5B16, 0x5B16}, {0x5B17, 0x5B17}, {0x5B18, 0x5B18}, + {0x5B19, 0x5B19}, {0x5B1A, 0x5B1A}, {0x5B1B, 0x5B1B}, {0x5B1C, 0x5B1C}, {0x5B1D, 0x5B1D}, {0x5B1E, 0x5B1E}, {0x5B1F, 0x5B1F}, + {0x5B20, 0x5B20}, {0x5B21, 0x5B21}, {0x5B22, 0x5B22}, {0x5B23, 0x5B23}, {0x5B24, 0x5B24}, {0x5B25, 0x5B25}, {0x5B26, 0x5B26}, + {0x5B27, 0x5B27}, {0x5B28, 0x5B28}, {0x5B29, 0x5B29}, {0x5B2A, 0x5B2A}, {0x5B2B, 0x5B2B}, {0x5B2C, 0x5B2C}, {0x5B2D, 0x5B2D}, + {0x5B2E, 0x5B2E}, {0x5B2F, 0x5B2F}, {0x5B30, 0x5B30}, {0x5B31, 0x5B31}, {0x5B32, 0x5B32}, {0x5B33, 0x5B33}, {0x5B34, 0x5B34}, + {0x5B35, 0x5B35}, {0x5B36, 0x5B36}, {0x5B37, 0x5B37}, {0x5B38, 0x5B38}, {0x5B39, 0x5B39}, {0x5B3A, 0x5B3A}, {0x5B3B, 0x5B3B}, + {0x5B3C, 0x5B3C}, {0x5B3D, 0x5B3D}, {0x5B3E, 0x5B3E}, {0x5B3F, 0x5B3F}, {0x5B40, 0x5B40}, {0x5B41, 0x5B41}, {0x5B42, 0x5B42}, + {0x5B43, 0x5B43}, {0x5B44, 0x5B44}, {0x5B45, 0x5B45}, {0x5B46, 0x5B46}, {0x5B47, 0x5B47}, {0x5B48, 0x5B48}, {0x5B49, 0x5B49}, + {0x5B4A, 0x5B4A}, {0x5B4B, 0x5B4B}, {0x5B4C, 0x5B4C}, {0x5B4D, 0x5B4D}, {0x5B4E, 0x5B4E}, {0x5B4F, 0x5B4F}, {0x5B50, 0x5B50}, + {0x5B51, 0x5B51}, {0x5B52, 0x5B52}, {0x5B53, 0x5B53}, {0x5B54, 0x5B54}, {0x5B55, 0x5B55}, {0x5B56, 0x5B56}, {0x5B57, 0x5B57}, + {0x5B58, 0x5B58}, {0x5B59, 0x5B59}, {0x5B5A, 0x5B5A}, {0x5B5B, 0x5B5B}, {0x5B5C, 0x5B5C}, {0x5B5D, 0x5B5D}, {0x5B5E, 0x5B5E}, + {0x5B5F, 0x5B5F}, {0x5B60, 0x5B60}, {0x5B61, 0x5B61}, {0x5B62, 0x5B62}, {0x5B63, 0x5B63}, {0x5B64, 0x5B64}, {0x5B65, 0x5B65}, + {0x5B66, 0x5B66}, {0x5B67, 0x5B67}, {0x5B68, 0x5B68}, {0x5B69, 0x5B69}, {0x5B6A, 0x5B6A}, {0x5B6B, 0x5B6B}, {0x5B6C, 0x5B6C}, + {0x5B6D, 0x5B6D}, {0x5B6E, 0x5B6E}, {0x5B6F, 0x5B6F}, {0x5B70, 0x5B70}, {0x5B71, 0x5B71}, {0x5B72, 0x5B72}, {0x5B73, 0x5B73}, + {0x5B74, 0x5B74}, {0x5B75, 0x5B75}, {0x5B76, 0x5B76}, {0x5B77, 0x5B77}, {0x5B78, 0x5B78}, {0x5B79, 0x5B79}, {0x5B7A, 0x5B7A}, + {0x5B7B, 0x5B7B}, {0x5B7C, 0x5B7C}, {0x5B7D, 0x5B7D}, {0x5B7E, 0x5B7E}, {0x5B7F, 0x5B7F}, {0x5B80, 0x5B80}, {0x5B81, 0x5B81}, + {0x5B82, 0x5B82}, {0x5B83, 0x5B83}, {0x5B84, 0x5B84}, {0x5B85, 0x5B85}, {0x5B86, 0x5B86}, {0x5B87, 0x5B87}, {0x5B88, 0x5B88}, + {0x5B89, 0x5B89}, {0x5B8A, 0x5B8A}, {0x5B8B, 0x5B8B}, {0x5B8C, 0x5B8C}, {0x5B8D, 0x5B8D}, {0x5B8E, 0x5B8E}, {0x5B8F, 0x5B8F}, + {0x5B90, 0x5B90}, {0x5B91, 0x5B91}, {0x5B92, 0x5B92}, {0x5B93, 0x5B93}, {0x5B94, 0x5B94}, {0x5B95, 0x5B95}, {0x5B96, 0x5B96}, + {0x5B97, 0x5B97}, {0x5B98, 0x5B98}, {0x5B99, 0x5B99}, {0x5B9A, 0x5B9A}, {0x5B9B, 0x5B9B}, {0x5B9C, 0x5B9C}, {0x5B9D, 0x5B9D}, + {0x5B9E, 0x5B9E}, {0x5B9F, 0x5B9F}, {0x5BA0, 0x5BA0}, {0x5BA1, 0x5BA1}, {0x5BA2, 0x5BA2}, {0x5BA3, 0x5BA3}, {0x5BA4, 0x5BA4}, + {0x5BA5, 0x5BA5}, {0x5BA6, 0x5BA6}, {0x5BA7, 0x5BA7}, {0x5BA8, 0x5BA8}, {0x5BA9, 0x5BA9}, {0x5BAA, 0x5BAA}, {0x5BAB, 0x5BAB}, + {0x5BAC, 0x5BAC}, {0x5BAD, 0x5BAD}, {0x5BAE, 0x5BAE}, {0x5BAF, 0x5BAF}, {0x5BB0, 0x5BB0}, {0x5BB1, 0x5BB1}, {0x5BB2, 0x5BB2}, + {0x5BB3, 0x5BB3}, {0x5BB4, 0x5BB4}, {0x5BB5, 0x5BB5}, {0x5BB6, 0x5BB6}, {0x5BB7, 0x5BB7}, {0x5BB8, 0x5BB8}, {0x5BB9, 0x5BB9}, + {0x5BBA, 0x5BBA}, {0x5BBB, 0x5BBB}, {0x5BBC, 0x5BBC}, {0x5BBD, 0x5BBD}, {0x5BBE, 0x5BBE}, {0x5BBF, 0x5BBF}, {0x5BC0, 0x5BC0}, + {0x5BC1, 0x5BC1}, {0x5BC2, 0x5BC2}, {0x5BC3, 0x5BC3}, {0x5BC4, 0x5BC4}, {0x5BC5, 0x5BC5}, {0x5BC6, 0x5BC6}, {0x5BC7, 0x5BC7}, + {0x5BC8, 0x5BC8}, {0x5BC9, 0x5BC9}, {0x5BCA, 0x5BCA}, {0x5BCB, 0x5BCB}, {0x5BCC, 0x5BCC}, {0x5BCD, 0x5BCD}, {0x5BCE, 0x5BCE}, + {0x5BCF, 0x5BCF}, {0x5BD0, 0x5BD0}, {0x5BD1, 0x5BD1}, {0x5BD2, 0x5BD2}, {0x5BD3, 0x5BD3}, {0x5BD4, 0x5BD4}, {0x5BD5, 0x5BD5}, + {0x5BD6, 0x5BD6}, {0x5BD7, 0x5BD7}, {0x5BD8, 0x5BD8}, {0x5BD9, 0x5BD9}, {0x5BDA, 0x5BDA}, {0x5BDB, 0x5BDB}, {0x5BDC, 0x5BDC}, + {0x5BDD, 0x5BDD}, {0x5BDE, 0x5BDE}, {0x5BDF, 0x5BDF}, {0x5BE0, 0x5BE0}, {0x5BE1, 0x5BE1}, {0x5BE2, 0x5BE2}, {0x5BE3, 0x5BE3}, + {0x5BE4, 0x5BE4}, {0x5BE5, 0x5BE5}, {0x5BE6, 0x5BE6}, {0x5BE7, 0x5BE7}, {0x5BE8, 0x5BE8}, {0x5BE9, 0x5BE9}, {0x5BEA, 0x5BEA}, + {0x5BEB, 0x5BEB}, {0x5BEC, 0x5BEC}, {0x5BED, 0x5BED}, {0x5BEE, 0x5BEE}, {0x5BEF, 0x5BEF}, {0x5BF0, 0x5BF0}, {0x5BF1, 0x5BF1}, + {0x5BF2, 0x5BF2}, {0x5BF3, 0x5BF3}, {0x5BF4, 0x5BF4}, {0x5BF5, 0x5BF5}, {0x5BF6, 0x5BF6}, {0x5BF7, 0x5BF7}, {0x5BF8, 0x5BF8}, + {0x5BF9, 0x5BF9}, {0x5BFA, 0x5BFA}, {0x5BFB, 0x5BFB}, {0x5BFC, 0x5BFC}, {0x5BFD, 0x5BFD}, {0x5BFE, 0x5BFE}, {0x5BFF, 0x5BFF}, + {0x5C00, 0x5C00}, {0x5C01, 0x5C01}, {0x5C02, 0x5C02}, {0x5C03, 0x5C03}, {0x5C04, 0x5C04}, {0x5C05, 0x5C05}, {0x5C06, 0x5C06}, + {0x5C07, 0x5C07}, {0x5C08, 0x5C08}, {0x5C09, 0x5C09}, {0x5C0A, 0x5C0A}, {0x5C0B, 0x5C0B}, {0x5C0C, 0x5C0C}, {0x5C0D, 0x5C0D}, + {0x5C0E, 0x5C0E}, {0x5C0F, 0x5C0F}, {0x5C10, 0x5C10}, {0x5C11, 0x5C11}, {0x5C12, 0x5C12}, {0x5C13, 0x5C13}, {0x5C14, 0x5C14}, + {0x5C15, 0x5C15}, {0x5C16, 0x5C16}, {0x5C17, 0x5C17}, {0x5C18, 0x5C18}, {0x5C19, 0x5C19}, {0x5C1A, 0x5C1A}, {0x5C1B, 0x5C1B}, + {0x5C1C, 0x5C1C}, {0x5C1D, 0x5C1D}, {0x5C1E, 0x5C1E}, {0x5C1F, 0x5C1F}, {0x5C20, 0x5C20}, {0x5C21, 0x5C21}, {0x5C22, 0x5C22}, + {0x5C23, 0x5C23}, {0x5C24, 0x5C24}, {0x5C25, 0x5C25}, {0x5C26, 0x5C26}, {0x5C27, 0x5C27}, {0x5C28, 0x5C28}, {0x5C29, 0x5C29}, + {0x5C2A, 0x5C2A}, {0x5C2B, 0x5C2B}, {0x5C2C, 0x5C2C}, {0x5C2D, 0x5C2D}, {0x5C2E, 0x5C2E}, {0x5C2F, 0x5C2F}, {0x5C30, 0x5C30}, + {0x5C31, 0x5C31}, {0x5C32, 0x5C32}, {0x5C33, 0x5C33}, {0x5C34, 0x5C34}, {0x5C35, 0x5C35}, {0x5C36, 0x5C36}, {0x5C37, 0x5C37}, + {0x5C38, 0x5C38}, {0x5C39, 0x5C39}, {0x5C3A, 0x5C3A}, {0x5C3B, 0x5C3B}, {0x5C3C, 0x5C3C}, {0x5C3D, 0x5C3D}, {0x5C3E, 0x5C3E}, + {0x5C3F, 0x5C3F}, {0x5C40, 0x5C40}, {0x5C41, 0x5C41}, {0x5C42, 0x5C42}, {0x5C43, 0x5C43}, {0x5C44, 0x5C44}, {0x5C45, 0x5C45}, + {0x5C46, 0x5C46}, {0x5C47, 0x5C47}, {0x5C48, 0x5C48}, {0x5C49, 0x5C49}, {0x5C4A, 0x5C4A}, {0x5C4B, 0x5C4B}, {0x5C4C, 0x5C4C}, + {0x5C4D, 0x5C4D}, {0x5C4E, 0x5C4E}, {0x5C4F, 0x5C4F}, {0x5C50, 0x5C50}, {0x5C51, 0x5C51}, {0x5C52, 0x5C52}, {0x5C53, 0x5C53}, + {0x5C54, 0x5C54}, {0x5C55, 0x5C55}, {0x5C56, 0x5C56}, {0x5C57, 0x5C57}, {0x5C58, 0x5C58}, {0x5C59, 0x5C59}, {0x5C5A, 0x5C5A}, + {0x5C5B, 0x5C5B}, {0x5C5C, 0x5C5C}, {0x5C5D, 0x5C5D}, {0x5C5E, 0x5C5E}, {0x5C5F, 0x5C5F}, {0x5C60, 0x5C60}, {0x5C61, 0x5C61}, + {0x5C62, 0x5C62}, {0x5C63, 0x5C63}, {0x5C64, 0x5C64}, {0x5C65, 0x5C65}, {0x5C66, 0x5C66}, {0x5C67, 0x5C67}, {0x5C68, 0x5C68}, + {0x5C69, 0x5C69}, {0x5C6A, 0x5C6A}, {0x5C6B, 0x5C6B}, {0x5C6C, 0x5C6C}, {0x5C6D, 0x5C6D}, {0x5C6E, 0x5C6E}, {0x5C6F, 0x5C6F}, + {0x5C70, 0x5C70}, {0x5C71, 0x5C71}, {0x5C72, 0x5C72}, {0x5C73, 0x5C73}, {0x5C74, 0x5C74}, {0x5C75, 0x5C75}, {0x5C76, 0x5C76}, + {0x5C77, 0x5C77}, {0x5C78, 0x5C78}, {0x5C79, 0x5C79}, {0x5C7A, 0x5C7A}, {0x5C7B, 0x5C7B}, {0x5C7C, 0x5C7C}, {0x5C7D, 0x5C7D}, + {0x5C7E, 0x5C7E}, {0x5C7F, 0x5C7F}, {0x5C80, 0x5C80}, {0x5C81, 0x5C81}, {0x5C82, 0x5C82}, {0x5C83, 0x5C83}, {0x5C84, 0x5C84}, + {0x5C85, 0x5C85}, {0x5C86, 0x5C86}, {0x5C87, 0x5C87}, {0x5C88, 0x5C88}, {0x5C89, 0x5C89}, {0x5C8A, 0x5C8A}, {0x5C8B, 0x5C8B}, + {0x5C8C, 0x5C8C}, {0x5C8D, 0x5C8D}, {0x5C8E, 0x5C8E}, {0x5C8F, 0x5C8F}, {0x5C90, 0x5C90}, {0x5C91, 0x5C91}, {0x5C92, 0x5C92}, + {0x5C93, 0x5C93}, {0x5C94, 0x5C94}, {0x5C95, 0x5C95}, {0x5C96, 0x5C96}, {0x5C97, 0x5C97}, {0x5C98, 0x5C98}, {0x5C99, 0x5C99}, + {0x5C9A, 0x5C9A}, {0x5C9B, 0x5C9B}, {0x5C9C, 0x5C9C}, {0x5C9D, 0x5C9D}, {0x5C9E, 0x5C9E}, {0x5C9F, 0x5C9F}, {0x5CA0, 0x5CA0}, + {0x5CA1, 0x5CA1}, {0x5CA2, 0x5CA2}, {0x5CA3, 0x5CA3}, {0x5CA4, 0x5CA4}, {0x5CA5, 0x5CA5}, {0x5CA6, 0x5CA6}, {0x5CA7, 0x5CA7}, + {0x5CA8, 0x5CA8}, {0x5CA9, 0x5CA9}, {0x5CAA, 0x5CAA}, {0x5CAB, 0x5CAB}, {0x5CAC, 0x5CAC}, {0x5CAD, 0x5CAD}, {0x5CAE, 0x5CAE}, + {0x5CAF, 0x5CAF}, {0x5CB0, 0x5CB0}, {0x5CB1, 0x5CB1}, {0x5CB2, 0x5CB2}, {0x5CB3, 0x5CB3}, {0x5CB4, 0x5CB4}, {0x5CB5, 0x5CB5}, + {0x5CB6, 0x5CB6}, {0x5CB7, 0x5CB7}, {0x5CB8, 0x5CB8}, {0x5CB9, 0x5CB9}, {0x5CBA, 0x5CBA}, {0x5CBB, 0x5CBB}, {0x5CBC, 0x5CBC}, + {0x5CBD, 0x5CBD}, {0x5CBE, 0x5CBE}, {0x5CBF, 0x5CBF}, {0x5CC0, 0x5CC0}, {0x5CC1, 0x5CC1}, {0x5CC2, 0x5CC2}, {0x5CC3, 0x5CC3}, + {0x5CC4, 0x5CC4}, {0x5CC5, 0x5CC5}, {0x5CC6, 0x5CC6}, {0x5CC7, 0x5CC7}, {0x5CC8, 0x5CC8}, {0x5CC9, 0x5CC9}, {0x5CCA, 0x5CCA}, + {0x5CCB, 0x5CCB}, {0x5CCC, 0x5CCC}, {0x5CCD, 0x5CCD}, {0x5CCE, 0x5CCE}, {0x5CCF, 0x5CCF}, {0x5CD0, 0x5CD0}, {0x5CD1, 0x5CD1}, + {0x5CD2, 0x5CD2}, {0x5CD3, 0x5CD3}, {0x5CD4, 0x5CD4}, {0x5CD5, 0x5CD5}, {0x5CD6, 0x5CD6}, {0x5CD7, 0x5CD7}, {0x5CD8, 0x5CD8}, + {0x5CD9, 0x5CD9}, {0x5CDA, 0x5CDA}, {0x5CDB, 0x5CDB}, {0x5CDC, 0x5CDC}, {0x5CDD, 0x5CDD}, {0x5CDE, 0x5CDE}, {0x5CDF, 0x5CDF}, + {0x5CE0, 0x5CE0}, {0x5CE1, 0x5CE1}, {0x5CE2, 0x5CE2}, {0x5CE3, 0x5CE3}, {0x5CE4, 0x5CE4}, {0x5CE5, 0x5CE5}, {0x5CE6, 0x5CE6}, + {0x5CE7, 0x5CE7}, {0x5CE8, 0x5CE8}, {0x5CE9, 0x5CE9}, {0x5CEA, 0x5CEA}, {0x5CEB, 0x5CEB}, {0x5CEC, 0x5CEC}, {0x5CED, 0x5CED}, + {0x5CEE, 0x5CEE}, {0x5CEF, 0x5CEF}, {0x5CF0, 0x5CF0}, {0x5CF1, 0x5CF1}, {0x5CF2, 0x5CF2}, {0x5CF3, 0x5CF3}, {0x5CF4, 0x5CF4}, + {0x5CF5, 0x5CF5}, {0x5CF6, 0x5CF6}, {0x5CF7, 0x5CF7}, {0x5CF8, 0x5CF8}, {0x5CF9, 0x5CF9}, {0x5CFA, 0x5CFA}, {0x5CFB, 0x5CFB}, + {0x5CFC, 0x5CFC}, {0x5CFD, 0x5CFD}, {0x5CFE, 0x5CFE}, {0x5CFF, 0x5CFF}, {0x5D00, 0x5D00}, {0x5D01, 0x5D01}, {0x5D02, 0x5D02}, + {0x5D03, 0x5D03}, {0x5D04, 0x5D04}, {0x5D05, 0x5D05}, {0x5D06, 0x5D06}, {0x5D07, 0x5D07}, {0x5D08, 0x5D08}, {0x5D09, 0x5D09}, + {0x5D0A, 0x5D0A}, {0x5D0B, 0x5D0B}, {0x5D0C, 0x5D0C}, {0x5D0D, 0x5D0D}, {0x5D0E, 0x5D0E}, {0x5D0F, 0x5D0F}, {0x5D10, 0x5D10}, + {0x5D11, 0x5D11}, {0x5D12, 0x5D12}, {0x5D13, 0x5D13}, {0x5D14, 0x5D14}, {0x5D15, 0x5D15}, {0x5D16, 0x5D16}, {0x5D17, 0x5D17}, + {0x5D18, 0x5D18}, {0x5D19, 0x5D19}, {0x5D1A, 0x5D1A}, {0x5D1B, 0x5D1B}, {0x5D1C, 0x5D1C}, {0x5D1D, 0x5D1D}, {0x5D1E, 0x5D1E}, + {0x5D1F, 0x5D1F}, {0x5D20, 0x5D20}, {0x5D21, 0x5D21}, {0x5D22, 0x5D22}, {0x5D23, 0x5D23}, {0x5D24, 0x5D24}, {0x5D25, 0x5D25}, + {0x5D26, 0x5D26}, {0x5D27, 0x5D27}, {0x5D28, 0x5D28}, {0x5D29, 0x5D29}, {0x5D2A, 0x5D2A}, {0x5D2B, 0x5D2B}, {0x5D2C, 0x5D2C}, + {0x5D2D, 0x5D2D}, {0x5D2E, 0x5D2E}, {0x5D2F, 0x5D2F}, {0x5D30, 0x5D30}, {0x5D31, 0x5D31}, {0x5D32, 0x5D32}, {0x5D33, 0x5D33}, + {0x5D34, 0x5D34}, {0x5D35, 0x5D35}, {0x5D36, 0x5D36}, {0x5D37, 0x5D37}, {0x5D38, 0x5D38}, {0x5D39, 0x5D39}, {0x5D3A, 0x5D3A}, + {0x5D3B, 0x5D3B}, {0x5D3C, 0x5D3C}, {0x5D3D, 0x5D3D}, {0x5D3E, 0x5D3E}, {0x5D3F, 0x5D3F}, {0x5D40, 0x5D40}, {0x5D41, 0x5D41}, + {0x5D42, 0x5D42}, {0x5D43, 0x5D43}, {0x5D44, 0x5D44}, {0x5D45, 0x5D45}, {0x5D46, 0x5D46}, {0x5D47, 0x5D47}, {0x5D48, 0x5D48}, + {0x5D49, 0x5D49}, {0x5D4A, 0x5D4A}, {0x5D4B, 0x5D4B}, {0x5D4C, 0x5D4C}, {0x5D4D, 0x5D4D}, {0x5D4E, 0x5D4E}, {0x5D4F, 0x5D4F}, + {0x5D50, 0x5D50}, {0x5D51, 0x5D51}, {0x5D52, 0x5D52}, {0x5D53, 0x5D53}, {0x5D54, 0x5D54}, {0x5D55, 0x5D55}, {0x5D56, 0x5D56}, + {0x5D57, 0x5D57}, {0x5D58, 0x5D58}, {0x5D59, 0x5D59}, {0x5D5A, 0x5D5A}, {0x5D5B, 0x5D5B}, {0x5D5C, 0x5D5C}, {0x5D5D, 0x5D5D}, + {0x5D5E, 0x5D5E}, {0x5D5F, 0x5D5F}, {0x5D60, 0x5D60}, {0x5D61, 0x5D61}, {0x5D62, 0x5D62}, {0x5D63, 0x5D63}, {0x5D64, 0x5D64}, + {0x5D65, 0x5D65}, {0x5D66, 0x5D66}, {0x5D67, 0x5D67}, {0x5D68, 0x5D68}, {0x5D69, 0x5D69}, {0x5D6A, 0x5D6A}, {0x5D6B, 0x5D6B}, + {0x5D6C, 0x5D6C}, {0x5D6D, 0x5D6D}, {0x5D6E, 0x5D6E}, {0x5D6F, 0x5D6F}, {0x5D70, 0x5D70}, {0x5D71, 0x5D71}, {0x5D72, 0x5D72}, + {0x5D73, 0x5D73}, {0x5D74, 0x5D74}, {0x5D75, 0x5D75}, {0x5D76, 0x5D76}, {0x5D77, 0x5D77}, {0x5D78, 0x5D78}, {0x5D79, 0x5D79}, + {0x5D7A, 0x5D7A}, {0x5D7B, 0x5D7B}, {0x5D7C, 0x5D7C}, {0x5D7D, 0x5D7D}, {0x5D7E, 0x5D7E}, {0x5D7F, 0x5D7F}, {0x5D80, 0x5D80}, + {0x5D81, 0x5D81}, {0x5D82, 0x5D82}, {0x5D83, 0x5D83}, {0x5D84, 0x5D84}, {0x5D85, 0x5D85}, {0x5D86, 0x5D86}, {0x5D87, 0x5D87}, + {0x5D88, 0x5D88}, {0x5D89, 0x5D89}, {0x5D8A, 0x5D8A}, {0x5D8B, 0x5D8B}, {0x5D8C, 0x5D8C}, {0x5D8D, 0x5D8D}, {0x5D8E, 0x5D8E}, + {0x5D8F, 0x5D8F}, {0x5D90, 0x5D90}, {0x5D91, 0x5D91}, {0x5D92, 0x5D92}, {0x5D93, 0x5D93}, {0x5D94, 0x5D94}, {0x5D95, 0x5D95}, + {0x5D96, 0x5D96}, {0x5D97, 0x5D97}, {0x5D98, 0x5D98}, {0x5D99, 0x5D99}, {0x5D9A, 0x5D9A}, {0x5D9B, 0x5D9B}, {0x5D9C, 0x5D9C}, + {0x5D9D, 0x5D9D}, {0x5D9E, 0x5D9E}, {0x5D9F, 0x5D9F}, {0x5DA0, 0x5DA0}, {0x5DA1, 0x5DA1}, {0x5DA2, 0x5DA2}, {0x5DA3, 0x5DA3}, + {0x5DA4, 0x5DA4}, {0x5DA5, 0x5DA5}, {0x5DA6, 0x5DA6}, {0x5DA7, 0x5DA7}, {0x5DA8, 0x5DA8}, {0x5DA9, 0x5DA9}, {0x5DAA, 0x5DAA}, + {0x5DAB, 0x5DAB}, {0x5DAC, 0x5DAC}, {0x5DAD, 0x5DAD}, {0x5DAE, 0x5DAE}, {0x5DAF, 0x5DAF}, {0x5DB0, 0x5DB0}, {0x5DB1, 0x5DB1}, + {0x5DB2, 0x5DB2}, {0x5DB3, 0x5DB3}, {0x5DB4, 0x5DB4}, {0x5DB5, 0x5DB5}, {0x5DB6, 0x5DB6}, {0x5DB7, 0x5DB7}, {0x5DB8, 0x5DB8}, + {0x5DB9, 0x5DB9}, {0x5DBA, 0x5DBA}, {0x5DBB, 0x5DBB}, {0x5DBC, 0x5DBC}, {0x5DBD, 0x5DBD}, {0x5DBE, 0x5DBE}, {0x5DBF, 0x5DBF}, + {0x5DC0, 0x5DC0}, {0x5DC1, 0x5DC1}, {0x5DC2, 0x5DC2}, {0x5DC3, 0x5DC3}, {0x5DC4, 0x5DC4}, {0x5DC5, 0x5DC5}, {0x5DC6, 0x5DC6}, + {0x5DC7, 0x5DC7}, {0x5DC8, 0x5DC8}, {0x5DC9, 0x5DC9}, {0x5DCA, 0x5DCA}, {0x5DCB, 0x5DCB}, {0x5DCC, 0x5DCC}, {0x5DCD, 0x5DCD}, + {0x5DCE, 0x5DCE}, {0x5DCF, 0x5DCF}, {0x5DD0, 0x5DD0}, {0x5DD1, 0x5DD1}, {0x5DD2, 0x5DD2}, {0x5DD3, 0x5DD3}, {0x5DD4, 0x5DD4}, + {0x5DD5, 0x5DD5}, {0x5DD6, 0x5DD6}, {0x5DD7, 0x5DD7}, {0x5DD8, 0x5DD8}, {0x5DD9, 0x5DD9}, {0x5DDA, 0x5DDA}, {0x5DDB, 0x5DDB}, + {0x5DDC, 0x5DDC}, {0x5DDD, 0x5DDD}, {0x5DDE, 0x5DDE}, {0x5DDF, 0x5DDF}, {0x5DE0, 0x5DE0}, {0x5DE1, 0x5DE1}, {0x5DE2, 0x5DE2}, + {0x5DE3, 0x5DE3}, {0x5DE4, 0x5DE4}, {0x5DE5, 0x5DE5}, {0x5DE6, 0x5DE6}, {0x5DE7, 0x5DE7}, {0x5DE8, 0x5DE8}, {0x5DE9, 0x5DE9}, + {0x5DEA, 0x5DEA}, {0x5DEB, 0x5DEB}, {0x5DEC, 0x5DEC}, {0x5DED, 0x5DED}, {0x5DEE, 0x5DEE}, {0x5DEF, 0x5DEF}, {0x5DF0, 0x5DF0}, + {0x5DF1, 0x5DF1}, {0x5DF2, 0x5DF2}, {0x5DF3, 0x5DF3}, {0x5DF4, 0x5DF4}, {0x5DF5, 0x5DF5}, {0x5DF6, 0x5DF6}, {0x5DF7, 0x5DF7}, + {0x5DF8, 0x5DF8}, {0x5DF9, 0x5DF9}, {0x5DFA, 0x5DFA}, {0x5DFB, 0x5DFB}, {0x5DFC, 0x5DFC}, {0x5DFD, 0x5DFD}, {0x5DFE, 0x5DFE}, + {0x5DFF, 0x5DFF}, {0x5E00, 0x5E00}, {0x5E01, 0x5E01}, {0x5E02, 0x5E02}, {0x5E03, 0x5E03}, {0x5E04, 0x5E04}, {0x5E05, 0x5E05}, + {0x5E06, 0x5E06}, {0x5E07, 0x5E07}, {0x5E08, 0x5E08}, {0x5E09, 0x5E09}, {0x5E0A, 0x5E0A}, {0x5E0B, 0x5E0B}, {0x5E0C, 0x5E0C}, + {0x5E0D, 0x5E0D}, {0x5E0E, 0x5E0E}, {0x5E0F, 0x5E0F}, {0x5E10, 0x5E10}, {0x5E11, 0x5E11}, {0x5E12, 0x5E12}, {0x5E13, 0x5E13}, + {0x5E14, 0x5E14}, {0x5E15, 0x5E15}, {0x5E16, 0x5E16}, {0x5E17, 0x5E17}, {0x5E18, 0x5E18}, {0x5E19, 0x5E19}, {0x5E1A, 0x5E1A}, + {0x5E1B, 0x5E1B}, {0x5E1C, 0x5E1C}, {0x5E1D, 0x5E1D}, {0x5E1E, 0x5E1E}, {0x5E1F, 0x5E1F}, {0x5E20, 0x5E20}, {0x5E21, 0x5E21}, + {0x5E22, 0x5E22}, {0x5E23, 0x5E23}, {0x5E24, 0x5E24}, {0x5E25, 0x5E25}, {0x5E26, 0x5E26}, {0x5E27, 0x5E27}, {0x5E28, 0x5E28}, + {0x5E29, 0x5E29}, {0x5E2A, 0x5E2A}, {0x5E2B, 0x5E2B}, {0x5E2C, 0x5E2C}, {0x5E2D, 0x5E2D}, {0x5E2E, 0x5E2E}, {0x5E2F, 0x5E2F}, + {0x5E30, 0x5E30}, {0x5E31, 0x5E31}, {0x5E32, 0x5E32}, {0x5E33, 0x5E33}, {0x5E34, 0x5E34}, {0x5E35, 0x5E35}, {0x5E36, 0x5E36}, + {0x5E37, 0x5E37}, {0x5E38, 0x5E38}, {0x5E39, 0x5E39}, {0x5E3A, 0x5E3A}, {0x5E3B, 0x5E3B}, {0x5E3C, 0x5E3C}, {0x5E3D, 0x5E3D}, + {0x5E3E, 0x5E3E}, {0x5E3F, 0x5E3F}, {0x5E40, 0x5E40}, {0x5E41, 0x5E41}, {0x5E42, 0x5E42}, {0x5E43, 0x5E43}, {0x5E44, 0x5E44}, + {0x5E45, 0x5E45}, {0x5E46, 0x5E46}, {0x5E47, 0x5E47}, {0x5E48, 0x5E48}, {0x5E49, 0x5E49}, {0x5E4A, 0x5E4A}, {0x5E4B, 0x5E4B}, + {0x5E4C, 0x5E4C}, {0x5E4D, 0x5E4D}, {0x5E4E, 0x5E4E}, {0x5E4F, 0x5E4F}, {0x5E50, 0x5E50}, {0x5E51, 0x5E51}, {0x5E52, 0x5E52}, + {0x5E53, 0x5E53}, {0x5E54, 0x5E54}, {0x5E55, 0x5E55}, {0x5E56, 0x5E56}, {0x5E57, 0x5E57}, {0x5E58, 0x5E58}, {0x5E59, 0x5E59}, + {0x5E5A, 0x5E5A}, {0x5E5B, 0x5E5B}, {0x5E5C, 0x5E5C}, {0x5E5D, 0x5E5D}, {0x5E5E, 0x5E5E}, {0x5E5F, 0x5E5F}, {0x5E60, 0x5E60}, + {0x5E61, 0x5E61}, {0x5E62, 0x5E62}, {0x5E63, 0x5E63}, {0x5E64, 0x5E64}, {0x5E65, 0x5E65}, {0x5E66, 0x5E66}, {0x5E67, 0x5E67}, + {0x5E68, 0x5E68}, {0x5E69, 0x5E69}, {0x5E6A, 0x5E6A}, {0x5E6B, 0x5E6B}, {0x5E6C, 0x5E6C}, {0x5E6D, 0x5E6D}, {0x5E6E, 0x5E6E}, + {0x5E6F, 0x5E6F}, {0x5E70, 0x5E70}, {0x5E71, 0x5E71}, {0x5E72, 0x5E72}, {0x5E73, 0x5E73}, {0x5E74, 0x5E74}, {0x5E75, 0x5E75}, + {0x5E76, 0x5E76}, {0x5E77, 0x5E77}, {0x5E78, 0x5E78}, {0x5E79, 0x5E79}, {0x5E7A, 0x5E7A}, {0x5E7B, 0x5E7B}, {0x5E7C, 0x5E7C}, + {0x5E7D, 0x5E7D}, {0x5E7E, 0x5E7E}, {0x5E7F, 0x5E7F}, {0x5E80, 0x5E80}, {0x5E81, 0x5E81}, {0x5E82, 0x5E82}, {0x5E83, 0x5E83}, + {0x5E84, 0x5E84}, {0x5E85, 0x5E85}, {0x5E86, 0x5E86}, {0x5E87, 0x5E87}, {0x5E88, 0x5E88}, {0x5E89, 0x5E89}, {0x5E8A, 0x5E8A}, + {0x5E8B, 0x5E8B}, {0x5E8C, 0x5E8C}, {0x5E8D, 0x5E8D}, {0x5E8E, 0x5E8E}, {0x5E8F, 0x5E8F}, {0x5E90, 0x5E90}, {0x5E91, 0x5E91}, + {0x5E92, 0x5E92}, {0x5E93, 0x5E93}, {0x5E94, 0x5E94}, {0x5E95, 0x5E95}, {0x5E96, 0x5E96}, {0x5E97, 0x5E97}, {0x5E98, 0x5E98}, + {0x5E99, 0x5E99}, {0x5E9A, 0x5E9A}, {0x5E9B, 0x5E9B}, {0x5E9C, 0x5E9C}, {0x5E9D, 0x5E9D}, {0x5E9E, 0x5E9E}, {0x5E9F, 0x5E9F}, + {0x5EA0, 0x5EA0}, {0x5EA1, 0x5EA1}, {0x5EA2, 0x5EA2}, {0x5EA3, 0x5EA3}, {0x5EA4, 0x5EA4}, {0x5EA5, 0x5EA5}, {0x5EA6, 0x5EA6}, + {0x5EA7, 0x5EA7}, {0x5EA8, 0x5EA8}, {0x5EA9, 0x5EA9}, {0x5EAA, 0x5EAA}, {0x5EAB, 0x5EAB}, {0x5EAC, 0x5EAC}, {0x5EAD, 0x5EAD}, + {0x5EAE, 0x5EAE}, {0x5EAF, 0x5EAF}, {0x5EB0, 0x5EB0}, {0x5EB1, 0x5EB1}, {0x5EB2, 0x5EB2}, {0x5EB3, 0x5EB3}, {0x5EB4, 0x5EB4}, + {0x5EB5, 0x5EB5}, {0x5EB6, 0x5EB6}, {0x5EB7, 0x5EB7}, {0x5EB8, 0x5EB8}, {0x5EB9, 0x5EB9}, {0x5EBA, 0x5EBA}, {0x5EBB, 0x5EBB}, + {0x5EBC, 0x5EBC}, {0x5EBD, 0x5EBD}, {0x5EBE, 0x5EBE}, {0x5EBF, 0x5EBF}, {0x5EC0, 0x5EC0}, {0x5EC1, 0x5EC1}, {0x5EC2, 0x5EC2}, + {0x5EC3, 0x5EC3}, {0x5EC4, 0x5EC4}, {0x5EC5, 0x5EC5}, {0x5EC6, 0x5EC6}, {0x5EC7, 0x5EC7}, {0x5EC8, 0x5EC8}, {0x5EC9, 0x5EC9}, + {0x5ECA, 0x5ECA}, {0x5ECB, 0x5ECB}, {0x5ECC, 0x5ECC}, {0x5ECD, 0x5ECD}, {0x5ECE, 0x5ECE}, {0x5ECF, 0x5ECF}, {0x5ED0, 0x5ED0}, + {0x5ED1, 0x5ED1}, {0x5ED2, 0x5ED2}, {0x5ED3, 0x5ED3}, {0x5ED4, 0x5ED4}, {0x5ED5, 0x5ED5}, {0x5ED6, 0x5ED6}, {0x5ED7, 0x5ED7}, + {0x5ED8, 0x5ED8}, {0x5ED9, 0x5ED9}, {0x5EDA, 0x5EDA}, {0x5EDB, 0x5EDB}, {0x5EDC, 0x5EDC}, {0x5EDD, 0x5EDD}, {0x5EDE, 0x5EDE}, + {0x5EDF, 0x5EDF}, {0x5EE0, 0x5EE0}, {0x5EE1, 0x5EE1}, {0x5EE2, 0x5EE2}, {0x5EE3, 0x5EE3}, {0x5EE4, 0x5EE4}, {0x5EE5, 0x5EE5}, + {0x5EE6, 0x5EE6}, {0x5EE7, 0x5EE7}, {0x5EE8, 0x5EE8}, {0x5EE9, 0x5EE9}, {0x5EEA, 0x5EEA}, {0x5EEB, 0x5EEB}, {0x5EEC, 0x5EEC}, + {0x5EED, 0x5EED}, {0x5EEE, 0x5EEE}, {0x5EEF, 0x5EEF}, {0x5EF0, 0x5EF0}, {0x5EF1, 0x5EF1}, {0x5EF2, 0x5EF2}, {0x5EF3, 0x5EF3}, + {0x5EF4, 0x5EF4}, {0x5EF5, 0x5EF5}, {0x5EF6, 0x5EF6}, {0x5EF7, 0x5EF7}, {0x5EF8, 0x5EF8}, {0x5EF9, 0x5EF9}, {0x5EFA, 0x5EFA}, + {0x5EFB, 0x5EFB}, {0x5EFC, 0x5EFC}, {0x5EFD, 0x5EFD}, {0x5EFE, 0x5EFE}, {0x5EFF, 0x5EFF}, {0x5F00, 0x5F00}, {0x5F01, 0x5F01}, + {0x5F02, 0x5F02}, {0x5F03, 0x5F03}, {0x5F04, 0x5F04}, {0x5F05, 0x5F05}, {0x5F06, 0x5F06}, {0x5F07, 0x5F07}, {0x5F08, 0x5F08}, + {0x5F09, 0x5F09}, {0x5F0A, 0x5F0A}, {0x5F0B, 0x5F0B}, {0x5F0C, 0x5F0C}, {0x5F0D, 0x5F0D}, {0x5F0E, 0x5F0E}, {0x5F0F, 0x5F0F}, + {0x5F10, 0x5F10}, {0x5F11, 0x5F11}, {0x5F12, 0x5F12}, {0x5F13, 0x5F13}, {0x5F14, 0x5F14}, {0x5F15, 0x5F15}, {0x5F16, 0x5F16}, + {0x5F17, 0x5F17}, {0x5F18, 0x5F18}, {0x5F19, 0x5F19}, {0x5F1A, 0x5F1A}, {0x5F1B, 0x5F1B}, {0x5F1C, 0x5F1C}, {0x5F1D, 0x5F1D}, + {0x5F1E, 0x5F1E}, {0x5F1F, 0x5F1F}, {0x5F20, 0x5F20}, {0x5F21, 0x5F21}, {0x5F22, 0x5F22}, {0x5F23, 0x5F23}, {0x5F24, 0x5F24}, + {0x5F25, 0x5F25}, {0x5F26, 0x5F26}, {0x5F27, 0x5F27}, {0x5F28, 0x5F28}, {0x5F29, 0x5F29}, {0x5F2A, 0x5F2A}, {0x5F2B, 0x5F2B}, + {0x5F2C, 0x5F2C}, {0x5F2D, 0x5F2D}, {0x5F2E, 0x5F2E}, {0x5F2F, 0x5F2F}, {0x5F30, 0x5F30}, {0x5F31, 0x5F31}, {0x5F32, 0x5F32}, + {0x5F33, 0x5F33}, {0x5F34, 0x5F34}, {0x5F35, 0x5F35}, {0x5F36, 0x5F36}, {0x5F37, 0x5F37}, {0x5F38, 0x5F38}, {0x5F39, 0x5F39}, + {0x5F3A, 0x5F3A}, {0x5F3B, 0x5F3B}, {0x5F3C, 0x5F3C}, {0x5F3D, 0x5F3D}, {0x5F3E, 0x5F3E}, {0x5F3F, 0x5F3F}, {0x5F40, 0x5F40}, + {0x5F41, 0x5F41}, {0x5F42, 0x5F42}, {0x5F43, 0x5F43}, {0x5F44, 0x5F44}, {0x5F45, 0x5F45}, {0x5F46, 0x5F46}, {0x5F47, 0x5F47}, + {0x5F48, 0x5F48}, {0x5F49, 0x5F49}, {0x5F4A, 0x5F4A}, {0x5F4B, 0x5F4B}, {0x5F4C, 0x5F4C}, {0x5F4D, 0x5F4D}, {0x5F4E, 0x5F4E}, + {0x5F4F, 0x5F4F}, {0x5F50, 0x5F50}, {0x5F51, 0x5F51}, {0x5F52, 0x5F52}, {0x5F53, 0x5F53}, {0x5F54, 0x5F54}, {0x5F55, 0x5F55}, + {0x5F56, 0x5F56}, {0x5F57, 0x5F57}, {0x5F58, 0x5F58}, {0x5F59, 0x5F59}, {0x5F5A, 0x5F5A}, {0x5F5B, 0x5F5B}, {0x5F5C, 0x5F5C}, + {0x5F5D, 0x5F5D}, {0x5F5E, 0x5F5E}, {0x5F5F, 0x5F5F}, {0x5F60, 0x5F60}, {0x5F61, 0x5F61}, {0x5F62, 0x5F62}, {0x5F63, 0x5F63}, + {0x5F64, 0x5F64}, {0x5F65, 0x5F65}, {0x5F66, 0x5F66}, {0x5F67, 0x5F67}, {0x5F68, 0x5F68}, {0x5F69, 0x5F69}, {0x5F6A, 0x5F6A}, + {0x5F6B, 0x5F6B}, {0x5F6C, 0x5F6C}, {0x5F6D, 0x5F6D}, {0x5F6E, 0x5F6E}, {0x5F6F, 0x5F6F}, {0x5F70, 0x5F70}, {0x5F71, 0x5F71}, + {0x5F72, 0x5F72}, {0x5F73, 0x5F73}, {0x5F74, 0x5F74}, {0x5F75, 0x5F75}, {0x5F76, 0x5F76}, {0x5F77, 0x5F77}, {0x5F78, 0x5F78}, + {0x5F79, 0x5F79}, {0x5F7A, 0x5F7A}, {0x5F7B, 0x5F7B}, {0x5F7C, 0x5F7C}, {0x5F7D, 0x5F7D}, {0x5F7E, 0x5F7E}, {0x5F7F, 0x5F7F}, + {0x5F80, 0x5F80}, {0x5F81, 0x5F81}, {0x5F82, 0x5F82}, {0x5F83, 0x5F83}, {0x5F84, 0x5F84}, {0x5F85, 0x5F85}, {0x5F86, 0x5F86}, + {0x5F87, 0x5F87}, {0x5F88, 0x5F88}, {0x5F89, 0x5F89}, {0x5F8A, 0x5F8A}, {0x5F8B, 0x5F8B}, {0x5F8C, 0x5F8C}, {0x5F8D, 0x5F8D}, + {0x5F8E, 0x5F8E}, {0x5F8F, 0x5F8F}, {0x5F90, 0x5F90}, {0x5F91, 0x5F91}, {0x5F92, 0x5F92}, {0x5F93, 0x5F93}, {0x5F94, 0x5F94}, + {0x5F95, 0x5F95}, {0x5F96, 0x5F96}, {0x5F97, 0x5F97}, {0x5F98, 0x5F98}, {0x5F99, 0x5F99}, {0x5F9A, 0x5F9A}, {0x5F9B, 0x5F9B}, + {0x5F9C, 0x5F9C}, {0x5F9D, 0x5F9D}, {0x5F9E, 0x5F9E}, {0x5F9F, 0x5F9F}, {0x5FA0, 0x5FA0}, {0x5FA1, 0x5FA1}, {0x5FA2, 0x5FA2}, + {0x5FA3, 0x5FA3}, {0x5FA4, 0x5FA4}, {0x5FA5, 0x5FA5}, {0x5FA6, 0x5FA6}, {0x5FA7, 0x5FA7}, {0x5FA8, 0x5FA8}, {0x5FA9, 0x5FA9}, + {0x5FAA, 0x5FAA}, {0x5FAB, 0x5FAB}, {0x5FAC, 0x5FAC}, {0x5FAD, 0x5FAD}, {0x5FAE, 0x5FAE}, {0x5FAF, 0x5FAF}, {0x5FB0, 0x5FB0}, + {0x5FB1, 0x5FB1}, {0x5FB2, 0x5FB2}, {0x5FB3, 0x5FB3}, {0x5FB4, 0x5FB4}, {0x5FB5, 0x5FB5}, {0x5FB6, 0x5FB6}, {0x5FB7, 0x5FB7}, + {0x5FB8, 0x5FB8}, {0x5FB9, 0x5FB9}, {0x5FBA, 0x5FBA}, {0x5FBB, 0x5FBB}, {0x5FBC, 0x5FBC}, {0x5FBD, 0x5FBD}, {0x5FBE, 0x5FBE}, + {0x5FBF, 0x5FBF}, {0x5FC0, 0x5FC0}, {0x5FC1, 0x5FC1}, {0x5FC2, 0x5FC2}, {0x5FC3, 0x5FC3}, {0x5FC4, 0x5FC4}, {0x5FC5, 0x5FC5}, + {0x5FC6, 0x5FC6}, {0x5FC7, 0x5FC7}, {0x5FC8, 0x5FC8}, {0x5FC9, 0x5FC9}, {0x5FCA, 0x5FCA}, {0x5FCB, 0x5FCB}, {0x5FCC, 0x5FCC}, + {0x5FCD, 0x5FCD}, {0x5FCE, 0x5FCE}, {0x5FCF, 0x5FCF}, {0x5FD0, 0x5FD0}, {0x5FD1, 0x5FD1}, {0x5FD2, 0x5FD2}, {0x5FD3, 0x5FD3}, + {0x5FD4, 0x5FD4}, {0x5FD5, 0x5FD5}, {0x5FD6, 0x5FD6}, {0x5FD7, 0x5FD7}, {0x5FD8, 0x5FD8}, {0x5FD9, 0x5FD9}, {0x5FDA, 0x5FDA}, + {0x5FDB, 0x5FDB}, {0x5FDC, 0x5FDC}, {0x5FDD, 0x5FDD}, {0x5FDE, 0x5FDE}, {0x5FDF, 0x5FDF}, {0x5FE0, 0x5FE0}, {0x5FE1, 0x5FE1}, + {0x5FE2, 0x5FE2}, {0x5FE3, 0x5FE3}, {0x5FE4, 0x5FE4}, {0x5FE5, 0x5FE5}, {0x5FE6, 0x5FE6}, {0x5FE7, 0x5FE7}, {0x5FE8, 0x5FE8}, + {0x5FE9, 0x5FE9}, {0x5FEA, 0x5FEA}, {0x5FEB, 0x5FEB}, {0x5FEC, 0x5FEC}, {0x5FED, 0x5FED}, {0x5FEE, 0x5FEE}, {0x5FEF, 0x5FEF}, + {0x5FF0, 0x5FF0}, {0x5FF1, 0x5FF1}, {0x5FF2, 0x5FF2}, {0x5FF3, 0x5FF3}, {0x5FF4, 0x5FF4}, {0x5FF5, 0x5FF5}, {0x5FF6, 0x5FF6}, + {0x5FF7, 0x5FF7}, {0x5FF8, 0x5FF8}, {0x5FF9, 0x5FF9}, {0x5FFA, 0x5FFA}, {0x5FFB, 0x5FFB}, {0x5FFC, 0x5FFC}, {0x5FFD, 0x5FFD}, + {0x5FFE, 0x5FFE}, {0x5FFF, 0x5FFF}, {0x6000, 0x6000}, {0x6001, 0x6001}, {0x6002, 0x6002}, {0x6003, 0x6003}, {0x6004, 0x6004}, + {0x6005, 0x6005}, {0x6006, 0x6006}, {0x6007, 0x6007}, {0x6008, 0x6008}, {0x6009, 0x6009}, {0x600A, 0x600A}, {0x600B, 0x600B}, + {0x600C, 0x600C}, {0x600D, 0x600D}, {0x600E, 0x600E}, {0x600F, 0x600F}, {0x6010, 0x6010}, {0x6011, 0x6011}, {0x6012, 0x6012}, + {0x6013, 0x6013}, {0x6014, 0x6014}, {0x6015, 0x6015}, {0x6016, 0x6016}, {0x6017, 0x6017}, {0x6018, 0x6018}, {0x6019, 0x6019}, + {0x601A, 0x601A}, {0x601B, 0x601B}, {0x601C, 0x601C}, {0x601D, 0x601D}, {0x601E, 0x601E}, {0x601F, 0x601F}, {0x6020, 0x6020}, + {0x6021, 0x6021}, {0x6022, 0x6022}, {0x6023, 0x6023}, {0x6024, 0x6024}, {0x6025, 0x6025}, {0x6026, 0x6026}, {0x6027, 0x6027}, + {0x6028, 0x6028}, {0x6029, 0x6029}, {0x602A, 0x602A}, {0x602B, 0x602B}, {0x602C, 0x602C}, {0x602D, 0x602D}, {0x602E, 0x602E}, + {0x602F, 0x602F}, {0x6030, 0x6030}, {0x6031, 0x6031}, {0x6032, 0x6032}, {0x6033, 0x6033}, {0x6034, 0x6034}, {0x6035, 0x6035}, + {0x6036, 0x6036}, {0x6037, 0x6037}, {0x6038, 0x6038}, {0x6039, 0x6039}, {0x603A, 0x603A}, {0x603B, 0x603B}, {0x603C, 0x603C}, + {0x603D, 0x603D}, {0x603E, 0x603E}, {0x603F, 0x603F}, {0x6040, 0x6040}, {0x6041, 0x6041}, {0x6042, 0x6042}, {0x6043, 0x6043}, + {0x6044, 0x6044}, {0x6045, 0x6045}, {0x6046, 0x6046}, {0x6047, 0x6047}, {0x6048, 0x6048}, {0x6049, 0x6049}, {0x604A, 0x604A}, + {0x604B, 0x604B}, {0x604C, 0x604C}, {0x604D, 0x604D}, {0x604E, 0x604E}, {0x604F, 0x604F}, {0x6050, 0x6050}, {0x6051, 0x6051}, + {0x6052, 0x6052}, {0x6053, 0x6053}, {0x6054, 0x6054}, {0x6055, 0x6055}, {0x6056, 0x6056}, {0x6057, 0x6057}, {0x6058, 0x6058}, + {0x6059, 0x6059}, {0x605A, 0x605A}, {0x605B, 0x605B}, {0x605C, 0x605C}, {0x605D, 0x605D}, {0x605E, 0x605E}, {0x605F, 0x605F}, + {0x6060, 0x6060}, {0x6061, 0x6061}, {0x6062, 0x6062}, {0x6063, 0x6063}, {0x6064, 0x6064}, {0x6065, 0x6065}, {0x6066, 0x6066}, + {0x6067, 0x6067}, {0x6068, 0x6068}, {0x6069, 0x6069}, {0x606A, 0x606A}, {0x606B, 0x606B}, {0x606C, 0x606C}, {0x606D, 0x606D}, + {0x606E, 0x606E}, {0x606F, 0x606F}, {0x6070, 0x6070}, {0x6071, 0x6071}, {0x6072, 0x6072}, {0x6073, 0x6073}, {0x6074, 0x6074}, + {0x6075, 0x6075}, {0x6076, 0x6076}, {0x6077, 0x6077}, {0x6078, 0x6078}, {0x6079, 0x6079}, {0x607A, 0x607A}, {0x607B, 0x607B}, + {0x607C, 0x607C}, {0x607D, 0x607D}, {0x607E, 0x607E}, {0x607F, 0x607F}, {0x6080, 0x6080}, {0x6081, 0x6081}, {0x6082, 0x6082}, + {0x6083, 0x6083}, {0x6084, 0x6084}, {0x6085, 0x6085}, {0x6086, 0x6086}, {0x6087, 0x6087}, {0x6088, 0x6088}, {0x6089, 0x6089}, + {0x608A, 0x608A}, {0x608B, 0x608B}, {0x608C, 0x608C}, {0x608D, 0x608D}, {0x608E, 0x608E}, {0x608F, 0x608F}, {0x6090, 0x6090}, + {0x6091, 0x6091}, {0x6092, 0x6092}, {0x6093, 0x6093}, {0x6094, 0x6094}, {0x6095, 0x6095}, {0x6096, 0x6096}, {0x6097, 0x6097}, + {0x6098, 0x6098}, {0x6099, 0x6099}, {0x609A, 0x609A}, {0x609B, 0x609B}, {0x609C, 0x609C}, {0x609D, 0x609D}, {0x609E, 0x609E}, + {0x609F, 0x609F}, {0x60A0, 0x60A0}, {0x60A1, 0x60A1}, {0x60A2, 0x60A2}, {0x60A3, 0x60A3}, {0x60A4, 0x60A4}, {0x60A5, 0x60A5}, + {0x60A6, 0x60A6}, {0x60A7, 0x60A7}, {0x60A8, 0x60A8}, {0x60A9, 0x60A9}, {0x60AA, 0x60AA}, {0x60AB, 0x60AB}, {0x60AC, 0x60AC}, + {0x60AD, 0x60AD}, {0x60AE, 0x60AE}, {0x60AF, 0x60AF}, {0x60B0, 0x60B0}, {0x60B1, 0x60B1}, {0x60B2, 0x60B2}, {0x60B3, 0x60B3}, + {0x60B4, 0x60B4}, {0x60B5, 0x60B5}, {0x60B6, 0x60B6}, {0x60B7, 0x60B7}, {0x60B8, 0x60B8}, {0x60B9, 0x60B9}, {0x60BA, 0x60BA}, + {0x60BB, 0x60BB}, {0x60BC, 0x60BC}, {0x60BD, 0x60BD}, {0x60BE, 0x60BE}, {0x60BF, 0x60BF}, {0x60C0, 0x60C0}, {0x60C1, 0x60C1}, + {0x60C2, 0x60C2}, {0x60C3, 0x60C3}, {0x60C4, 0x60C4}, {0x60C5, 0x60C5}, {0x60C6, 0x60C6}, {0x60C7, 0x60C7}, {0x60C8, 0x60C8}, + {0x60C9, 0x60C9}, {0x60CA, 0x60CA}, {0x60CB, 0x60CB}, {0x60CC, 0x60CC}, {0x60CD, 0x60CD}, {0x60CE, 0x60CE}, {0x60CF, 0x60CF}, + {0x60D0, 0x60D0}, {0x60D1, 0x60D1}, {0x60D2, 0x60D2}, {0x60D3, 0x60D3}, {0x60D4, 0x60D4}, {0x60D5, 0x60D5}, {0x60D6, 0x60D6}, + {0x60D7, 0x60D7}, {0x60D8, 0x60D8}, {0x60D9, 0x60D9}, {0x60DA, 0x60DA}, {0x60DB, 0x60DB}, {0x60DC, 0x60DC}, {0x60DD, 0x60DD}, + {0x60DE, 0x60DE}, {0x60DF, 0x60DF}, {0x60E0, 0x60E0}, {0x60E1, 0x60E1}, {0x60E2, 0x60E2}, {0x60E3, 0x60E3}, {0x60E4, 0x60E4}, + {0x60E5, 0x60E5}, {0x60E6, 0x60E6}, {0x60E7, 0x60E7}, {0x60E8, 0x60E8}, {0x60E9, 0x60E9}, {0x60EA, 0x60EA}, {0x60EB, 0x60EB}, + {0x60EC, 0x60EC}, {0x60ED, 0x60ED}, {0x60EE, 0x60EE}, {0x60EF, 0x60EF}, {0x60F0, 0x60F0}, {0x60F1, 0x60F1}, {0x60F2, 0x60F2}, + {0x60F3, 0x60F3}, {0x60F4, 0x60F4}, {0x60F5, 0x60F5}, {0x60F6, 0x60F6}, {0x60F7, 0x60F7}, {0x60F8, 0x60F8}, {0x60F9, 0x60F9}, + {0x60FA, 0x60FA}, {0x60FB, 0x60FB}, {0x60FC, 0x60FC}, {0x60FD, 0x60FD}, {0x60FE, 0x60FE}, {0x60FF, 0x60FF}, {0x6100, 0x6100}, + {0x6101, 0x6101}, {0x6102, 0x6102}, {0x6103, 0x6103}, {0x6104, 0x6104}, {0x6105, 0x6105}, {0x6106, 0x6106}, {0x6107, 0x6107}, + {0x6108, 0x6108}, {0x6109, 0x6109}, {0x610A, 0x610A}, {0x610B, 0x610B}, {0x610C, 0x610C}, {0x610D, 0x610D}, {0x610E, 0x610E}, + {0x610F, 0x610F}, {0x6110, 0x6110}, {0x6111, 0x6111}, {0x6112, 0x6112}, {0x6113, 0x6113}, {0x6114, 0x6114}, {0x6115, 0x6115}, + {0x6116, 0x6116}, {0x6117, 0x6117}, {0x6118, 0x6118}, {0x6119, 0x6119}, {0x611A, 0x611A}, {0x611B, 0x611B}, {0x611C, 0x611C}, + {0x611D, 0x611D}, {0x611E, 0x611E}, {0x611F, 0x611F}, {0x6120, 0x6120}, {0x6121, 0x6121}, {0x6122, 0x6122}, {0x6123, 0x6123}, + {0x6124, 0x6124}, {0x6125, 0x6125}, {0x6126, 0x6126}, {0x6127, 0x6127}, {0x6128, 0x6128}, {0x6129, 0x6129}, {0x612A, 0x612A}, + {0x612B, 0x612B}, {0x612C, 0x612C}, {0x612D, 0x612D}, {0x612E, 0x612E}, {0x612F, 0x612F}, {0x6130, 0x6130}, {0x6131, 0x6131}, + {0x6132, 0x6132}, {0x6133, 0x6133}, {0x6134, 0x6134}, {0x6135, 0x6135}, {0x6136, 0x6136}, {0x6137, 0x6137}, {0x6138, 0x6138}, + {0x6139, 0x6139}, {0x613A, 0x613A}, {0x613B, 0x613B}, {0x613C, 0x613C}, {0x613D, 0x613D}, {0x613E, 0x613E}, {0x613F, 0x613F}, + {0x6140, 0x6140}, {0x6141, 0x6141}, {0x6142, 0x6142}, {0x6143, 0x6143}, {0x6144, 0x6144}, {0x6145, 0x6145}, {0x6146, 0x6146}, + {0x6147, 0x6147}, {0x6148, 0x6148}, {0x6149, 0x6149}, {0x614A, 0x614A}, {0x614B, 0x614B}, {0x614C, 0x614C}, {0x614D, 0x614D}, + {0x614E, 0x614E}, {0x614F, 0x614F}, {0x6150, 0x6150}, {0x6151, 0x6151}, {0x6152, 0x6152}, {0x6153, 0x6153}, {0x6154, 0x6154}, + {0x6155, 0x6155}, {0x6156, 0x6156}, {0x6157, 0x6157}, {0x6158, 0x6158}, {0x6159, 0x6159}, {0x615A, 0x615A}, {0x615B, 0x615B}, + {0x615C, 0x615C}, {0x615D, 0x615D}, {0x615E, 0x615E}, {0x615F, 0x615F}, {0x6160, 0x6160}, {0x6161, 0x6161}, {0x6162, 0x6162}, + {0x6163, 0x6163}, {0x6164, 0x6164}, {0x6165, 0x6165}, {0x6166, 0x6166}, {0x6167, 0x6167}, {0x6168, 0x6168}, {0x6169, 0x6169}, + {0x616A, 0x616A}, {0x616B, 0x616B}, {0x616C, 0x616C}, {0x616D, 0x616D}, {0x616E, 0x616E}, {0x616F, 0x616F}, {0x6170, 0x6170}, + {0x6171, 0x6171}, {0x6172, 0x6172}, {0x6173, 0x6173}, {0x6174, 0x6174}, {0x6175, 0x6175}, {0x6176, 0x6176}, {0x6177, 0x6177}, + {0x6178, 0x6178}, {0x6179, 0x6179}, {0x617A, 0x617A}, {0x617B, 0x617B}, {0x617C, 0x617C}, {0x617D, 0x617D}, {0x617E, 0x617E}, + {0x617F, 0x617F}, {0x6180, 0x6180}, {0x6181, 0x6181}, {0x6182, 0x6182}, {0x6183, 0x6183}, {0x6184, 0x6184}, {0x6185, 0x6185}, + {0x6186, 0x6186}, {0x6187, 0x6187}, {0x6188, 0x6188}, {0x6189, 0x6189}, {0x618A, 0x618A}, {0x618B, 0x618B}, {0x618C, 0x618C}, + {0x618D, 0x618D}, {0x618E, 0x618E}, {0x618F, 0x618F}, {0x6190, 0x6190}, {0x6191, 0x6191}, {0x6192, 0x6192}, {0x6193, 0x6193}, + {0x6194, 0x6194}, {0x6195, 0x6195}, {0x6196, 0x6196}, {0x6197, 0x6197}, {0x6198, 0x6198}, {0x6199, 0x6199}, {0x619A, 0x619A}, + {0x619B, 0x619B}, {0x619C, 0x619C}, {0x619D, 0x619D}, {0x619E, 0x619E}, {0x619F, 0x619F}, {0x61A0, 0x61A0}, {0x61A1, 0x61A1}, + {0x61A2, 0x61A2}, {0x61A3, 0x61A3}, {0x61A4, 0x61A4}, {0x61A5, 0x61A5}, {0x61A6, 0x61A6}, {0x61A7, 0x61A7}, {0x61A8, 0x61A8}, + {0x61A9, 0x61A9}, {0x61AA, 0x61AA}, {0x61AB, 0x61AB}, {0x61AC, 0x61AC}, {0x61AD, 0x61AD}, {0x61AE, 0x61AE}, {0x61AF, 0x61AF}, + {0x61B0, 0x61B0}, {0x61B1, 0x61B1}, {0x61B2, 0x61B2}, {0x61B3, 0x61B3}, {0x61B4, 0x61B4}, {0x61B5, 0x61B5}, {0x61B6, 0x61B6}, + {0x61B7, 0x61B7}, {0x61B8, 0x61B8}, {0x61B9, 0x61B9}, {0x61BA, 0x61BA}, {0x61BB, 0x61BB}, {0x61BC, 0x61BC}, {0x61BD, 0x61BD}, + {0x61BE, 0x61BE}, {0x61BF, 0x61BF}, {0x61C0, 0x61C0}, {0x61C1, 0x61C1}, {0x61C2, 0x61C2}, {0x61C3, 0x61C3}, {0x61C4, 0x61C4}, + {0x61C5, 0x61C5}, {0x61C6, 0x61C6}, {0x61C7, 0x61C7}, {0x61C8, 0x61C8}, {0x61C9, 0x61C9}, {0x61CA, 0x61CA}, {0x61CB, 0x61CB}, + {0x61CC, 0x61CC}, {0x61CD, 0x61CD}, {0x61CE, 0x61CE}, {0x61CF, 0x61CF}, {0x61D0, 0x61D0}, {0x61D1, 0x61D1}, {0x61D2, 0x61D2}, + {0x61D3, 0x61D3}, {0x61D4, 0x61D4}, {0x61D5, 0x61D5}, {0x61D6, 0x61D6}, {0x61D7, 0x61D7}, {0x61D8, 0x61D8}, {0x61D9, 0x61D9}, + {0x61DA, 0x61DA}, {0x61DB, 0x61DB}, {0x61DC, 0x61DC}, {0x61DD, 0x61DD}, {0x61DE, 0x61DE}, {0x61DF, 0x61DF}, {0x61E0, 0x61E0}, + {0x61E1, 0x61E1}, {0x61E2, 0x61E2}, {0x61E3, 0x61E3}, {0x61E4, 0x61E4}, {0x61E5, 0x61E5}, {0x61E6, 0x61E6}, {0x61E7, 0x61E7}, + {0x61E8, 0x61E8}, {0x61E9, 0x61E9}, {0x61EA, 0x61EA}, {0x61EB, 0x61EB}, {0x61EC, 0x61EC}, {0x61ED, 0x61ED}, {0x61EE, 0x61EE}, + {0x61EF, 0x61EF}, {0x61F0, 0x61F0}, {0x61F1, 0x61F1}, {0x61F2, 0x61F2}, {0x61F3, 0x61F3}, {0x61F4, 0x61F4}, {0x61F5, 0x61F5}, + {0x61F6, 0x61F6}, {0x61F7, 0x61F7}, {0x61F8, 0x61F8}, {0x61F9, 0x61F9}, {0x61FA, 0x61FA}, {0x61FB, 0x61FB}, {0x61FC, 0x61FC}, + {0x61FD, 0x61FD}, {0x61FE, 0x61FE}, {0x61FF, 0x61FF}, {0x6200, 0x6200}, {0x6201, 0x6201}, {0x6202, 0x6202}, {0x6203, 0x6203}, + {0x6204, 0x6204}, {0x6205, 0x6205}, {0x6206, 0x6206}, {0x6207, 0x6207}, {0x6208, 0x6208}, {0x6209, 0x6209}, {0x620A, 0x620A}, + {0x620B, 0x620B}, {0x620C, 0x620C}, {0x620D, 0x620D}, {0x620E, 0x620E}, {0x620F, 0x620F}, {0x6210, 0x6210}, {0x6211, 0x6211}, + {0x6212, 0x6212}, {0x6213, 0x6213}, {0x6214, 0x6214}, {0x6215, 0x6215}, {0x6216, 0x6216}, {0x6217, 0x6217}, {0x6218, 0x6218}, + {0x6219, 0x6219}, {0x621A, 0x621A}, {0x621B, 0x621B}, {0x621C, 0x621C}, {0x621D, 0x621D}, {0x621E, 0x621E}, {0x621F, 0x621F}, + {0x6220, 0x6220}, {0x6221, 0x6221}, {0x6222, 0x6222}, {0x6223, 0x6223}, {0x6224, 0x6224}, {0x6225, 0x6225}, {0x6226, 0x6226}, + {0x6227, 0x6227}, {0x6228, 0x6228}, {0x6229, 0x6229}, {0x622A, 0x622A}, {0x622B, 0x622B}, {0x622C, 0x622C}, {0x622D, 0x622D}, + {0x622E, 0x622E}, {0x622F, 0x622F}, {0x6230, 0x6230}, {0x6231, 0x6231}, {0x6232, 0x6232}, {0x6233, 0x6233}, {0x6234, 0x6234}, + {0x6235, 0x6235}, {0x6236, 0x6236}, {0x6237, 0x6237}, {0x6238, 0x6238}, {0x6239, 0x6239}, {0x623A, 0x623A}, {0x623B, 0x623B}, + {0x623C, 0x623C}, {0x623D, 0x623D}, {0x623E, 0x623E}, {0x623F, 0x623F}, {0x6240, 0x6240}, {0x6241, 0x6241}, {0x6242, 0x6242}, + {0x6243, 0x6243}, {0x6244, 0x6244}, {0x6245, 0x6245}, {0x6246, 0x6246}, {0x6247, 0x6247}, {0x6248, 0x6248}, {0x6249, 0x6249}, + {0x624A, 0x624A}, {0x624B, 0x624B}, {0x624C, 0x624C}, {0x624D, 0x624D}, {0x624E, 0x624E}, {0x624F, 0x624F}, {0x6250, 0x6250}, + {0x6251, 0x6251}, {0x6252, 0x6252}, {0x6253, 0x6253}, {0x6254, 0x6254}, {0x6255, 0x6255}, {0x6256, 0x6256}, {0x6257, 0x6257}, + {0x6258, 0x6258}, {0x6259, 0x6259}, {0x625A, 0x625A}, {0x625B, 0x625B}, {0x625C, 0x625C}, {0x625D, 0x625D}, {0x625E, 0x625E}, + {0x625F, 0x625F}, {0x6260, 0x6260}, {0x6261, 0x6261}, {0x6262, 0x6262}, {0x6263, 0x6263}, {0x6264, 0x6264}, {0x6265, 0x6265}, + {0x6266, 0x6266}, {0x6267, 0x6267}, {0x6268, 0x6268}, {0x6269, 0x6269}, {0x626A, 0x626A}, {0x626B, 0x626B}, {0x626C, 0x626C}, + {0x626D, 0x626D}, {0x626E, 0x626E}, {0x626F, 0x626F}, {0x6270, 0x6270}, {0x6271, 0x6271}, {0x6272, 0x6272}, {0x6273, 0x6273}, + {0x6274, 0x6274}, {0x6275, 0x6275}, {0x6276, 0x6276}, {0x6277, 0x6277}, {0x6278, 0x6278}, {0x6279, 0x6279}, {0x627A, 0x627A}, + {0x627B, 0x627B}, {0x627C, 0x627C}, {0x627D, 0x627D}, {0x627E, 0x627E}, {0x627F, 0x627F}, {0x6280, 0x6280}, {0x6281, 0x6281}, + {0x6282, 0x6282}, {0x6283, 0x6283}, {0x6284, 0x6284}, {0x6285, 0x6285}, {0x6286, 0x6286}, {0x6287, 0x6287}, {0x6288, 0x6288}, + {0x6289, 0x6289}, {0x628A, 0x628A}, {0x628B, 0x628B}, {0x628C, 0x628C}, {0x628D, 0x628D}, {0x628E, 0x628E}, {0x628F, 0x628F}, + {0x6290, 0x6290}, {0x6291, 0x6291}, {0x6292, 0x6292}, {0x6293, 0x6293}, {0x6294, 0x6294}, {0x6295, 0x6295}, {0x6296, 0x6296}, + {0x6297, 0x6297}, {0x6298, 0x6298}, {0x6299, 0x6299}, {0x629A, 0x629A}, {0x629B, 0x629B}, {0x629C, 0x629C}, {0x629D, 0x629D}, + {0x629E, 0x629E}, {0x629F, 0x629F}, {0x62A0, 0x62A0}, {0x62A1, 0x62A1}, {0x62A2, 0x62A2}, {0x62A3, 0x62A3}, {0x62A4, 0x62A4}, + {0x62A5, 0x62A5}, {0x62A6, 0x62A6}, {0x62A7, 0x62A7}, {0x62A8, 0x62A8}, {0x62A9, 0x62A9}, {0x62AA, 0x62AA}, {0x62AB, 0x62AB}, + {0x62AC, 0x62AC}, {0x62AD, 0x62AD}, {0x62AE, 0x62AE}, {0x62AF, 0x62AF}, {0x62B0, 0x62B0}, {0x62B1, 0x62B1}, {0x62B2, 0x62B2}, + {0x62B3, 0x62B3}, {0x62B4, 0x62B4}, {0x62B5, 0x62B5}, {0x62B6, 0x62B6}, {0x62B7, 0x62B7}, {0x62B8, 0x62B8}, {0x62B9, 0x62B9}, + {0x62BA, 0x62BA}, {0x62BB, 0x62BB}, {0x62BC, 0x62BC}, {0x62BD, 0x62BD}, {0x62BE, 0x62BE}, {0x62BF, 0x62BF}, {0x62C0, 0x62C0}, + {0x62C1, 0x62C1}, {0x62C2, 0x62C2}, {0x62C3, 0x62C3}, {0x62C4, 0x62C4}, {0x62C5, 0x62C5}, {0x62C6, 0x62C6}, {0x62C7, 0x62C7}, + {0x62C8, 0x62C8}, {0x62C9, 0x62C9}, {0x62CA, 0x62CA}, {0x62CB, 0x62CB}, {0x62CC, 0x62CC}, {0x62CD, 0x62CD}, {0x62CE, 0x62CE}, + {0x62CF, 0x62CF}, {0x62D0, 0x62D0}, {0x62D1, 0x62D1}, {0x62D2, 0x62D2}, {0x62D3, 0x62D3}, {0x62D4, 0x62D4}, {0x62D5, 0x62D5}, + {0x62D6, 0x62D6}, {0x62D7, 0x62D7}, {0x62D8, 0x62D8}, {0x62D9, 0x62D9}, {0x62DA, 0x62DA}, {0x62DB, 0x62DB}, {0x62DC, 0x62DC}, + {0x62DD, 0x62DD}, {0x62DE, 0x62DE}, {0x62DF, 0x62DF}, {0x62E0, 0x62E0}, {0x62E1, 0x62E1}, {0x62E2, 0x62E2}, {0x62E3, 0x62E3}, + {0x62E4, 0x62E4}, {0x62E5, 0x62E5}, {0x62E6, 0x62E6}, {0x62E7, 0x62E7}, {0x62E8, 0x62E8}, {0x62E9, 0x62E9}, {0x62EA, 0x62EA}, + {0x62EB, 0x62EB}, {0x62EC, 0x62EC}, {0x62ED, 0x62ED}, {0x62EE, 0x62EE}, {0x62EF, 0x62EF}, {0x62F0, 0x62F0}, {0x62F1, 0x62F1}, + {0x62F2, 0x62F2}, {0x62F3, 0x62F3}, {0x62F4, 0x62F4}, {0x62F5, 0x62F5}, {0x62F6, 0x62F6}, {0x62F7, 0x62F7}, {0x62F8, 0x62F8}, + {0x62F9, 0x62F9}, {0x62FA, 0x62FA}, {0x62FB, 0x62FB}, {0x62FC, 0x62FC}, {0x62FD, 0x62FD}, {0x62FE, 0x62FE}, {0x62FF, 0x62FF}, + {0x6300, 0x6300}, {0x6301, 0x6301}, {0x6302, 0x6302}, {0x6303, 0x6303}, {0x6304, 0x6304}, {0x6305, 0x6305}, {0x6306, 0x6306}, + {0x6307, 0x6307}, {0x6308, 0x6308}, {0x6309, 0x6309}, {0x630A, 0x630A}, {0x630B, 0x630B}, {0x630C, 0x630C}, {0x630D, 0x630D}, + {0x630E, 0x630E}, {0x630F, 0x630F}, {0x6310, 0x6310}, {0x6311, 0x6311}, {0x6312, 0x6312}, {0x6313, 0x6313}, {0x6314, 0x6314}, + {0x6315, 0x6315}, {0x6316, 0x6316}, {0x6317, 0x6317}, {0x6318, 0x6318}, {0x6319, 0x6319}, {0x631A, 0x631A}, {0x631B, 0x631B}, + {0x631C, 0x631C}, {0x631D, 0x631D}, {0x631E, 0x631E}, {0x631F, 0x631F}, {0x6320, 0x6320}, {0x6321, 0x6321}, {0x6322, 0x6322}, + {0x6323, 0x6323}, {0x6324, 0x6324}, {0x6325, 0x6325}, {0x6326, 0x6326}, {0x6327, 0x6327}, {0x6328, 0x6328}, {0x6329, 0x6329}, + {0x632A, 0x632A}, {0x632B, 0x632B}, {0x632C, 0x632C}, {0x632D, 0x632D}, {0x632E, 0x632E}, {0x632F, 0x632F}, {0x6330, 0x6330}, + {0x6331, 0x6331}, {0x6332, 0x6332}, {0x6333, 0x6333}, {0x6334, 0x6334}, {0x6335, 0x6335}, {0x6336, 0x6336}, {0x6337, 0x6337}, + {0x6338, 0x6338}, {0x6339, 0x6339}, {0x633A, 0x633A}, {0x633B, 0x633B}, {0x633C, 0x633C}, {0x633D, 0x633D}, {0x633E, 0x633E}, + {0x633F, 0x633F}, {0x6340, 0x6340}, {0x6341, 0x6341}, {0x6342, 0x6342}, {0x6343, 0x6343}, {0x6344, 0x6344}, {0x6345, 0x6345}, + {0x6346, 0x6346}, {0x6347, 0x6347}, {0x6348, 0x6348}, {0x6349, 0x6349}, {0x634A, 0x634A}, {0x634B, 0x634B}, {0x634C, 0x634C}, + {0x634D, 0x634D}, {0x634E, 0x634E}, {0x634F, 0x634F}, {0x6350, 0x6350}, {0x6351, 0x6351}, {0x6352, 0x6352}, {0x6353, 0x6353}, + {0x6354, 0x6354}, {0x6355, 0x6355}, {0x6356, 0x6356}, {0x6357, 0x6357}, {0x6358, 0x6358}, {0x6359, 0x6359}, {0x635A, 0x635A}, + {0x635B, 0x635B}, {0x635C, 0x635C}, {0x635D, 0x635D}, {0x635E, 0x635E}, {0x635F, 0x635F}, {0x6360, 0x6360}, {0x6361, 0x6361}, + {0x6362, 0x6362}, {0x6363, 0x6363}, {0x6364, 0x6364}, {0x6365, 0x6365}, {0x6366, 0x6366}, {0x6367, 0x6367}, {0x6368, 0x6368}, + {0x6369, 0x6369}, {0x636A, 0x636A}, {0x636B, 0x636B}, {0x636C, 0x636C}, {0x636D, 0x636D}, {0x636E, 0x636E}, {0x636F, 0x636F}, + {0x6370, 0x6370}, {0x6371, 0x6371}, {0x6372, 0x6372}, {0x6373, 0x6373}, {0x6374, 0x6374}, {0x6375, 0x6375}, {0x6376, 0x6376}, + {0x6377, 0x6377}, {0x6378, 0x6378}, {0x6379, 0x6379}, {0x637A, 0x637A}, {0x637B, 0x637B}, {0x637C, 0x637C}, {0x637D, 0x637D}, + {0x637E, 0x637E}, {0x637F, 0x637F}, {0x6380, 0x6380}, {0x6381, 0x6381}, {0x6382, 0x6382}, {0x6383, 0x6383}, {0x6384, 0x6384}, + {0x6385, 0x6385}, {0x6386, 0x6386}, {0x6387, 0x6387}, {0x6388, 0x6388}, {0x6389, 0x6389}, {0x638A, 0x638A}, {0x638B, 0x638B}, + {0x638C, 0x638C}, {0x638D, 0x638D}, {0x638E, 0x638E}, {0x638F, 0x638F}, {0x6390, 0x6390}, {0x6391, 0x6391}, {0x6392, 0x6392}, + {0x6393, 0x6393}, {0x6394, 0x6394}, {0x6395, 0x6395}, {0x6396, 0x6396}, {0x6397, 0x6397}, {0x6398, 0x6398}, {0x6399, 0x6399}, + {0x639A, 0x639A}, {0x639B, 0x639B}, {0x639C, 0x639C}, {0x639D, 0x639D}, {0x639E, 0x639E}, {0x639F, 0x639F}, {0x63A0, 0x63A0}, + {0x63A1, 0x63A1}, {0x63A2, 0x63A2}, {0x63A3, 0x63A3}, {0x63A4, 0x63A4}, {0x63A5, 0x63A5}, {0x63A6, 0x63A6}, {0x63A7, 0x63A7}, + {0x63A8, 0x63A8}, {0x63A9, 0x63A9}, {0x63AA, 0x63AA}, {0x63AB, 0x63AB}, {0x63AC, 0x63AC}, {0x63AD, 0x63AD}, {0x63AE, 0x63AE}, + {0x63AF, 0x63AF}, {0x63B0, 0x63B0}, {0x63B1, 0x63B1}, {0x63B2, 0x63B2}, {0x63B3, 0x63B3}, {0x63B4, 0x63B4}, {0x63B5, 0x63B5}, + {0x63B6, 0x63B6}, {0x63B7, 0x63B7}, {0x63B8, 0x63B8}, {0x63B9, 0x63B9}, {0x63BA, 0x63BA}, {0x63BB, 0x63BB}, {0x63BC, 0x63BC}, + {0x63BD, 0x63BD}, {0x63BE, 0x63BE}, {0x63BF, 0x63BF}, {0x63C0, 0x63C0}, {0x63C1, 0x63C1}, {0x63C2, 0x63C2}, {0x63C3, 0x63C3}, + {0x63C4, 0x63C4}, {0x63C5, 0x63C5}, {0x63C6, 0x63C6}, {0x63C7, 0x63C7}, {0x63C8, 0x63C8}, {0x63C9, 0x63C9}, {0x63CA, 0x63CA}, + {0x63CB, 0x63CB}, {0x63CC, 0x63CC}, {0x63CD, 0x63CD}, {0x63CE, 0x63CE}, {0x63CF, 0x63CF}, {0x63D0, 0x63D0}, {0x63D1, 0x63D1}, + {0x63D2, 0x63D2}, {0x63D3, 0x63D3}, {0x63D4, 0x63D4}, {0x63D5, 0x63D5}, {0x63D6, 0x63D6}, {0x63D7, 0x63D7}, {0x63D8, 0x63D8}, + {0x63D9, 0x63D9}, {0x63DA, 0x63DA}, {0x63DB, 0x63DB}, {0x63DC, 0x63DC}, {0x63DD, 0x63DD}, {0x63DE, 0x63DE}, {0x63DF, 0x63DF}, + {0x63E0, 0x63E0}, {0x63E1, 0x63E1}, {0x63E2, 0x63E2}, {0x63E3, 0x63E3}, {0x63E4, 0x63E4}, {0x63E5, 0x63E5}, {0x63E6, 0x63E6}, + {0x63E7, 0x63E7}, {0x63E8, 0x63E8}, {0x63E9, 0x63E9}, {0x63EA, 0x63EA}, {0x63EB, 0x63EB}, {0x63EC, 0x63EC}, {0x63ED, 0x63ED}, + {0x63EE, 0x63EE}, {0x63EF, 0x63EF}, {0x63F0, 0x63F0}, {0x63F1, 0x63F1}, {0x63F2, 0x63F2}, {0x63F3, 0x63F3}, {0x63F4, 0x63F4}, + {0x63F5, 0x63F5}, {0x63F6, 0x63F6}, {0x63F7, 0x63F7}, {0x63F8, 0x63F8}, {0x63F9, 0x63F9}, {0x63FA, 0x63FA}, {0x63FB, 0x63FB}, + {0x63FC, 0x63FC}, {0x63FD, 0x63FD}, {0x63FE, 0x63FE}, {0x63FF, 0x63FF}, {0x6400, 0x6400}, {0x6401, 0x6401}, {0x6402, 0x6402}, + {0x6403, 0x6403}, {0x6404, 0x6404}, {0x6405, 0x6405}, {0x6406, 0x6406}, {0x6407, 0x6407}, {0x6408, 0x6408}, {0x6409, 0x6409}, + {0x640A, 0x640A}, {0x640B, 0x640B}, {0x640C, 0x640C}, {0x640D, 0x640D}, {0x640E, 0x640E}, {0x640F, 0x640F}, {0x6410, 0x6410}, + {0x6411, 0x6411}, {0x6412, 0x6412}, {0x6413, 0x6413}, {0x6414, 0x6414}, {0x6415, 0x6415}, {0x6416, 0x6416}, {0x6417, 0x6417}, + {0x6418, 0x6418}, {0x6419, 0x6419}, {0x641A, 0x641A}, {0x641B, 0x641B}, {0x641C, 0x641C}, {0x641D, 0x641D}, {0x641E, 0x641E}, + {0x641F, 0x641F}, {0x6420, 0x6420}, {0x6421, 0x6421}, {0x6422, 0x6422}, {0x6423, 0x6423}, {0x6424, 0x6424}, {0x6425, 0x6425}, + {0x6426, 0x6426}, {0x6427, 0x6427}, {0x6428, 0x6428}, {0x6429, 0x6429}, {0x642A, 0x642A}, {0x642B, 0x642B}, {0x642C, 0x642C}, + {0x642D, 0x642D}, {0x642E, 0x642E}, {0x642F, 0x642F}, {0x6430, 0x6430}, {0x6431, 0x6431}, {0x6432, 0x6432}, {0x6433, 0x6433}, + {0x6434, 0x6434}, {0x6435, 0x6435}, {0x6436, 0x6436}, {0x6437, 0x6437}, {0x6438, 0x6438}, {0x6439, 0x6439}, {0x643A, 0x643A}, + {0x643B, 0x643B}, {0x643C, 0x643C}, {0x643D, 0x643D}, {0x643E, 0x643E}, {0x643F, 0x643F}, {0x6440, 0x6440}, {0x6441, 0x6441}, + {0x6442, 0x6442}, {0x6443, 0x6443}, {0x6444, 0x6444}, {0x6445, 0x6445}, {0x6446, 0x6446}, {0x6447, 0x6447}, {0x6448, 0x6448}, + {0x6449, 0x6449}, {0x644A, 0x644A}, {0x644B, 0x644B}, {0x644C, 0x644C}, {0x644D, 0x644D}, {0x644E, 0x644E}, {0x644F, 0x644F}, + {0x6450, 0x6450}, {0x6451, 0x6451}, {0x6452, 0x6452}, {0x6453, 0x6453}, {0x6454, 0x6454}, {0x6455, 0x6455}, {0x6456, 0x6456}, + {0x6457, 0x6457}, {0x6458, 0x6458}, {0x6459, 0x6459}, {0x645A, 0x645A}, {0x645B, 0x645B}, {0x645C, 0x645C}, {0x645D, 0x645D}, + {0x645E, 0x645E}, {0x645F, 0x645F}, {0x6460, 0x6460}, {0x6461, 0x6461}, {0x6462, 0x6462}, {0x6463, 0x6463}, {0x6464, 0x6464}, + {0x6465, 0x6465}, {0x6466, 0x6466}, {0x6467, 0x6467}, {0x6468, 0x6468}, {0x6469, 0x6469}, {0x646A, 0x646A}, {0x646B, 0x646B}, + {0x646C, 0x646C}, {0x646D, 0x646D}, {0x646E, 0x646E}, {0x646F, 0x646F}, {0x6470, 0x6470}, {0x6471, 0x6471}, {0x6472, 0x6472}, + {0x6473, 0x6473}, {0x6474, 0x6474}, {0x6475, 0x6475}, {0x6476, 0x6476}, {0x6477, 0x6477}, {0x6478, 0x6478}, {0x6479, 0x6479}, + {0x647A, 0x647A}, {0x647B, 0x647B}, {0x647C, 0x647C}, {0x647D, 0x647D}, {0x647E, 0x647E}, {0x647F, 0x647F}, {0x6480, 0x6480}, + {0x6481, 0x6481}, {0x6482, 0x6482}, {0x6483, 0x6483}, {0x6484, 0x6484}, {0x6485, 0x6485}, {0x6486, 0x6486}, {0x6487, 0x6487}, + {0x6488, 0x6488}, {0x6489, 0x6489}, {0x648A, 0x648A}, {0x648B, 0x648B}, {0x648C, 0x648C}, {0x648D, 0x648D}, {0x648E, 0x648E}, + {0x648F, 0x648F}, {0x6490, 0x6490}, {0x6491, 0x6491}, {0x6492, 0x6492}, {0x6493, 0x6493}, {0x6494, 0x6494}, {0x6495, 0x6495}, + {0x6496, 0x6496}, {0x6497, 0x6497}, {0x6498, 0x6498}, {0x6499, 0x6499}, {0x649A, 0x649A}, {0x649B, 0x649B}, {0x649C, 0x649C}, + {0x649D, 0x649D}, {0x649E, 0x649E}, {0x649F, 0x649F}, {0x64A0, 0x64A0}, {0x64A1, 0x64A1}, {0x64A2, 0x64A2}, {0x64A3, 0x64A3}, + {0x64A4, 0x64A4}, {0x64A5, 0x64A5}, {0x64A6, 0x64A6}, {0x64A7, 0x64A7}, {0x64A8, 0x64A8}, {0x64A9, 0x64A9}, {0x64AA, 0x64AA}, + {0x64AB, 0x64AB}, {0x64AC, 0x64AC}, {0x64AD, 0x64AD}, {0x64AE, 0x64AE}, {0x64AF, 0x64AF}, {0x64B0, 0x64B0}, {0x64B1, 0x64B1}, + {0x64B2, 0x64B2}, {0x64B3, 0x64B3}, {0x64B4, 0x64B4}, {0x64B5, 0x64B5}, {0x64B6, 0x64B6}, {0x64B7, 0x64B7}, {0x64B8, 0x64B8}, + {0x64B9, 0x64B9}, {0x64BA, 0x64BA}, {0x64BB, 0x64BB}, {0x64BC, 0x64BC}, {0x64BD, 0x64BD}, {0x64BE, 0x64BE}, {0x64BF, 0x64BF}, + {0x64C0, 0x64C0}, {0x64C1, 0x64C1}, {0x64C2, 0x64C2}, {0x64C3, 0x64C3}, {0x64C4, 0x64C4}, {0x64C5, 0x64C5}, {0x64C6, 0x64C6}, + {0x64C7, 0x64C7}, {0x64C8, 0x64C8}, {0x64C9, 0x64C9}, {0x64CA, 0x64CA}, {0x64CB, 0x64CB}, {0x64CC, 0x64CC}, {0x64CD, 0x64CD}, + {0x64CE, 0x64CE}, {0x64CF, 0x64CF}, {0x64D0, 0x64D0}, {0x64D1, 0x64D1}, {0x64D2, 0x64D2}, {0x64D3, 0x64D3}, {0x64D4, 0x64D4}, + {0x64D5, 0x64D5}, {0x64D6, 0x64D6}, {0x64D7, 0x64D7}, {0x64D8, 0x64D8}, {0x64D9, 0x64D9}, {0x64DA, 0x64DA}, {0x64DB, 0x64DB}, + {0x64DC, 0x64DC}, {0x64DD, 0x64DD}, {0x64DE, 0x64DE}, {0x64DF, 0x64DF}, {0x64E0, 0x64E0}, {0x64E1, 0x64E1}, {0x64E2, 0x64E2}, + {0x64E3, 0x64E3}, {0x64E4, 0x64E4}, {0x64E5, 0x64E5}, {0x64E6, 0x64E6}, {0x64E7, 0x64E7}, {0x64E8, 0x64E8}, {0x64E9, 0x64E9}, + {0x64EA, 0x64EA}, {0x64EB, 0x64EB}, {0x64EC, 0x64EC}, {0x64ED, 0x64ED}, {0x64EE, 0x64EE}, {0x64EF, 0x64EF}, {0x64F0, 0x64F0}, + {0x64F1, 0x64F1}, {0x64F2, 0x64F2}, {0x64F3, 0x64F3}, {0x64F4, 0x64F4}, {0x64F5, 0x64F5}, {0x64F6, 0x64F6}, {0x64F7, 0x64F7}, + {0x64F8, 0x64F8}, {0x64F9, 0x64F9}, {0x64FA, 0x64FA}, {0x64FB, 0x64FB}, {0x64FC, 0x64FC}, {0x64FD, 0x64FD}, {0x64FE, 0x64FE}, + {0x64FF, 0x64FF}, {0x6500, 0x6500}, {0x6501, 0x6501}, {0x6502, 0x6502}, {0x6503, 0x6503}, {0x6504, 0x6504}, {0x6505, 0x6505}, + {0x6506, 0x6506}, {0x6507, 0x6507}, {0x6508, 0x6508}, {0x6509, 0x6509}, {0x650A, 0x650A}, {0x650B, 0x650B}, {0x650C, 0x650C}, + {0x650D, 0x650D}, {0x650E, 0x650E}, {0x650F, 0x650F}, {0x6510, 0x6510}, {0x6511, 0x6511}, {0x6512, 0x6512}, {0x6513, 0x6513}, + {0x6514, 0x6514}, {0x6515, 0x6515}, {0x6516, 0x6516}, {0x6517, 0x6517}, {0x6518, 0x6518}, {0x6519, 0x6519}, {0x651A, 0x651A}, + {0x651B, 0x651B}, {0x651C, 0x651C}, {0x651D, 0x651D}, {0x651E, 0x651E}, {0x651F, 0x651F}, {0x6520, 0x6520}, {0x6521, 0x6521}, + {0x6522, 0x6522}, {0x6523, 0x6523}, {0x6524, 0x6524}, {0x6525, 0x6525}, {0x6526, 0x6526}, {0x6527, 0x6527}, {0x6528, 0x6528}, + {0x6529, 0x6529}, {0x652A, 0x652A}, {0x652B, 0x652B}, {0x652C, 0x652C}, {0x652D, 0x652D}, {0x652E, 0x652E}, {0x652F, 0x652F}, + {0x6530, 0x6530}, {0x6531, 0x6531}, {0x6532, 0x6532}, {0x6533, 0x6533}, {0x6534, 0x6534}, {0x6535, 0x6535}, {0x6536, 0x6536}, + {0x6537, 0x6537}, {0x6538, 0x6538}, {0x6539, 0x6539}, {0x653A, 0x653A}, {0x653B, 0x653B}, {0x653C, 0x653C}, {0x653D, 0x653D}, + {0x653E, 0x653E}, {0x653F, 0x653F}, {0x6540, 0x6540}, {0x6541, 0x6541}, {0x6542, 0x6542}, {0x6543, 0x6543}, {0x6544, 0x6544}, + {0x6545, 0x6545}, {0x6546, 0x6546}, {0x6547, 0x6547}, {0x6548, 0x6548}, {0x6549, 0x6549}, {0x654A, 0x654A}, {0x654B, 0x654B}, + {0x654C, 0x654C}, {0x654D, 0x654D}, {0x654E, 0x654E}, {0x654F, 0x654F}, {0x6550, 0x6550}, {0x6551, 0x6551}, {0x6552, 0x6552}, + {0x6553, 0x6553}, {0x6554, 0x6554}, {0x6555, 0x6555}, {0x6556, 0x6556}, {0x6557, 0x6557}, {0x6558, 0x6558}, {0x6559, 0x6559}, + {0x655A, 0x655A}, {0x655B, 0x655B}, {0x655C, 0x655C}, {0x655D, 0x655D}, {0x655E, 0x655E}, {0x655F, 0x655F}, {0x6560, 0x6560}, + {0x6561, 0x6561}, {0x6562, 0x6562}, {0x6563, 0x6563}, {0x6564, 0x6564}, {0x6565, 0x6565}, {0x6566, 0x6566}, {0x6567, 0x6567}, + {0x6568, 0x6568}, {0x6569, 0x6569}, {0x656A, 0x656A}, {0x656B, 0x656B}, {0x656C, 0x656C}, {0x656D, 0x656D}, {0x656E, 0x656E}, + {0x656F, 0x656F}, {0x6570, 0x6570}, {0x6571, 0x6571}, {0x6572, 0x6572}, {0x6573, 0x6573}, {0x6574, 0x6574}, {0x6575, 0x6575}, + {0x6576, 0x6576}, {0x6577, 0x6577}, {0x6578, 0x6578}, {0x6579, 0x6579}, {0x657A, 0x657A}, {0x657B, 0x657B}, {0x657C, 0x657C}, + {0x657D, 0x657D}, {0x657E, 0x657E}, {0x657F, 0x657F}, {0x6580, 0x6580}, {0x6581, 0x6581}, {0x6582, 0x6582}, {0x6583, 0x6583}, + {0x6584, 0x6584}, {0x6585, 0x6585}, {0x6586, 0x6586}, {0x6587, 0x6587}, {0x6588, 0x6588}, {0x6589, 0x6589}, {0x658A, 0x658A}, + {0x658B, 0x658B}, {0x658C, 0x658C}, {0x658D, 0x658D}, {0x658E, 0x658E}, {0x658F, 0x658F}, {0x6590, 0x6590}, {0x6591, 0x6591}, + {0x6592, 0x6592}, {0x6593, 0x6593}, {0x6594, 0x6594}, {0x6595, 0x6595}, {0x6596, 0x6596}, {0x6597, 0x6597}, {0x6598, 0x6598}, + {0x6599, 0x6599}, {0x659A, 0x659A}, {0x659B, 0x659B}, {0x659C, 0x659C}, {0x659D, 0x659D}, {0x659E, 0x659E}, {0x659F, 0x659F}, + {0x65A0, 0x65A0}, {0x65A1, 0x65A1}, {0x65A2, 0x65A2}, {0x65A3, 0x65A3}, {0x65A4, 0x65A4}, {0x65A5, 0x65A5}, {0x65A6, 0x65A6}, + {0x65A7, 0x65A7}, {0x65A8, 0x65A8}, {0x65A9, 0x65A9}, {0x65AA, 0x65AA}, {0x65AB, 0x65AB}, {0x65AC, 0x65AC}, {0x65AD, 0x65AD}, + {0x65AE, 0x65AE}, {0x65AF, 0x65AF}, {0x65B0, 0x65B0}, {0x65B1, 0x65B1}, {0x65B2, 0x65B2}, {0x65B3, 0x65B3}, {0x65B4, 0x65B4}, + {0x65B5, 0x65B5}, {0x65B6, 0x65B6}, {0x65B7, 0x65B7}, {0x65B8, 0x65B8}, {0x65B9, 0x65B9}, {0x65BA, 0x65BA}, {0x65BB, 0x65BB}, + {0x65BC, 0x65BC}, {0x65BD, 0x65BD}, {0x65BE, 0x65BE}, {0x65BF, 0x65BF}, {0x65C0, 0x65C0}, {0x65C1, 0x65C1}, {0x65C2, 0x65C2}, + {0x65C3, 0x65C3}, {0x65C4, 0x65C4}, {0x65C5, 0x65C5}, {0x65C6, 0x65C6}, {0x65C7, 0x65C7}, {0x65C8, 0x65C8}, {0x65C9, 0x65C9}, + {0x65CA, 0x65CA}, {0x65CB, 0x65CB}, {0x65CC, 0x65CC}, {0x65CD, 0x65CD}, {0x65CE, 0x65CE}, {0x65CF, 0x65CF}, {0x65D0, 0x65D0}, + {0x65D1, 0x65D1}, {0x65D2, 0x65D2}, {0x65D3, 0x65D3}, {0x65D4, 0x65D4}, {0x65D5, 0x65D5}, {0x65D6, 0x65D6}, {0x65D7, 0x65D7}, + {0x65D8, 0x65D8}, {0x65D9, 0x65D9}, {0x65DA, 0x65DA}, {0x65DB, 0x65DB}, {0x65DC, 0x65DC}, {0x65DD, 0x65DD}, {0x65DE, 0x65DE}, + {0x65DF, 0x65DF}, {0x65E0, 0x65E0}, {0x65E1, 0x65E1}, {0x65E2, 0x65E2}, {0x65E3, 0x65E3}, {0x65E4, 0x65E4}, {0x65E5, 0x65E5}, + {0x65E6, 0x65E6}, {0x65E7, 0x65E7}, {0x65E8, 0x65E8}, {0x65E9, 0x65E9}, {0x65EA, 0x65EA}, {0x65EB, 0x65EB}, {0x65EC, 0x65EC}, + {0x65ED, 0x65ED}, {0x65EE, 0x65EE}, {0x65EF, 0x65EF}, {0x65F0, 0x65F0}, {0x65F1, 0x65F1}, {0x65F2, 0x65F2}, {0x65F3, 0x65F3}, + {0x65F4, 0x65F4}, {0x65F5, 0x65F5}, {0x65F6, 0x65F6}, {0x65F7, 0x65F7}, {0x65F8, 0x65F8}, {0x65F9, 0x65F9}, {0x65FA, 0x65FA}, + {0x65FB, 0x65FB}, {0x65FC, 0x65FC}, {0x65FD, 0x65FD}, {0x65FE, 0x65FE}, {0x65FF, 0x65FF}, {0x6600, 0x6600}, {0x6601, 0x6601}, + {0x6602, 0x6602}, {0x6603, 0x6603}, {0x6604, 0x6604}, {0x6605, 0x6605}, {0x6606, 0x6606}, {0x6607, 0x6607}, {0x6608, 0x6608}, + {0x6609, 0x6609}, {0x660A, 0x660A}, {0x660B, 0x660B}, {0x660C, 0x660C}, {0x660D, 0x660D}, {0x660E, 0x660E}, {0x660F, 0x660F}, + {0x6610, 0x6610}, {0x6611, 0x6611}, {0x6612, 0x6612}, {0x6613, 0x6613}, {0x6614, 0x6614}, {0x6615, 0x6615}, {0x6616, 0x6616}, + {0x6617, 0x6617}, {0x6618, 0x6618}, {0x6619, 0x6619}, {0x661A, 0x661A}, {0x661B, 0x661B}, {0x661C, 0x661C}, {0x661D, 0x661D}, + {0x661E, 0x661E}, {0x661F, 0x661F}, {0x6620, 0x6620}, {0x6621, 0x6621}, {0x6622, 0x6622}, {0x6623, 0x6623}, {0x6624, 0x6624}, + {0x6625, 0x6625}, {0x6626, 0x6626}, {0x6627, 0x6627}, {0x6628, 0x6628}, {0x6629, 0x6629}, {0x662A, 0x662A}, {0x662B, 0x662B}, + {0x662C, 0x662C}, {0x662D, 0x662D}, {0x662E, 0x662E}, {0x662F, 0x662F}, {0x6630, 0x6630}, {0x6631, 0x6631}, {0x6632, 0x6632}, + {0x6633, 0x6633}, {0x6634, 0x6634}, {0x6635, 0x6635}, {0x6636, 0x6636}, {0x6637, 0x6637}, {0x6638, 0x6638}, {0x6639, 0x6639}, + {0x663A, 0x663A}, {0x663B, 0x663B}, {0x663C, 0x663C}, {0x663D, 0x663D}, {0x663E, 0x663E}, {0x663F, 0x663F}, {0x6640, 0x6640}, + {0x6641, 0x6641}, {0x6642, 0x6642}, {0x6643, 0x6643}, {0x6644, 0x6644}, {0x6645, 0x6645}, {0x6646, 0x6646}, {0x6647, 0x6647}, + {0x6648, 0x6648}, {0x6649, 0x6649}, {0x664A, 0x664A}, {0x664B, 0x664B}, {0x664C, 0x664C}, {0x664D, 0x664D}, {0x664E, 0x664E}, + {0x664F, 0x664F}, {0x6650, 0x6650}, {0x6651, 0x6651}, {0x6652, 0x6652}, {0x6653, 0x6653}, {0x6654, 0x6654}, {0x6655, 0x6655}, + {0x6656, 0x6656}, {0x6657, 0x6657}, {0x6658, 0x6658}, {0x6659, 0x6659}, {0x665A, 0x665A}, {0x665B, 0x665B}, {0x665C, 0x665C}, + {0x665D, 0x665D}, {0x665E, 0x665E}, {0x665F, 0x665F}, {0x6660, 0x6660}, {0x6661, 0x6661}, {0x6662, 0x6662}, {0x6663, 0x6663}, + {0x6664, 0x6664}, {0x6665, 0x6665}, {0x6666, 0x6666}, {0x6667, 0x6667}, {0x6668, 0x6668}, {0x6669, 0x6669}, {0x666A, 0x666A}, + {0x666B, 0x666B}, {0x666C, 0x666C}, {0x666D, 0x666D}, {0x666E, 0x666E}, {0x666F, 0x666F}, {0x6670, 0x6670}, {0x6671, 0x6671}, + {0x6672, 0x6672}, {0x6673, 0x6673}, {0x6674, 0x6674}, {0x6675, 0x6675}, {0x6676, 0x6676}, {0x6677, 0x6677}, {0x6678, 0x6678}, + {0x6679, 0x6679}, {0x667A, 0x667A}, {0x667B, 0x667B}, {0x667C, 0x667C}, {0x667D, 0x667D}, {0x667E, 0x667E}, {0x667F, 0x667F}, + {0x6680, 0x6680}, {0x6681, 0x6681}, {0x6682, 0x6682}, {0x6683, 0x6683}, {0x6684, 0x6684}, {0x6685, 0x6685}, {0x6686, 0x6686}, + {0x6687, 0x6687}, {0x6688, 0x6688}, {0x6689, 0x6689}, {0x668A, 0x668A}, {0x668B, 0x668B}, {0x668C, 0x668C}, {0x668D, 0x668D}, + {0x668E, 0x668E}, {0x668F, 0x668F}, {0x6690, 0x6690}, {0x6691, 0x6691}, {0x6692, 0x6692}, {0x6693, 0x6693}, {0x6694, 0x6694}, + {0x6695, 0x6695}, {0x6696, 0x6696}, {0x6697, 0x6697}, {0x6698, 0x6698}, {0x6699, 0x6699}, {0x669A, 0x669A}, {0x669B, 0x669B}, + {0x669C, 0x669C}, {0x669D, 0x669D}, {0x669E, 0x669E}, {0x669F, 0x669F}, {0x66A0, 0x66A0}, {0x66A1, 0x66A1}, {0x66A2, 0x66A2}, + {0x66A3, 0x66A3}, {0x66A4, 0x66A4}, {0x66A5, 0x66A5}, {0x66A6, 0x66A6}, {0x66A7, 0x66A7}, {0x66A8, 0x66A8}, {0x66A9, 0x66A9}, + {0x66AA, 0x66AA}, {0x66AB, 0x66AB}, {0x66AC, 0x66AC}, {0x66AD, 0x66AD}, {0x66AE, 0x66AE}, {0x66AF, 0x66AF}, {0x66B0, 0x66B0}, + {0x66B1, 0x66B1}, {0x66B2, 0x66B2}, {0x66B3, 0x66B3}, {0x66B4, 0x66B4}, {0x66B5, 0x66B5}, {0x66B6, 0x66B6}, {0x66B7, 0x66B7}, + {0x66B8, 0x66B8}, {0x66B9, 0x66B9}, {0x66BA, 0x66BA}, {0x66BB, 0x66BB}, {0x66BC, 0x66BC}, {0x66BD, 0x66BD}, {0x66BE, 0x66BE}, + {0x66BF, 0x66BF}, {0x66C0, 0x66C0}, {0x66C1, 0x66C1}, {0x66C2, 0x66C2}, {0x66C3, 0x66C3}, {0x66C4, 0x66C4}, {0x66C5, 0x66C5}, + {0x66C6, 0x66C6}, {0x66C7, 0x66C7}, {0x66C8, 0x66C8}, {0x66C9, 0x66C9}, {0x66CA, 0x66CA}, {0x66CB, 0x66CB}, {0x66CC, 0x66CC}, + {0x66CD, 0x66CD}, {0x66CE, 0x66CE}, {0x66CF, 0x66CF}, {0x66D0, 0x66D0}, {0x66D1, 0x66D1}, {0x66D2, 0x66D2}, {0x66D3, 0x66D3}, + {0x66D4, 0x66D4}, {0x66D5, 0x66D5}, {0x66D6, 0x66D6}, {0x66D7, 0x66D7}, {0x66D8, 0x66D8}, {0x66D9, 0x66D9}, {0x66DA, 0x66DA}, + {0x66DB, 0x66DB}, {0x66DC, 0x66DC}, {0x66DD, 0x66DD}, {0x66DE, 0x66DE}, {0x66DF, 0x66DF}, {0x66E0, 0x66E0}, {0x66E1, 0x66E1}, + {0x66E2, 0x66E2}, {0x66E3, 0x66E3}, {0x66E4, 0x66E4}, {0x66E5, 0x66E5}, {0x66E6, 0x66E6}, {0x66E7, 0x66E7}, {0x66E8, 0x66E8}, + {0x66E9, 0x66E9}, {0x66EA, 0x66EA}, {0x66EB, 0x66EB}, {0x66EC, 0x66EC}, {0x66ED, 0x66ED}, {0x66EE, 0x66EE}, {0x66EF, 0x66EF}, + {0x66F0, 0x66F0}, {0x66F1, 0x66F1}, {0x66F2, 0x66F2}, {0x66F3, 0x66F3}, {0x66F4, 0x66F4}, {0x66F5, 0x66F5}, {0x66F6, 0x66F6}, + {0x66F7, 0x66F7}, {0x66F8, 0x66F8}, {0x66F9, 0x66F9}, {0x66FA, 0x66FA}, {0x66FB, 0x66FB}, {0x66FC, 0x66FC}, {0x66FD, 0x66FD}, + {0x66FE, 0x66FE}, {0x66FF, 0x66FF}, {0x6700, 0x6700}, {0x6701, 0x6701}, {0x6702, 0x6702}, {0x6703, 0x6703}, {0x6704, 0x6704}, + {0x6705, 0x6705}, {0x6706, 0x6706}, {0x6707, 0x6707}, {0x6708, 0x6708}, {0x6709, 0x6709}, {0x670A, 0x670A}, {0x670B, 0x670B}, + {0x670C, 0x670C}, {0x670D, 0x670D}, {0x670E, 0x670E}, {0x670F, 0x670F}, {0x6710, 0x6710}, {0x6711, 0x6711}, {0x6712, 0x6712}, + {0x6713, 0x6713}, {0x6714, 0x6714}, {0x6715, 0x6715}, {0x6716, 0x6716}, {0x6717, 0x6717}, {0x6718, 0x6718}, {0x6719, 0x6719}, + {0x671A, 0x671A}, {0x671B, 0x671B}, {0x671C, 0x671C}, {0x671D, 0x671D}, {0x671E, 0x671E}, {0x671F, 0x671F}, {0x6720, 0x6720}, + {0x6721, 0x6721}, {0x6722, 0x6722}, {0x6723, 0x6723}, {0x6724, 0x6724}, {0x6725, 0x6725}, {0x6726, 0x6726}, {0x6727, 0x6727}, + {0x6728, 0x6728}, {0x6729, 0x6729}, {0x672A, 0x672A}, {0x672B, 0x672B}, {0x672C, 0x672C}, {0x672D, 0x672D}, {0x672E, 0x672E}, + {0x672F, 0x672F}, {0x6730, 0x6730}, {0x6731, 0x6731}, {0x6732, 0x6732}, {0x6733, 0x6733}, {0x6734, 0x6734}, {0x6735, 0x6735}, + {0x6736, 0x6736}, {0x6737, 0x6737}, {0x6738, 0x6738}, {0x6739, 0x6739}, {0x673A, 0x673A}, {0x673B, 0x673B}, {0x673C, 0x673C}, + {0x673D, 0x673D}, {0x673E, 0x673E}, {0x673F, 0x673F}, {0x6740, 0x6740}, {0x6741, 0x6741}, {0x6742, 0x6742}, {0x6743, 0x6743}, + {0x6744, 0x6744}, {0x6745, 0x6745}, {0x6746, 0x6746}, {0x6747, 0x6747}, {0x6748, 0x6748}, {0x6749, 0x6749}, {0x674A, 0x674A}, + {0x674B, 0x674B}, {0x674C, 0x674C}, {0x674D, 0x674D}, {0x674E, 0x674E}, {0x674F, 0x674F}, {0x6750, 0x6750}, {0x6751, 0x6751}, + {0x6752, 0x6752}, {0x6753, 0x6753}, {0x6754, 0x6754}, {0x6755, 0x6755}, {0x6756, 0x6756}, {0x6757, 0x6757}, {0x6758, 0x6758}, + {0x6759, 0x6759}, {0x675A, 0x675A}, {0x675B, 0x675B}, {0x675C, 0x675C}, {0x675D, 0x675D}, {0x675E, 0x675E}, {0x675F, 0x675F}, + {0x6760, 0x6760}, {0x6761, 0x6761}, {0x6762, 0x6762}, {0x6763, 0x6763}, {0x6764, 0x6764}, {0x6765, 0x6765}, {0x6766, 0x6766}, + {0x6767, 0x6767}, {0x6768, 0x6768}, {0x6769, 0x6769}, {0x676A, 0x676A}, {0x676B, 0x676B}, {0x676C, 0x676C}, {0x676D, 0x676D}, + {0x676E, 0x676E}, {0x676F, 0x676F}, {0x6770, 0x6770}, {0x6771, 0x6771}, {0x6772, 0x6772}, {0x6773, 0x6773}, {0x6774, 0x6774}, + {0x6775, 0x6775}, {0x6776, 0x6776}, {0x6777, 0x6777}, {0x6778, 0x6778}, {0x6779, 0x6779}, {0x677A, 0x677A}, {0x677B, 0x677B}, + {0x677C, 0x677C}, {0x677D, 0x677D}, {0x677E, 0x677E}, {0x677F, 0x677F}, {0x6780, 0x6780}, {0x6781, 0x6781}, {0x6782, 0x6782}, + {0x6783, 0x6783}, {0x6784, 0x6784}, {0x6785, 0x6785}, {0x6786, 0x6786}, {0x6787, 0x6787}, {0x6788, 0x6788}, {0x6789, 0x6789}, + {0x678A, 0x678A}, {0x678B, 0x678B}, {0x678C, 0x678C}, {0x678D, 0x678D}, {0x678E, 0x678E}, {0x678F, 0x678F}, {0x6790, 0x6790}, + {0x6791, 0x6791}, {0x6792, 0x6792}, {0x6793, 0x6793}, {0x6794, 0x6794}, {0x6795, 0x6795}, {0x6796, 0x6796}, {0x6797, 0x6797}, + {0x6798, 0x6798}, {0x6799, 0x6799}, {0x679A, 0x679A}, {0x679B, 0x679B}, {0x679C, 0x679C}, {0x679D, 0x679D}, {0x679E, 0x679E}, + {0x679F, 0x679F}, {0x67A0, 0x67A0}, {0x67A1, 0x67A1}, {0x67A2, 0x67A2}, {0x67A3, 0x67A3}, {0x67A4, 0x67A4}, {0x67A5, 0x67A5}, + {0x67A6, 0x67A6}, {0x67A7, 0x67A7}, {0x67A8, 0x67A8}, {0x67A9, 0x67A9}, {0x67AA, 0x67AA}, {0x67AB, 0x67AB}, {0x67AC, 0x67AC}, + {0x67AD, 0x67AD}, {0x67AE, 0x67AE}, {0x67AF, 0x67AF}, {0x67B0, 0x67B0}, {0x67B1, 0x67B1}, {0x67B2, 0x67B2}, {0x67B3, 0x67B3}, + {0x67B4, 0x67B4}, {0x67B5, 0x67B5}, {0x67B6, 0x67B6}, {0x67B7, 0x67B7}, {0x67B8, 0x67B8}, {0x67B9, 0x67B9}, {0x67BA, 0x67BA}, + {0x67BB, 0x67BB}, {0x67BC, 0x67BC}, {0x67BD, 0x67BD}, {0x67BE, 0x67BE}, {0x67BF, 0x67BF}, {0x67C0, 0x67C0}, {0x67C1, 0x67C1}, + {0x67C2, 0x67C2}, {0x67C3, 0x67C3}, {0x67C4, 0x67C4}, {0x67C5, 0x67C5}, {0x67C6, 0x67C6}, {0x67C7, 0x67C7}, {0x67C8, 0x67C8}, + {0x67C9, 0x67C9}, {0x67CA, 0x67CA}, {0x67CB, 0x67CB}, {0x67CC, 0x67CC}, {0x67CD, 0x67CD}, {0x67CE, 0x67CE}, {0x67CF, 0x67CF}, + {0x67D0, 0x67D0}, {0x67D1, 0x67D1}, {0x67D2, 0x67D2}, {0x67D3, 0x67D3}, {0x67D4, 0x67D4}, {0x67D5, 0x67D5}, {0x67D6, 0x67D6}, + {0x67D7, 0x67D7}, {0x67D8, 0x67D8}, {0x67D9, 0x67D9}, {0x67DA, 0x67DA}, {0x67DB, 0x67DB}, {0x67DC, 0x67DC}, {0x67DD, 0x67DD}, + {0x67DE, 0x67DE}, {0x67DF, 0x67DF}, {0x67E0, 0x67E0}, {0x67E1, 0x67E1}, {0x67E2, 0x67E2}, {0x67E3, 0x67E3}, {0x67E4, 0x67E4}, + {0x67E5, 0x67E5}, {0x67E6, 0x67E6}, {0x67E7, 0x67E7}, {0x67E8, 0x67E8}, {0x67E9, 0x67E9}, {0x67EA, 0x67EA}, {0x67EB, 0x67EB}, + {0x67EC, 0x67EC}, {0x67ED, 0x67ED}, {0x67EE, 0x67EE}, {0x67EF, 0x67EF}, {0x67F0, 0x67F0}, {0x67F1, 0x67F1}, {0x67F2, 0x67F2}, + {0x67F3, 0x67F3}, {0x67F4, 0x67F4}, {0x67F5, 0x67F5}, {0x67F6, 0x67F6}, {0x67F7, 0x67F7}, {0x67F8, 0x67F8}, {0x67F9, 0x67F9}, + {0x67FA, 0x67FA}, {0x67FB, 0x67FB}, {0x67FC, 0x67FC}, {0x67FD, 0x67FD}, {0x67FE, 0x67FE}, {0x67FF, 0x67FF}, {0x6800, 0x6800}, + {0x6801, 0x6801}, {0x6802, 0x6802}, {0x6803, 0x6803}, {0x6804, 0x6804}, {0x6805, 0x6805}, {0x6806, 0x6806}, {0x6807, 0x6807}, + {0x6808, 0x6808}, {0x6809, 0x6809}, {0x680A, 0x680A}, {0x680B, 0x680B}, {0x680C, 0x680C}, {0x680D, 0x680D}, {0x680E, 0x680E}, + {0x680F, 0x680F}, {0x6810, 0x6810}, {0x6811, 0x6811}, {0x6812, 0x6812}, {0x6813, 0x6813}, {0x6814, 0x6814}, {0x6815, 0x6815}, + {0x6816, 0x6816}, {0x6817, 0x6817}, {0x6818, 0x6818}, {0x6819, 0x6819}, {0x681A, 0x681A}, {0x681B, 0x681B}, {0x681C, 0x681C}, + {0x681D, 0x681D}, {0x681E, 0x681E}, {0x681F, 0x681F}, {0x6820, 0x6820}, {0x6821, 0x6821}, {0x6822, 0x6822}, {0x6823, 0x6823}, + {0x6824, 0x6824}, {0x6825, 0x6825}, {0x6826, 0x6826}, {0x6827, 0x6827}, {0x6828, 0x6828}, {0x6829, 0x6829}, {0x682A, 0x682A}, + {0x682B, 0x682B}, {0x682C, 0x682C}, {0x682D, 0x682D}, {0x682E, 0x682E}, {0x682F, 0x682F}, {0x6830, 0x6830}, {0x6831, 0x6831}, + {0x6832, 0x6832}, {0x6833, 0x6833}, {0x6834, 0x6834}, {0x6835, 0x6835}, {0x6836, 0x6836}, {0x6837, 0x6837}, {0x6838, 0x6838}, + {0x6839, 0x6839}, {0x683A, 0x683A}, {0x683B, 0x683B}, {0x683C, 0x683C}, {0x683D, 0x683D}, {0x683E, 0x683E}, {0x683F, 0x683F}, + {0x6840, 0x6840}, {0x6841, 0x6841}, {0x6842, 0x6842}, {0x6843, 0x6843}, {0x6844, 0x6844}, {0x6845, 0x6845}, {0x6846, 0x6846}, + {0x6847, 0x6847}, {0x6848, 0x6848}, {0x6849, 0x6849}, {0x684A, 0x684A}, {0x684B, 0x684B}, {0x684C, 0x684C}, {0x684D, 0x684D}, + {0x684E, 0x684E}, {0x684F, 0x684F}, {0x6850, 0x6850}, {0x6851, 0x6851}, {0x6852, 0x6852}, {0x6853, 0x6853}, {0x6854, 0x6854}, + {0x6855, 0x6855}, {0x6856, 0x6856}, {0x6857, 0x6857}, {0x6858, 0x6858}, {0x6859, 0x6859}, {0x685A, 0x685A}, {0x685B, 0x685B}, + {0x685C, 0x685C}, {0x685D, 0x685D}, {0x685E, 0x685E}, {0x685F, 0x685F}, {0x6860, 0x6860}, {0x6861, 0x6861}, {0x6862, 0x6862}, + {0x6863, 0x6863}, {0x6864, 0x6864}, {0x6865, 0x6865}, {0x6866, 0x6866}, {0x6867, 0x6867}, {0x6868, 0x6868}, {0x6869, 0x6869}, + {0x686A, 0x686A}, {0x686B, 0x686B}, {0x686C, 0x686C}, {0x686D, 0x686D}, {0x686E, 0x686E}, {0x686F, 0x686F}, {0x6870, 0x6870}, + {0x6871, 0x6871}, {0x6872, 0x6872}, {0x6873, 0x6873}, {0x6874, 0x6874}, {0x6875, 0x6875}, {0x6876, 0x6876}, {0x6877, 0x6877}, + {0x6878, 0x6878}, {0x6879, 0x6879}, {0x687A, 0x687A}, {0x687B, 0x687B}, {0x687C, 0x687C}, {0x687D, 0x687D}, {0x687E, 0x687E}, + {0x687F, 0x687F}, {0x6880, 0x6880}, {0x6881, 0x6881}, {0x6882, 0x6882}, {0x6883, 0x6883}, {0x6884, 0x6884}, {0x6885, 0x6885}, + {0x6886, 0x6886}, {0x6887, 0x6887}, {0x6888, 0x6888}, {0x6889, 0x6889}, {0x688A, 0x688A}, {0x688B, 0x688B}, {0x688C, 0x688C}, + {0x688D, 0x688D}, {0x688E, 0x688E}, {0x688F, 0x688F}, {0x6890, 0x6890}, {0x6891, 0x6891}, {0x6892, 0x6892}, {0x6893, 0x6893}, + {0x6894, 0x6894}, {0x6895, 0x6895}, {0x6896, 0x6896}, {0x6897, 0x6897}, {0x6898, 0x6898}, {0x6899, 0x6899}, {0x689A, 0x689A}, + {0x689B, 0x689B}, {0x689C, 0x689C}, {0x689D, 0x689D}, {0x689E, 0x689E}, {0x689F, 0x689F}, {0x68A0, 0x68A0}, {0x68A1, 0x68A1}, + {0x68A2, 0x68A2}, {0x68A3, 0x68A3}, {0x68A4, 0x68A4}, {0x68A5, 0x68A5}, {0x68A6, 0x68A6}, {0x68A7, 0x68A7}, {0x68A8, 0x68A8}, + {0x68A9, 0x68A9}, {0x68AA, 0x68AA}, {0x68AB, 0x68AB}, {0x68AC, 0x68AC}, {0x68AD, 0x68AD}, {0x68AE, 0x68AE}, {0x68AF, 0x68AF}, + {0x68B0, 0x68B0}, {0x68B1, 0x68B1}, {0x68B2, 0x68B2}, {0x68B3, 0x68B3}, {0x68B4, 0x68B4}, {0x68B5, 0x68B5}, {0x68B6, 0x68B6}, + {0x68B7, 0x68B7}, {0x68B8, 0x68B8}, {0x68B9, 0x68B9}, {0x68BA, 0x68BA}, {0x68BB, 0x68BB}, {0x68BC, 0x68BC}, {0x68BD, 0x68BD}, + {0x68BE, 0x68BE}, {0x68BF, 0x68BF}, {0x68C0, 0x68C0}, {0x68C1, 0x68C1}, {0x68C2, 0x68C2}, {0x68C3, 0x68C3}, {0x68C4, 0x68C4}, + {0x68C5, 0x68C5}, {0x68C6, 0x68C6}, {0x68C7, 0x68C7}, {0x68C8, 0x68C8}, {0x68C9, 0x68C9}, {0x68CA, 0x68CA}, {0x68CB, 0x68CB}, + {0x68CC, 0x68CC}, {0x68CD, 0x68CD}, {0x68CE, 0x68CE}, {0x68CF, 0x68CF}, {0x68D0, 0x68D0}, {0x68D1, 0x68D1}, {0x68D2, 0x68D2}, + {0x68D3, 0x68D3}, {0x68D4, 0x68D4}, {0x68D5, 0x68D5}, {0x68D6, 0x68D6}, {0x68D7, 0x68D7}, {0x68D8, 0x68D8}, {0x68D9, 0x68D9}, + {0x68DA, 0x68DA}, {0x68DB, 0x68DB}, {0x68DC, 0x68DC}, {0x68DD, 0x68DD}, {0x68DE, 0x68DE}, {0x68DF, 0x68DF}, {0x68E0, 0x68E0}, + {0x68E1, 0x68E1}, {0x68E2, 0x68E2}, {0x68E3, 0x68E3}, {0x68E4, 0x68E4}, {0x68E5, 0x68E5}, {0x68E6, 0x68E6}, {0x68E7, 0x68E7}, + {0x68E8, 0x68E8}, {0x68E9, 0x68E9}, {0x68EA, 0x68EA}, {0x68EB, 0x68EB}, {0x68EC, 0x68EC}, {0x68ED, 0x68ED}, {0x68EE, 0x68EE}, + {0x68EF, 0x68EF}, {0x68F0, 0x68F0}, {0x68F1, 0x68F1}, {0x68F2, 0x68F2}, {0x68F3, 0x68F3}, {0x68F4, 0x68F4}, {0x68F5, 0x68F5}, + {0x68F6, 0x68F6}, {0x68F7, 0x68F7}, {0x68F8, 0x68F8}, {0x68F9, 0x68F9}, {0x68FA, 0x68FA}, {0x68FB, 0x68FB}, {0x68FC, 0x68FC}, + {0x68FD, 0x68FD}, {0x68FE, 0x68FE}, {0x68FF, 0x68FF}, {0x6900, 0x6900}, {0x6901, 0x6901}, {0x6902, 0x6902}, {0x6903, 0x6903}, + {0x6904, 0x6904}, {0x6905, 0x6905}, {0x6906, 0x6906}, {0x6907, 0x6907}, {0x6908, 0x6908}, {0x6909, 0x6909}, {0x690A, 0x690A}, + {0x690B, 0x690B}, {0x690C, 0x690C}, {0x690D, 0x690D}, {0x690E, 0x690E}, {0x690F, 0x690F}, {0x6910, 0x6910}, {0x6911, 0x6911}, + {0x6912, 0x6912}, {0x6913, 0x6913}, {0x6914, 0x6914}, {0x6915, 0x6915}, {0x6916, 0x6916}, {0x6917, 0x6917}, {0x6918, 0x6918}, + {0x6919, 0x6919}, {0x691A, 0x691A}, {0x691B, 0x691B}, {0x691C, 0x691C}, {0x691D, 0x691D}, {0x691E, 0x691E}, {0x691F, 0x691F}, + {0x6920, 0x6920}, {0x6921, 0x6921}, {0x6922, 0x6922}, {0x6923, 0x6923}, {0x6924, 0x6924}, {0x6925, 0x6925}, {0x6926, 0x6926}, + {0x6927, 0x6927}, {0x6928, 0x6928}, {0x6929, 0x6929}, {0x692A, 0x692A}, {0x692B, 0x692B}, {0x692C, 0x692C}, {0x692D, 0x692D}, + {0x692E, 0x692E}, {0x692F, 0x692F}, {0x6930, 0x6930}, {0x6931, 0x6931}, {0x6932, 0x6932}, {0x6933, 0x6933}, {0x6934, 0x6934}, + {0x6935, 0x6935}, {0x6936, 0x6936}, {0x6937, 0x6937}, {0x6938, 0x6938}, {0x6939, 0x6939}, {0x693A, 0x693A}, {0x693B, 0x693B}, + {0x693C, 0x693C}, {0x693D, 0x693D}, {0x693E, 0x693E}, {0x693F, 0x693F}, {0x6940, 0x6940}, {0x6941, 0x6941}, {0x6942, 0x6942}, + {0x6943, 0x6943}, {0x6944, 0x6944}, {0x6945, 0x6945}, {0x6946, 0x6946}, {0x6947, 0x6947}, {0x6948, 0x6948}, {0x6949, 0x6949}, + {0x694A, 0x694A}, {0x694B, 0x694B}, {0x694C, 0x694C}, {0x694D, 0x694D}, {0x694E, 0x694E}, {0x694F, 0x694F}, {0x6950, 0x6950}, + {0x6951, 0x6951}, {0x6952, 0x6952}, {0x6953, 0x6953}, {0x6954, 0x6954}, {0x6955, 0x6955}, {0x6956, 0x6956}, {0x6957, 0x6957}, + {0x6958, 0x6958}, {0x6959, 0x6959}, {0x695A, 0x695A}, {0x695B, 0x695B}, {0x695C, 0x695C}, {0x695D, 0x695D}, {0x695E, 0x695E}, + {0x695F, 0x695F}, {0x6960, 0x6960}, {0x6961, 0x6961}, {0x6962, 0x6962}, {0x6963, 0x6963}, {0x6964, 0x6964}, {0x6965, 0x6965}, + {0x6966, 0x6966}, {0x6967, 0x6967}, {0x6968, 0x6968}, {0x6969, 0x6969}, {0x696A, 0x696A}, {0x696B, 0x696B}, {0x696C, 0x696C}, + {0x696D, 0x696D}, {0x696E, 0x696E}, {0x696F, 0x696F}, {0x6970, 0x6970}, {0x6971, 0x6971}, {0x6972, 0x6972}, {0x6973, 0x6973}, + {0x6974, 0x6974}, {0x6975, 0x6975}, {0x6976, 0x6976}, {0x6977, 0x6977}, {0x6978, 0x6978}, {0x6979, 0x6979}, {0x697A, 0x697A}, + {0x697B, 0x697B}, {0x697C, 0x697C}, {0x697D, 0x697D}, {0x697E, 0x697E}, {0x697F, 0x697F}, {0x6980, 0x6980}, {0x6981, 0x6981}, + {0x6982, 0x6982}, {0x6983, 0x6983}, {0x6984, 0x6984}, {0x6985, 0x6985}, {0x6986, 0x6986}, {0x6987, 0x6987}, {0x6988, 0x6988}, + {0x6989, 0x6989}, {0x698A, 0x698A}, {0x698B, 0x698B}, {0x698C, 0x698C}, {0x698D, 0x698D}, {0x698E, 0x698E}, {0x698F, 0x698F}, + {0x6990, 0x6990}, {0x6991, 0x6991}, {0x6992, 0x6992}, {0x6993, 0x6993}, {0x6994, 0x6994}, {0x6995, 0x6995}, {0x6996, 0x6996}, + {0x6997, 0x6997}, {0x6998, 0x6998}, {0x6999, 0x6999}, {0x699A, 0x699A}, {0x699B, 0x699B}, {0x699C, 0x699C}, {0x699D, 0x699D}, + {0x699E, 0x699E}, {0x699F, 0x699F}, {0x69A0, 0x69A0}, {0x69A1, 0x69A1}, {0x69A2, 0x69A2}, {0x69A3, 0x69A3}, {0x69A4, 0x69A4}, + {0x69A5, 0x69A5}, {0x69A6, 0x69A6}, {0x69A7, 0x69A7}, {0x69A8, 0x69A8}, {0x69A9, 0x69A9}, {0x69AA, 0x69AA}, {0x69AB, 0x69AB}, + {0x69AC, 0x69AC}, {0x69AD, 0x69AD}, {0x69AE, 0x69AE}, {0x69AF, 0x69AF}, {0x69B0, 0x69B0}, {0x69B1, 0x69B1}, {0x69B2, 0x69B2}, + {0x69B3, 0x69B3}, {0x69B4, 0x69B4}, {0x69B5, 0x69B5}, {0x69B6, 0x69B6}, {0x69B7, 0x69B7}, {0x69B8, 0x69B8}, {0x69B9, 0x69B9}, + {0x69BA, 0x69BA}, {0x69BB, 0x69BB}, {0x69BC, 0x69BC}, {0x69BD, 0x69BD}, {0x69BE, 0x69BE}, {0x69BF, 0x69BF}, {0x69C0, 0x69C0}, + {0x69C1, 0x69C1}, {0x69C2, 0x69C2}, {0x69C3, 0x69C3}, {0x69C4, 0x69C4}, {0x69C5, 0x69C5}, {0x69C6, 0x69C6}, {0x69C7, 0x69C7}, + {0x69C8, 0x69C8}, {0x69C9, 0x69C9}, {0x69CA, 0x69CA}, {0x69CB, 0x69CB}, {0x69CC, 0x69CC}, {0x69CD, 0x69CD}, {0x69CE, 0x69CE}, + {0x69CF, 0x69CF}, {0x69D0, 0x69D0}, {0x69D1, 0x69D1}, {0x69D2, 0x69D2}, {0x69D3, 0x69D3}, {0x69D4, 0x69D4}, {0x69D5, 0x69D5}, + {0x69D6, 0x69D6}, {0x69D7, 0x69D7}, {0x69D8, 0x69D8}, {0x69D9, 0x69D9}, {0x69DA, 0x69DA}, {0x69DB, 0x69DB}, {0x69DC, 0x69DC}, + {0x69DD, 0x69DD}, {0x69DE, 0x69DE}, {0x69DF, 0x69DF}, {0x69E0, 0x69E0}, {0x69E1, 0x69E1}, {0x69E2, 0x69E2}, {0x69E3, 0x69E3}, + {0x69E4, 0x69E4}, {0x69E5, 0x69E5}, {0x69E6, 0x69E6}, {0x69E7, 0x69E7}, {0x69E8, 0x69E8}, {0x69E9, 0x69E9}, {0x69EA, 0x69EA}, + {0x69EB, 0x69EB}, {0x69EC, 0x69EC}, {0x69ED, 0x69ED}, {0x69EE, 0x69EE}, {0x69EF, 0x69EF}, {0x69F0, 0x69F0}, {0x69F1, 0x69F1}, + {0x69F2, 0x69F2}, {0x69F3, 0x69F3}, {0x69F4, 0x69F4}, {0x69F5, 0x69F5}, {0x69F6, 0x69F6}, {0x69F7, 0x69F7}, {0x69F8, 0x69F8}, + {0x69F9, 0x69F9}, {0x69FA, 0x69FA}, {0x69FB, 0x69FB}, {0x69FC, 0x69FC}, {0x69FD, 0x69FD}, {0x69FE, 0x69FE}, {0x69FF, 0x69FF}, + {0x6A00, 0x6A00}, {0x6A01, 0x6A01}, {0x6A02, 0x6A02}, {0x6A03, 0x6A03}, {0x6A04, 0x6A04}, {0x6A05, 0x6A05}, {0x6A06, 0x6A06}, + {0x6A07, 0x6A07}, {0x6A08, 0x6A08}, {0x6A09, 0x6A09}, {0x6A0A, 0x6A0A}, {0x6A0B, 0x6A0B}, {0x6A0C, 0x6A0C}, {0x6A0D, 0x6A0D}, + {0x6A0E, 0x6A0E}, {0x6A0F, 0x6A0F}, {0x6A10, 0x6A10}, {0x6A11, 0x6A11}, {0x6A12, 0x6A12}, {0x6A13, 0x6A13}, {0x6A14, 0x6A14}, + {0x6A15, 0x6A15}, {0x6A16, 0x6A16}, {0x6A17, 0x6A17}, {0x6A18, 0x6A18}, {0x6A19, 0x6A19}, {0x6A1A, 0x6A1A}, {0x6A1B, 0x6A1B}, + {0x6A1C, 0x6A1C}, {0x6A1D, 0x6A1D}, {0x6A1E, 0x6A1E}, {0x6A1F, 0x6A1F}, {0x6A20, 0x6A20}, {0x6A21, 0x6A21}, {0x6A22, 0x6A22}, + {0x6A23, 0x6A23}, {0x6A24, 0x6A24}, {0x6A25, 0x6A25}, {0x6A26, 0x6A26}, {0x6A27, 0x6A27}, {0x6A28, 0x6A28}, {0x6A29, 0x6A29}, + {0x6A2A, 0x6A2A}, {0x6A2B, 0x6A2B}, {0x6A2C, 0x6A2C}, {0x6A2D, 0x6A2D}, {0x6A2E, 0x6A2E}, {0x6A2F, 0x6A2F}, {0x6A30, 0x6A30}, + {0x6A31, 0x6A31}, {0x6A32, 0x6A32}, {0x6A33, 0x6A33}, {0x6A34, 0x6A34}, {0x6A35, 0x6A35}, {0x6A36, 0x6A36}, {0x6A37, 0x6A37}, + {0x6A38, 0x6A38}, {0x6A39, 0x6A39}, {0x6A3A, 0x6A3A}, {0x6A3B, 0x6A3B}, {0x6A3C, 0x6A3C}, {0x6A3D, 0x6A3D}, {0x6A3E, 0x6A3E}, + {0x6A3F, 0x6A3F}, {0x6A40, 0x6A40}, {0x6A41, 0x6A41}, {0x6A42, 0x6A42}, {0x6A43, 0x6A43}, {0x6A44, 0x6A44}, {0x6A45, 0x6A45}, + {0x6A46, 0x6A46}, {0x6A47, 0x6A47}, {0x6A48, 0x6A48}, {0x6A49, 0x6A49}, {0x6A4A, 0x6A4A}, {0x6A4B, 0x6A4B}, {0x6A4C, 0x6A4C}, + {0x6A4D, 0x6A4D}, {0x6A4E, 0x6A4E}, {0x6A4F, 0x6A4F}, {0x6A50, 0x6A50}, {0x6A51, 0x6A51}, {0x6A52, 0x6A52}, {0x6A53, 0x6A53}, + {0x6A54, 0x6A54}, {0x6A55, 0x6A55}, {0x6A56, 0x6A56}, {0x6A57, 0x6A57}, {0x6A58, 0x6A58}, {0x6A59, 0x6A59}, {0x6A5A, 0x6A5A}, + {0x6A5B, 0x6A5B}, {0x6A5C, 0x6A5C}, {0x6A5D, 0x6A5D}, {0x6A5E, 0x6A5E}, {0x6A5F, 0x6A5F}, {0x6A60, 0x6A60}, {0x6A61, 0x6A61}, + {0x6A62, 0x6A62}, {0x6A63, 0x6A63}, {0x6A64, 0x6A64}, {0x6A65, 0x6A65}, {0x6A66, 0x6A66}, {0x6A67, 0x6A67}, {0x6A68, 0x6A68}, + {0x6A69, 0x6A69}, {0x6A6A, 0x6A6A}, {0x6A6B, 0x6A6B}, {0x6A6C, 0x6A6C}, {0x6A6D, 0x6A6D}, {0x6A6E, 0x6A6E}, {0x6A6F, 0x6A6F}, + {0x6A70, 0x6A70}, {0x6A71, 0x6A71}, {0x6A72, 0x6A72}, {0x6A73, 0x6A73}, {0x6A74, 0x6A74}, {0x6A75, 0x6A75}, {0x6A76, 0x6A76}, + {0x6A77, 0x6A77}, {0x6A78, 0x6A78}, {0x6A79, 0x6A79}, {0x6A7A, 0x6A7A}, {0x6A7B, 0x6A7B}, {0x6A7C, 0x6A7C}, {0x6A7D, 0x6A7D}, + {0x6A7E, 0x6A7E}, {0x6A7F, 0x6A7F}, {0x6A80, 0x6A80}, {0x6A81, 0x6A81}, {0x6A82, 0x6A82}, {0x6A83, 0x6A83}, {0x6A84, 0x6A84}, + {0x6A85, 0x6A85}, {0x6A86, 0x6A86}, {0x6A87, 0x6A87}, {0x6A88, 0x6A88}, {0x6A89, 0x6A89}, {0x6A8A, 0x6A8A}, {0x6A8B, 0x6A8B}, + {0x6A8C, 0x6A8C}, {0x6A8D, 0x6A8D}, {0x6A8E, 0x6A8E}, {0x6A8F, 0x6A8F}, {0x6A90, 0x6A90}, {0x6A91, 0x6A91}, {0x6A92, 0x6A92}, + {0x6A93, 0x6A93}, {0x6A94, 0x6A94}, {0x6A95, 0x6A95}, {0x6A96, 0x6A96}, {0x6A97, 0x6A97}, {0x6A98, 0x6A98}, {0x6A99, 0x6A99}, + {0x6A9A, 0x6A9A}, {0x6A9B, 0x6A9B}, {0x6A9C, 0x6A9C}, {0x6A9D, 0x6A9D}, {0x6A9E, 0x6A9E}, {0x6A9F, 0x6A9F}, {0x6AA0, 0x6AA0}, + {0x6AA1, 0x6AA1}, {0x6AA2, 0x6AA2}, {0x6AA3, 0x6AA3}, {0x6AA4, 0x6AA4}, {0x6AA5, 0x6AA5}, {0x6AA6, 0x6AA6}, {0x6AA7, 0x6AA7}, + {0x6AA8, 0x6AA8}, {0x6AA9, 0x6AA9}, {0x6AAA, 0x6AAA}, {0x6AAB, 0x6AAB}, {0x6AAC, 0x6AAC}, {0x6AAD, 0x6AAD}, {0x6AAE, 0x6AAE}, + {0x6AAF, 0x6AAF}, {0x6AB0, 0x6AB0}, {0x6AB1, 0x6AB1}, {0x6AB2, 0x6AB2}, {0x6AB3, 0x6AB3}, {0x6AB4, 0x6AB4}, {0x6AB5, 0x6AB5}, + {0x6AB6, 0x6AB6}, {0x6AB7, 0x6AB7}, {0x6AB8, 0x6AB8}, {0x6AB9, 0x6AB9}, {0x6ABA, 0x6ABA}, {0x6ABB, 0x6ABB}, {0x6ABC, 0x6ABC}, + {0x6ABD, 0x6ABD}, {0x6ABE, 0x6ABE}, {0x6ABF, 0x6ABF}, {0x6AC0, 0x6AC0}, {0x6AC1, 0x6AC1}, {0x6AC2, 0x6AC2}, {0x6AC3, 0x6AC3}, + {0x6AC4, 0x6AC4}, {0x6AC5, 0x6AC5}, {0x6AC6, 0x6AC6}, {0x6AC7, 0x6AC7}, {0x6AC8, 0x6AC8}, {0x6AC9, 0x6AC9}, {0x6ACA, 0x6ACA}, + {0x6ACB, 0x6ACB}, {0x6ACC, 0x6ACC}, {0x6ACD, 0x6ACD}, {0x6ACE, 0x6ACE}, {0x6ACF, 0x6ACF}, {0x6AD0, 0x6AD0}, {0x6AD1, 0x6AD1}, + {0x6AD2, 0x6AD2}, {0x6AD3, 0x6AD3}, {0x6AD4, 0x6AD4}, {0x6AD5, 0x6AD5}, {0x6AD6, 0x6AD6}, {0x6AD7, 0x6AD7}, {0x6AD8, 0x6AD8}, + {0x6AD9, 0x6AD9}, {0x6ADA, 0x6ADA}, {0x6ADB, 0x6ADB}, {0x6ADC, 0x6ADC}, {0x6ADD, 0x6ADD}, {0x6ADE, 0x6ADE}, {0x6ADF, 0x6ADF}, + {0x6AE0, 0x6AE0}, {0x6AE1, 0x6AE1}, {0x6AE2, 0x6AE2}, {0x6AE3, 0x6AE3}, {0x6AE4, 0x6AE4}, {0x6AE5, 0x6AE5}, {0x6AE6, 0x6AE6}, + {0x6AE7, 0x6AE7}, {0x6AE8, 0x6AE8}, {0x6AE9, 0x6AE9}, {0x6AEA, 0x6AEA}, {0x6AEB, 0x6AEB}, {0x6AEC, 0x6AEC}, {0x6AED, 0x6AED}, + {0x6AEE, 0x6AEE}, {0x6AEF, 0x6AEF}, {0x6AF0, 0x6AF0}, {0x6AF1, 0x6AF1}, {0x6AF2, 0x6AF2}, {0x6AF3, 0x6AF3}, {0x6AF4, 0x6AF4}, + {0x6AF5, 0x6AF5}, {0x6AF6, 0x6AF6}, {0x6AF7, 0x6AF7}, {0x6AF8, 0x6AF8}, {0x6AF9, 0x6AF9}, {0x6AFA, 0x6AFA}, {0x6AFB, 0x6AFB}, + {0x6AFC, 0x6AFC}, {0x6AFD, 0x6AFD}, {0x6AFE, 0x6AFE}, {0x6AFF, 0x6AFF}, {0x6B00, 0x6B00}, {0x6B01, 0x6B01}, {0x6B02, 0x6B02}, + {0x6B03, 0x6B03}, {0x6B04, 0x6B04}, {0x6B05, 0x6B05}, {0x6B06, 0x6B06}, {0x6B07, 0x6B07}, {0x6B08, 0x6B08}, {0x6B09, 0x6B09}, + {0x6B0A, 0x6B0A}, {0x6B0B, 0x6B0B}, {0x6B0C, 0x6B0C}, {0x6B0D, 0x6B0D}, {0x6B0E, 0x6B0E}, {0x6B0F, 0x6B0F}, {0x6B10, 0x6B10}, + {0x6B11, 0x6B11}, {0x6B12, 0x6B12}, {0x6B13, 0x6B13}, {0x6B14, 0x6B14}, {0x6B15, 0x6B15}, {0x6B16, 0x6B16}, {0x6B17, 0x6B17}, + {0x6B18, 0x6B18}, {0x6B19, 0x6B19}, {0x6B1A, 0x6B1A}, {0x6B1B, 0x6B1B}, {0x6B1C, 0x6B1C}, {0x6B1D, 0x6B1D}, {0x6B1E, 0x6B1E}, + {0x6B1F, 0x6B1F}, {0x6B20, 0x6B20}, {0x6B21, 0x6B21}, {0x6B22, 0x6B22}, {0x6B23, 0x6B23}, {0x6B24, 0x6B24}, {0x6B25, 0x6B25}, + {0x6B26, 0x6B26}, {0x6B27, 0x6B27}, {0x6B28, 0x6B28}, {0x6B29, 0x6B29}, {0x6B2A, 0x6B2A}, {0x6B2B, 0x6B2B}, {0x6B2C, 0x6B2C}, + {0x6B2D, 0x6B2D}, {0x6B2E, 0x6B2E}, {0x6B2F, 0x6B2F}, {0x6B30, 0x6B30}, {0x6B31, 0x6B31}, {0x6B32, 0x6B32}, {0x6B33, 0x6B33}, + {0x6B34, 0x6B34}, {0x6B35, 0x6B35}, {0x6B36, 0x6B36}, {0x6B37, 0x6B37}, {0x6B38, 0x6B38}, {0x6B39, 0x6B39}, {0x6B3A, 0x6B3A}, + {0x6B3B, 0x6B3B}, {0x6B3C, 0x6B3C}, {0x6B3D, 0x6B3D}, {0x6B3E, 0x6B3E}, {0x6B3F, 0x6B3F}, {0x6B40, 0x6B40}, {0x6B41, 0x6B41}, + {0x6B42, 0x6B42}, {0x6B43, 0x6B43}, {0x6B44, 0x6B44}, {0x6B45, 0x6B45}, {0x6B46, 0x6B46}, {0x6B47, 0x6B47}, {0x6B48, 0x6B48}, + {0x6B49, 0x6B49}, {0x6B4A, 0x6B4A}, {0x6B4B, 0x6B4B}, {0x6B4C, 0x6B4C}, {0x6B4D, 0x6B4D}, {0x6B4E, 0x6B4E}, {0x6B4F, 0x6B4F}, + {0x6B50, 0x6B50}, {0x6B51, 0x6B51}, {0x6B52, 0x6B52}, {0x6B53, 0x6B53}, {0x6B54, 0x6B54}, {0x6B55, 0x6B55}, {0x6B56, 0x6B56}, + {0x6B57, 0x6B57}, {0x6B58, 0x6B58}, {0x6B59, 0x6B59}, {0x6B5A, 0x6B5A}, {0x6B5B, 0x6B5B}, {0x6B5C, 0x6B5C}, {0x6B5D, 0x6B5D}, + {0x6B5E, 0x6B5E}, {0x6B5F, 0x6B5F}, {0x6B60, 0x6B60}, {0x6B61, 0x6B61}, {0x6B62, 0x6B62}, {0x6B63, 0x6B63}, {0x6B64, 0x6B64}, + {0x6B65, 0x6B65}, {0x6B66, 0x6B66}, {0x6B67, 0x6B67}, {0x6B68, 0x6B68}, {0x6B69, 0x6B69}, {0x6B6A, 0x6B6A}, {0x6B6B, 0x6B6B}, + {0x6B6C, 0x6B6C}, {0x6B6D, 0x6B6D}, {0x6B6E, 0x6B6E}, {0x6B6F, 0x6B6F}, {0x6B70, 0x6B70}, {0x6B71, 0x6B71}, {0x6B72, 0x6B72}, + {0x6B73, 0x6B73}, {0x6B74, 0x6B74}, {0x6B75, 0x6B75}, {0x6B76, 0x6B76}, {0x6B77, 0x6B77}, {0x6B78, 0x6B78}, {0x6B79, 0x6B79}, + {0x6B7A, 0x6B7A}, {0x6B7B, 0x6B7B}, {0x6B7C, 0x6B7C}, {0x6B7D, 0x6B7D}, {0x6B7E, 0x6B7E}, {0x6B7F, 0x6B7F}, {0x6B80, 0x6B80}, + {0x6B81, 0x6B81}, {0x6B82, 0x6B82}, {0x6B83, 0x6B83}, {0x6B84, 0x6B84}, {0x6B85, 0x6B85}, {0x6B86, 0x6B86}, {0x6B87, 0x6B87}, + {0x6B88, 0x6B88}, {0x6B89, 0x6B89}, {0x6B8A, 0x6B8A}, {0x6B8B, 0x6B8B}, {0x6B8C, 0x6B8C}, {0x6B8D, 0x6B8D}, {0x6B8E, 0x6B8E}, + {0x6B8F, 0x6B8F}, {0x6B90, 0x6B90}, {0x6B91, 0x6B91}, {0x6B92, 0x6B92}, {0x6B93, 0x6B93}, {0x6B94, 0x6B94}, {0x6B95, 0x6B95}, + {0x6B96, 0x6B96}, {0x6B97, 0x6B97}, {0x6B98, 0x6B98}, {0x6B99, 0x6B99}, {0x6B9A, 0x6B9A}, {0x6B9B, 0x6B9B}, {0x6B9C, 0x6B9C}, + {0x6B9D, 0x6B9D}, {0x6B9E, 0x6B9E}, {0x6B9F, 0x6B9F}, {0x6BA0, 0x6BA0}, {0x6BA1, 0x6BA1}, {0x6BA2, 0x6BA2}, {0x6BA3, 0x6BA3}, + {0x6BA4, 0x6BA4}, {0x6BA5, 0x6BA5}, {0x6BA6, 0x6BA6}, {0x6BA7, 0x6BA7}, {0x6BA8, 0x6BA8}, {0x6BA9, 0x6BA9}, {0x6BAA, 0x6BAA}, + {0x6BAB, 0x6BAB}, {0x6BAC, 0x6BAC}, {0x6BAD, 0x6BAD}, {0x6BAE, 0x6BAE}, {0x6BAF, 0x6BAF}, {0x6BB0, 0x6BB0}, {0x6BB1, 0x6BB1}, + {0x6BB2, 0x6BB2}, {0x6BB3, 0x6BB3}, {0x6BB4, 0x6BB4}, {0x6BB5, 0x6BB5}, {0x6BB6, 0x6BB6}, {0x6BB7, 0x6BB7}, {0x6BB8, 0x6BB8}, + {0x6BB9, 0x6BB9}, {0x6BBA, 0x6BBA}, {0x6BBB, 0x6BBB}, {0x6BBC, 0x6BBC}, {0x6BBD, 0x6BBD}, {0x6BBE, 0x6BBE}, {0x6BBF, 0x6BBF}, + {0x6BC0, 0x6BC0}, {0x6BC1, 0x6BC1}, {0x6BC2, 0x6BC2}, {0x6BC3, 0x6BC3}, {0x6BC4, 0x6BC4}, {0x6BC5, 0x6BC5}, {0x6BC6, 0x6BC6}, + {0x6BC7, 0x6BC7}, {0x6BC8, 0x6BC8}, {0x6BC9, 0x6BC9}, {0x6BCA, 0x6BCA}, {0x6BCB, 0x6BCB}, {0x6BCC, 0x6BCC}, {0x6BCD, 0x6BCD}, + {0x6BCE, 0x6BCE}, {0x6BCF, 0x6BCF}, {0x6BD0, 0x6BD0}, {0x6BD1, 0x6BD1}, {0x6BD2, 0x6BD2}, {0x6BD3, 0x6BD3}, {0x6BD4, 0x6BD4}, + {0x6BD5, 0x6BD5}, {0x6BD6, 0x6BD6}, {0x6BD7, 0x6BD7}, {0x6BD8, 0x6BD8}, {0x6BD9, 0x6BD9}, {0x6BDA, 0x6BDA}, {0x6BDB, 0x6BDB}, + {0x6BDC, 0x6BDC}, {0x6BDD, 0x6BDD}, {0x6BDE, 0x6BDE}, {0x6BDF, 0x6BDF}, {0x6BE0, 0x6BE0}, {0x6BE1, 0x6BE1}, {0x6BE2, 0x6BE2}, + {0x6BE3, 0x6BE3}, {0x6BE4, 0x6BE4}, {0x6BE5, 0x6BE5}, {0x6BE6, 0x6BE6}, {0x6BE7, 0x6BE7}, {0x6BE8, 0x6BE8}, {0x6BE9, 0x6BE9}, + {0x6BEA, 0x6BEA}, {0x6BEB, 0x6BEB}, {0x6BEC, 0x6BEC}, {0x6BED, 0x6BED}, {0x6BEE, 0x6BEE}, {0x6BEF, 0x6BEF}, {0x6BF0, 0x6BF0}, + {0x6BF1, 0x6BF1}, {0x6BF2, 0x6BF2}, {0x6BF3, 0x6BF3}, {0x6BF4, 0x6BF4}, {0x6BF5, 0x6BF5}, {0x6BF6, 0x6BF6}, {0x6BF7, 0x6BF7}, + {0x6BF8, 0x6BF8}, {0x6BF9, 0x6BF9}, {0x6BFA, 0x6BFA}, {0x6BFB, 0x6BFB}, {0x6BFC, 0x6BFC}, {0x6BFD, 0x6BFD}, {0x6BFE, 0x6BFE}, + {0x6BFF, 0x6BFF}, {0x6C00, 0x6C00}, {0x6C01, 0x6C01}, {0x6C02, 0x6C02}, {0x6C03, 0x6C03}, {0x6C04, 0x6C04}, {0x6C05, 0x6C05}, + {0x6C06, 0x6C06}, {0x6C07, 0x6C07}, {0x6C08, 0x6C08}, {0x6C09, 0x6C09}, {0x6C0A, 0x6C0A}, {0x6C0B, 0x6C0B}, {0x6C0C, 0x6C0C}, + {0x6C0D, 0x6C0D}, {0x6C0E, 0x6C0E}, {0x6C0F, 0x6C0F}, {0x6C10, 0x6C10}, {0x6C11, 0x6C11}, {0x6C12, 0x6C12}, {0x6C13, 0x6C13}, + {0x6C14, 0x6C14}, {0x6C15, 0x6C15}, {0x6C16, 0x6C16}, {0x6C17, 0x6C17}, {0x6C18, 0x6C18}, {0x6C19, 0x6C19}, {0x6C1A, 0x6C1A}, + {0x6C1B, 0x6C1B}, {0x6C1C, 0x6C1C}, {0x6C1D, 0x6C1D}, {0x6C1E, 0x6C1E}, {0x6C1F, 0x6C1F}, {0x6C20, 0x6C20}, {0x6C21, 0x6C21}, + {0x6C22, 0x6C22}, {0x6C23, 0x6C23}, {0x6C24, 0x6C24}, {0x6C25, 0x6C25}, {0x6C26, 0x6C26}, {0x6C27, 0x6C27}, {0x6C28, 0x6C28}, + {0x6C29, 0x6C29}, {0x6C2A, 0x6C2A}, {0x6C2B, 0x6C2B}, {0x6C2C, 0x6C2C}, {0x6C2D, 0x6C2D}, {0x6C2E, 0x6C2E}, {0x6C2F, 0x6C2F}, + {0x6C30, 0x6C30}, {0x6C31, 0x6C31}, {0x6C32, 0x6C32}, {0x6C33, 0x6C33}, {0x6C34, 0x6C34}, {0x6C35, 0x6C35}, {0x6C36, 0x6C36}, + {0x6C37, 0x6C37}, {0x6C38, 0x6C38}, {0x6C39, 0x6C39}, {0x6C3A, 0x6C3A}, {0x6C3B, 0x6C3B}, {0x6C3C, 0x6C3C}, {0x6C3D, 0x6C3D}, + {0x6C3E, 0x6C3E}, {0x6C3F, 0x6C3F}, {0x6C40, 0x6C40}, {0x6C41, 0x6C41}, {0x6C42, 0x6C42}, {0x6C43, 0x6C43}, {0x6C44, 0x6C44}, + {0x6C45, 0x6C45}, {0x6C46, 0x6C46}, {0x6C47, 0x6C47}, {0x6C48, 0x6C48}, {0x6C49, 0x6C49}, {0x6C4A, 0x6C4A}, {0x6C4B, 0x6C4B}, + {0x6C4C, 0x6C4C}, {0x6C4D, 0x6C4D}, {0x6C4E, 0x6C4E}, {0x6C4F, 0x6C4F}, {0x6C50, 0x6C50}, {0x6C51, 0x6C51}, {0x6C52, 0x6C52}, + {0x6C53, 0x6C53}, {0x6C54, 0x6C54}, {0x6C55, 0x6C55}, {0x6C56, 0x6C56}, {0x6C57, 0x6C57}, {0x6C58, 0x6C58}, {0x6C59, 0x6C59}, + {0x6C5A, 0x6C5A}, {0x6C5B, 0x6C5B}, {0x6C5C, 0x6C5C}, {0x6C5D, 0x6C5D}, {0x6C5E, 0x6C5E}, {0x6C5F, 0x6C5F}, {0x6C60, 0x6C60}, + {0x6C61, 0x6C61}, {0x6C62, 0x6C62}, {0x6C63, 0x6C63}, {0x6C64, 0x6C64}, {0x6C65, 0x6C65}, {0x6C66, 0x6C66}, {0x6C67, 0x6C67}, + {0x6C68, 0x6C68}, {0x6C69, 0x6C69}, {0x6C6A, 0x6C6A}, {0x6C6B, 0x6C6B}, {0x6C6C, 0x6C6C}, {0x6C6D, 0x6C6D}, {0x6C6E, 0x6C6E}, + {0x6C6F, 0x6C6F}, {0x6C70, 0x6C70}, {0x6C71, 0x6C71}, {0x6C72, 0x6C72}, {0x6C73, 0x6C73}, {0x6C74, 0x6C74}, {0x6C75, 0x6C75}, + {0x6C76, 0x6C76}, {0x6C77, 0x6C77}, {0x6C78, 0x6C78}, {0x6C79, 0x6C79}, {0x6C7A, 0x6C7A}, {0x6C7B, 0x6C7B}, {0x6C7C, 0x6C7C}, + {0x6C7D, 0x6C7D}, {0x6C7E, 0x6C7E}, {0x6C7F, 0x6C7F}, {0x6C80, 0x6C80}, {0x6C81, 0x6C81}, {0x6C82, 0x6C82}, {0x6C83, 0x6C83}, + {0x6C84, 0x6C84}, {0x6C85, 0x6C85}, {0x6C86, 0x6C86}, {0x6C87, 0x6C87}, {0x6C88, 0x6C88}, {0x6C89, 0x6C89}, {0x6C8A, 0x6C8A}, + {0x6C8B, 0x6C8B}, {0x6C8C, 0x6C8C}, {0x6C8D, 0x6C8D}, {0x6C8E, 0x6C8E}, {0x6C8F, 0x6C8F}, {0x6C90, 0x6C90}, {0x6C91, 0x6C91}, + {0x6C92, 0x6C92}, {0x6C93, 0x6C93}, {0x6C94, 0x6C94}, {0x6C95, 0x6C95}, {0x6C96, 0x6C96}, {0x6C97, 0x6C97}, {0x6C98, 0x6C98}, + {0x6C99, 0x6C99}, {0x6C9A, 0x6C9A}, {0x6C9B, 0x6C9B}, {0x6C9C, 0x6C9C}, {0x6C9D, 0x6C9D}, {0x6C9E, 0x6C9E}, {0x6C9F, 0x6C9F}, + {0x6CA0, 0x6CA0}, {0x6CA1, 0x6CA1}, {0x6CA2, 0x6CA2}, {0x6CA3, 0x6CA3}, {0x6CA4, 0x6CA4}, {0x6CA5, 0x6CA5}, {0x6CA6, 0x6CA6}, + {0x6CA7, 0x6CA7}, {0x6CA8, 0x6CA8}, {0x6CA9, 0x6CA9}, {0x6CAA, 0x6CAA}, {0x6CAB, 0x6CAB}, {0x6CAC, 0x6CAC}, {0x6CAD, 0x6CAD}, + {0x6CAE, 0x6CAE}, {0x6CAF, 0x6CAF}, {0x6CB0, 0x6CB0}, {0x6CB1, 0x6CB1}, {0x6CB2, 0x6CB2}, {0x6CB3, 0x6CB3}, {0x6CB4, 0x6CB4}, + {0x6CB5, 0x6CB5}, {0x6CB6, 0x6CB6}, {0x6CB7, 0x6CB7}, {0x6CB8, 0x6CB8}, {0x6CB9, 0x6CB9}, {0x6CBA, 0x6CBA}, {0x6CBB, 0x6CBB}, + {0x6CBC, 0x6CBC}, {0x6CBD, 0x6CBD}, {0x6CBE, 0x6CBE}, {0x6CBF, 0x6CBF}, {0x6CC0, 0x6CC0}, {0x6CC1, 0x6CC1}, {0x6CC2, 0x6CC2}, + {0x6CC3, 0x6CC3}, {0x6CC4, 0x6CC4}, {0x6CC5, 0x6CC5}, {0x6CC6, 0x6CC6}, {0x6CC7, 0x6CC7}, {0x6CC8, 0x6CC8}, {0x6CC9, 0x6CC9}, + {0x6CCA, 0x6CCA}, {0x6CCB, 0x6CCB}, {0x6CCC, 0x6CCC}, {0x6CCD, 0x6CCD}, {0x6CCE, 0x6CCE}, {0x6CCF, 0x6CCF}, {0x6CD0, 0x6CD0}, + {0x6CD1, 0x6CD1}, {0x6CD2, 0x6CD2}, {0x6CD3, 0x6CD3}, {0x6CD4, 0x6CD4}, {0x6CD5, 0x6CD5}, {0x6CD6, 0x6CD6}, {0x6CD7, 0x6CD7}, + {0x6CD8, 0x6CD8}, {0x6CD9, 0x6CD9}, {0x6CDA, 0x6CDA}, {0x6CDB, 0x6CDB}, {0x6CDC, 0x6CDC}, {0x6CDD, 0x6CDD}, {0x6CDE, 0x6CDE}, + {0x6CDF, 0x6CDF}, {0x6CE0, 0x6CE0}, {0x6CE1, 0x6CE1}, {0x6CE2, 0x6CE2}, {0x6CE3, 0x6CE3}, {0x6CE4, 0x6CE4}, {0x6CE5, 0x6CE5}, + {0x6CE6, 0x6CE6}, {0x6CE7, 0x6CE7}, {0x6CE8, 0x6CE8}, {0x6CE9, 0x6CE9}, {0x6CEA, 0x6CEA}, {0x6CEB, 0x6CEB}, {0x6CEC, 0x6CEC}, + {0x6CED, 0x6CED}, {0x6CEE, 0x6CEE}, {0x6CEF, 0x6CEF}, {0x6CF0, 0x6CF0}, {0x6CF1, 0x6CF1}, {0x6CF2, 0x6CF2}, {0x6CF3, 0x6CF3}, + {0x6CF4, 0x6CF4}, {0x6CF5, 0x6CF5}, {0x6CF6, 0x6CF6}, {0x6CF7, 0x6CF7}, {0x6CF8, 0x6CF8}, {0x6CF9, 0x6CF9}, {0x6CFA, 0x6CFA}, + {0x6CFB, 0x6CFB}, {0x6CFC, 0x6CFC}, {0x6CFD, 0x6CFD}, {0x6CFE, 0x6CFE}, {0x6CFF, 0x6CFF}, {0x6D00, 0x6D00}, {0x6D01, 0x6D01}, + {0x6D02, 0x6D02}, {0x6D03, 0x6D03}, {0x6D04, 0x6D04}, {0x6D05, 0x6D05}, {0x6D06, 0x6D06}, {0x6D07, 0x6D07}, {0x6D08, 0x6D08}, + {0x6D09, 0x6D09}, {0x6D0A, 0x6D0A}, {0x6D0B, 0x6D0B}, {0x6D0C, 0x6D0C}, {0x6D0D, 0x6D0D}, {0x6D0E, 0x6D0E}, {0x6D0F, 0x6D0F}, + {0x6D10, 0x6D10}, {0x6D11, 0x6D11}, {0x6D12, 0x6D12}, {0x6D13, 0x6D13}, {0x6D14, 0x6D14}, {0x6D15, 0x6D15}, {0x6D16, 0x6D16}, + {0x6D17, 0x6D17}, {0x6D18, 0x6D18}, {0x6D19, 0x6D19}, {0x6D1A, 0x6D1A}, {0x6D1B, 0x6D1B}, {0x6D1C, 0x6D1C}, {0x6D1D, 0x6D1D}, + {0x6D1E, 0x6D1E}, {0x6D1F, 0x6D1F}, {0x6D20, 0x6D20}, {0x6D21, 0x6D21}, {0x6D22, 0x6D22}, {0x6D23, 0x6D23}, {0x6D24, 0x6D24}, + {0x6D25, 0x6D25}, {0x6D26, 0x6D26}, {0x6D27, 0x6D27}, {0x6D28, 0x6D28}, {0x6D29, 0x6D29}, {0x6D2A, 0x6D2A}, {0x6D2B, 0x6D2B}, + {0x6D2C, 0x6D2C}, {0x6D2D, 0x6D2D}, {0x6D2E, 0x6D2E}, {0x6D2F, 0x6D2F}, {0x6D30, 0x6D30}, {0x6D31, 0x6D31}, {0x6D32, 0x6D32}, + {0x6D33, 0x6D33}, {0x6D34, 0x6D34}, {0x6D35, 0x6D35}, {0x6D36, 0x6D36}, {0x6D37, 0x6D37}, {0x6D38, 0x6D38}, {0x6D39, 0x6D39}, + {0x6D3A, 0x6D3A}, {0x6D3B, 0x6D3B}, {0x6D3C, 0x6D3C}, {0x6D3D, 0x6D3D}, {0x6D3E, 0x6D3E}, {0x6D3F, 0x6D3F}, {0x6D40, 0x6D40}, + {0x6D41, 0x6D41}, {0x6D42, 0x6D42}, {0x6D43, 0x6D43}, {0x6D44, 0x6D44}, {0x6D45, 0x6D45}, {0x6D46, 0x6D46}, {0x6D47, 0x6D47}, + {0x6D48, 0x6D48}, {0x6D49, 0x6D49}, {0x6D4A, 0x6D4A}, {0x6D4B, 0x6D4B}, {0x6D4C, 0x6D4C}, {0x6D4D, 0x6D4D}, {0x6D4E, 0x6D4E}, + {0x6D4F, 0x6D4F}, {0x6D50, 0x6D50}, {0x6D51, 0x6D51}, {0x6D52, 0x6D52}, {0x6D53, 0x6D53}, {0x6D54, 0x6D54}, {0x6D55, 0x6D55}, + {0x6D56, 0x6D56}, {0x6D57, 0x6D57}, {0x6D58, 0x6D58}, {0x6D59, 0x6D59}, {0x6D5A, 0x6D5A}, {0x6D5B, 0x6D5B}, {0x6D5C, 0x6D5C}, + {0x6D5D, 0x6D5D}, {0x6D5E, 0x6D5E}, {0x6D5F, 0x6D5F}, {0x6D60, 0x6D60}, {0x6D61, 0x6D61}, {0x6D62, 0x6D62}, {0x6D63, 0x6D63}, + {0x6D64, 0x6D64}, {0x6D65, 0x6D65}, {0x6D66, 0x6D66}, {0x6D67, 0x6D67}, {0x6D68, 0x6D68}, {0x6D69, 0x6D69}, {0x6D6A, 0x6D6A}, + {0x6D6B, 0x6D6B}, {0x6D6C, 0x6D6C}, {0x6D6D, 0x6D6D}, {0x6D6E, 0x6D6E}, {0x6D6F, 0x6D6F}, {0x6D70, 0x6D70}, {0x6D71, 0x6D71}, + {0x6D72, 0x6D72}, {0x6D73, 0x6D73}, {0x6D74, 0x6D74}, {0x6D75, 0x6D75}, {0x6D76, 0x6D76}, {0x6D77, 0x6D77}, {0x6D78, 0x6D78}, + {0x6D79, 0x6D79}, {0x6D7A, 0x6D7A}, {0x6D7B, 0x6D7B}, {0x6D7C, 0x6D7C}, {0x6D7D, 0x6D7D}, {0x6D7E, 0x6D7E}, {0x6D7F, 0x6D7F}, + {0x6D80, 0x6D80}, {0x6D81, 0x6D81}, {0x6D82, 0x6D82}, {0x6D83, 0x6D83}, {0x6D84, 0x6D84}, {0x6D85, 0x6D85}, {0x6D86, 0x6D86}, + {0x6D87, 0x6D87}, {0x6D88, 0x6D88}, {0x6D89, 0x6D89}, {0x6D8A, 0x6D8A}, {0x6D8B, 0x6D8B}, {0x6D8C, 0x6D8C}, {0x6D8D, 0x6D8D}, + {0x6D8E, 0x6D8E}, {0x6D8F, 0x6D8F}, {0x6D90, 0x6D90}, {0x6D91, 0x6D91}, {0x6D92, 0x6D92}, {0x6D93, 0x6D93}, {0x6D94, 0x6D94}, + {0x6D95, 0x6D95}, {0x6D96, 0x6D96}, {0x6D97, 0x6D97}, {0x6D98, 0x6D98}, {0x6D99, 0x6D99}, {0x6D9A, 0x6D9A}, {0x6D9B, 0x6D9B}, + {0x6D9C, 0x6D9C}, {0x6D9D, 0x6D9D}, {0x6D9E, 0x6D9E}, {0x6D9F, 0x6D9F}, {0x6DA0, 0x6DA0}, {0x6DA1, 0x6DA1}, {0x6DA2, 0x6DA2}, + {0x6DA3, 0x6DA3}, {0x6DA4, 0x6DA4}, {0x6DA5, 0x6DA5}, {0x6DA6, 0x6DA6}, {0x6DA7, 0x6DA7}, {0x6DA8, 0x6DA8}, {0x6DA9, 0x6DA9}, + {0x6DAA, 0x6DAA}, {0x6DAB, 0x6DAB}, {0x6DAC, 0x6DAC}, {0x6DAD, 0x6DAD}, {0x6DAE, 0x6DAE}, {0x6DAF, 0x6DAF}, {0x6DB0, 0x6DB0}, + {0x6DB1, 0x6DB1}, {0x6DB2, 0x6DB2}, {0x6DB3, 0x6DB3}, {0x6DB4, 0x6DB4}, {0x6DB5, 0x6DB5}, {0x6DB6, 0x6DB6}, {0x6DB7, 0x6DB7}, + {0x6DB8, 0x6DB8}, {0x6DB9, 0x6DB9}, {0x6DBA, 0x6DBA}, {0x6DBB, 0x6DBB}, {0x6DBC, 0x6DBC}, {0x6DBD, 0x6DBD}, {0x6DBE, 0x6DBE}, + {0x6DBF, 0x6DBF}, {0x6DC0, 0x6DC0}, {0x6DC1, 0x6DC1}, {0x6DC2, 0x6DC2}, {0x6DC3, 0x6DC3}, {0x6DC4, 0x6DC4}, {0x6DC5, 0x6DC5}, + {0x6DC6, 0x6DC6}, {0x6DC7, 0x6DC7}, {0x6DC8, 0x6DC8}, {0x6DC9, 0x6DC9}, {0x6DCA, 0x6DCA}, {0x6DCB, 0x6DCB}, {0x6DCC, 0x6DCC}, + {0x6DCD, 0x6DCD}, {0x6DCE, 0x6DCE}, {0x6DCF, 0x6DCF}, {0x6DD0, 0x6DD0}, {0x6DD1, 0x6DD1}, {0x6DD2, 0x6DD2}, {0x6DD3, 0x6DD3}, + {0x6DD4, 0x6DD4}, {0x6DD5, 0x6DD5}, {0x6DD6, 0x6DD6}, {0x6DD7, 0x6DD7}, {0x6DD8, 0x6DD8}, {0x6DD9, 0x6DD9}, {0x6DDA, 0x6DDA}, + {0x6DDB, 0x6DDB}, {0x6DDC, 0x6DDC}, {0x6DDD, 0x6DDD}, {0x6DDE, 0x6DDE}, {0x6DDF, 0x6DDF}, {0x6DE0, 0x6DE0}, {0x6DE1, 0x6DE1}, + {0x6DE2, 0x6DE2}, {0x6DE3, 0x6DE3}, {0x6DE4, 0x6DE4}, {0x6DE5, 0x6DE5}, {0x6DE6, 0x6DE6}, {0x6DE7, 0x6DE7}, {0x6DE8, 0x6DE8}, + {0x6DE9, 0x6DE9}, {0x6DEA, 0x6DEA}, {0x6DEB, 0x6DEB}, {0x6DEC, 0x6DEC}, {0x6DED, 0x6DED}, {0x6DEE, 0x6DEE}, {0x6DEF, 0x6DEF}, + {0x6DF0, 0x6DF0}, {0x6DF1, 0x6DF1}, {0x6DF2, 0x6DF2}, {0x6DF3, 0x6DF3}, {0x6DF4, 0x6DF4}, {0x6DF5, 0x6DF5}, {0x6DF6, 0x6DF6}, + {0x6DF7, 0x6DF7}, {0x6DF8, 0x6DF8}, {0x6DF9, 0x6DF9}, {0x6DFA, 0x6DFA}, {0x6DFB, 0x6DFB}, {0x6DFC, 0x6DFC}, {0x6DFD, 0x6DFD}, + {0x6DFE, 0x6DFE}, {0x6DFF, 0x6DFF}, {0x6E00, 0x6E00}, {0x6E01, 0x6E01}, {0x6E02, 0x6E02}, {0x6E03, 0x6E03}, {0x6E04, 0x6E04}, + {0x6E05, 0x6E05}, {0x6E06, 0x6E06}, {0x6E07, 0x6E07}, {0x6E08, 0x6E08}, {0x6E09, 0x6E09}, {0x6E0A, 0x6E0A}, {0x6E0B, 0x6E0B}, + {0x6E0C, 0x6E0C}, {0x6E0D, 0x6E0D}, {0x6E0E, 0x6E0E}, {0x6E0F, 0x6E0F}, {0x6E10, 0x6E10}, {0x6E11, 0x6E11}, {0x6E12, 0x6E12}, + {0x6E13, 0x6E13}, {0x6E14, 0x6E14}, {0x6E15, 0x6E15}, {0x6E16, 0x6E16}, {0x6E17, 0x6E17}, {0x6E18, 0x6E18}, {0x6E19, 0x6E19}, + {0x6E1A, 0x6E1A}, {0x6E1B, 0x6E1B}, {0x6E1C, 0x6E1C}, {0x6E1D, 0x6E1D}, {0x6E1E, 0x6E1E}, {0x6E1F, 0x6E1F}, {0x6E20, 0x6E20}, + {0x6E21, 0x6E21}, {0x6E22, 0x6E22}, {0x6E23, 0x6E23}, {0x6E24, 0x6E24}, {0x6E25, 0x6E25}, {0x6E26, 0x6E26}, {0x6E27, 0x6E27}, + {0x6E28, 0x6E28}, {0x6E29, 0x6E29}, {0x6E2A, 0x6E2A}, {0x6E2B, 0x6E2B}, {0x6E2C, 0x6E2C}, {0x6E2D, 0x6E2D}, {0x6E2E, 0x6E2E}, + {0x6E2F, 0x6E2F}, {0x6E30, 0x6E30}, {0x6E31, 0x6E31}, {0x6E32, 0x6E32}, {0x6E33, 0x6E33}, {0x6E34, 0x6E34}, {0x6E35, 0x6E35}, + {0x6E36, 0x6E36}, {0x6E37, 0x6E37}, {0x6E38, 0x6E38}, {0x6E39, 0x6E39}, {0x6E3A, 0x6E3A}, {0x6E3B, 0x6E3B}, {0x6E3C, 0x6E3C}, + {0x6E3D, 0x6E3D}, {0x6E3E, 0x6E3E}, {0x6E3F, 0x6E3F}, {0x6E40, 0x6E40}, {0x6E41, 0x6E41}, {0x6E42, 0x6E42}, {0x6E43, 0x6E43}, + {0x6E44, 0x6E44}, {0x6E45, 0x6E45}, {0x6E46, 0x6E46}, {0x6E47, 0x6E47}, {0x6E48, 0x6E48}, {0x6E49, 0x6E49}, {0x6E4A, 0x6E4A}, + {0x6E4B, 0x6E4B}, {0x6E4C, 0x6E4C}, {0x6E4D, 0x6E4D}, {0x6E4E, 0x6E4E}, {0x6E4F, 0x6E4F}, {0x6E50, 0x6E50}, {0x6E51, 0x6E51}, + {0x6E52, 0x6E52}, {0x6E53, 0x6E53}, {0x6E54, 0x6E54}, {0x6E55, 0x6E55}, {0x6E56, 0x6E56}, {0x6E57, 0x6E57}, {0x6E58, 0x6E58}, + {0x6E59, 0x6E59}, {0x6E5A, 0x6E5A}, {0x6E5B, 0x6E5B}, {0x6E5C, 0x6E5C}, {0x6E5D, 0x6E5D}, {0x6E5E, 0x6E5E}, {0x6E5F, 0x6E5F}, + {0x6E60, 0x6E60}, {0x6E61, 0x6E61}, {0x6E62, 0x6E62}, {0x6E63, 0x6E63}, {0x6E64, 0x6E64}, {0x6E65, 0x6E65}, {0x6E66, 0x6E66}, + {0x6E67, 0x6E67}, {0x6E68, 0x6E68}, {0x6E69, 0x6E69}, {0x6E6A, 0x6E6A}, {0x6E6B, 0x6E6B}, {0x6E6C, 0x6E6C}, {0x6E6D, 0x6E6D}, + {0x6E6E, 0x6E6E}, {0x6E6F, 0x6E6F}, {0x6E70, 0x6E70}, {0x6E71, 0x6E71}, {0x6E72, 0x6E72}, {0x6E73, 0x6E73}, {0x6E74, 0x6E74}, + {0x6E75, 0x6E75}, {0x6E76, 0x6E76}, {0x6E77, 0x6E77}, {0x6E78, 0x6E78}, {0x6E79, 0x6E79}, {0x6E7A, 0x6E7A}, {0x6E7B, 0x6E7B}, + {0x6E7C, 0x6E7C}, {0x6E7D, 0x6E7D}, {0x6E7E, 0x6E7E}, {0x6E7F, 0x6E7F}, {0x6E80, 0x6E80}, {0x6E81, 0x6E81}, {0x6E82, 0x6E82}, + {0x6E83, 0x6E83}, {0x6E84, 0x6E84}, {0x6E85, 0x6E85}, {0x6E86, 0x6E86}, {0x6E87, 0x6E87}, {0x6E88, 0x6E88}, {0x6E89, 0x6E89}, + {0x6E8A, 0x6E8A}, {0x6E8B, 0x6E8B}, {0x6E8C, 0x6E8C}, {0x6E8D, 0x6E8D}, {0x6E8E, 0x6E8E}, {0x6E8F, 0x6E8F}, {0x6E90, 0x6E90}, + {0x6E91, 0x6E91}, {0x6E92, 0x6E92}, {0x6E93, 0x6E93}, {0x6E94, 0x6E94}, {0x6E95, 0x6E95}, {0x6E96, 0x6E96}, {0x6E97, 0x6E97}, + {0x6E98, 0x6E98}, {0x6E99, 0x6E99}, {0x6E9A, 0x6E9A}, {0x6E9B, 0x6E9B}, {0x6E9C, 0x6E9C}, {0x6E9D, 0x6E9D}, {0x6E9E, 0x6E9E}, + {0x6E9F, 0x6E9F}, {0x6EA0, 0x6EA0}, {0x6EA1, 0x6EA1}, {0x6EA2, 0x6EA2}, {0x6EA3, 0x6EA3}, {0x6EA4, 0x6EA4}, {0x6EA5, 0x6EA5}, + {0x6EA6, 0x6EA6}, {0x6EA7, 0x6EA7}, {0x6EA8, 0x6EA8}, {0x6EA9, 0x6EA9}, {0x6EAA, 0x6EAA}, {0x6EAB, 0x6EAB}, {0x6EAC, 0x6EAC}, + {0x6EAD, 0x6EAD}, {0x6EAE, 0x6EAE}, {0x6EAF, 0x6EAF}, {0x6EB0, 0x6EB0}, {0x6EB1, 0x6EB1}, {0x6EB2, 0x6EB2}, {0x6EB3, 0x6EB3}, + {0x6EB4, 0x6EB4}, {0x6EB5, 0x6EB5}, {0x6EB6, 0x6EB6}, {0x6EB7, 0x6EB7}, {0x6EB8, 0x6EB8}, {0x6EB9, 0x6EB9}, {0x6EBA, 0x6EBA}, + {0x6EBB, 0x6EBB}, {0x6EBC, 0x6EBC}, {0x6EBD, 0x6EBD}, {0x6EBE, 0x6EBE}, {0x6EBF, 0x6EBF}, {0x6EC0, 0x6EC0}, {0x6EC1, 0x6EC1}, + {0x6EC2, 0x6EC2}, {0x6EC3, 0x6EC3}, {0x6EC4, 0x6EC4}, {0x6EC5, 0x6EC5}, {0x6EC6, 0x6EC6}, {0x6EC7, 0x6EC7}, {0x6EC8, 0x6EC8}, + {0x6EC9, 0x6EC9}, {0x6ECA, 0x6ECA}, {0x6ECB, 0x6ECB}, {0x6ECC, 0x6ECC}, {0x6ECD, 0x6ECD}, {0x6ECE, 0x6ECE}, {0x6ECF, 0x6ECF}, + {0x6ED0, 0x6ED0}, {0x6ED1, 0x6ED1}, {0x6ED2, 0x6ED2}, {0x6ED3, 0x6ED3}, {0x6ED4, 0x6ED4}, {0x6ED5, 0x6ED5}, {0x6ED6, 0x6ED6}, + {0x6ED7, 0x6ED7}, {0x6ED8, 0x6ED8}, {0x6ED9, 0x6ED9}, {0x6EDA, 0x6EDA}, {0x6EDB, 0x6EDB}, {0x6EDC, 0x6EDC}, {0x6EDD, 0x6EDD}, + {0x6EDE, 0x6EDE}, {0x6EDF, 0x6EDF}, {0x6EE0, 0x6EE0}, {0x6EE1, 0x6EE1}, {0x6EE2, 0x6EE2}, {0x6EE3, 0x6EE3}, {0x6EE4, 0x6EE4}, + {0x6EE5, 0x6EE5}, {0x6EE6, 0x6EE6}, {0x6EE7, 0x6EE7}, {0x6EE8, 0x6EE8}, {0x6EE9, 0x6EE9}, {0x6EEA, 0x6EEA}, {0x6EEB, 0x6EEB}, + {0x6EEC, 0x6EEC}, {0x6EED, 0x6EED}, {0x6EEE, 0x6EEE}, {0x6EEF, 0x6EEF}, {0x6EF0, 0x6EF0}, {0x6EF1, 0x6EF1}, {0x6EF2, 0x6EF2}, + {0x6EF3, 0x6EF3}, {0x6EF4, 0x6EF4}, {0x6EF5, 0x6EF5}, {0x6EF6, 0x6EF6}, {0x6EF7, 0x6EF7}, {0x6EF8, 0x6EF8}, {0x6EF9, 0x6EF9}, + {0x6EFA, 0x6EFA}, {0x6EFB, 0x6EFB}, {0x6EFC, 0x6EFC}, {0x6EFD, 0x6EFD}, {0x6EFE, 0x6EFE}, {0x6EFF, 0x6EFF}, {0x6F00, 0x6F00}, + {0x6F01, 0x6F01}, {0x6F02, 0x6F02}, {0x6F03, 0x6F03}, {0x6F04, 0x6F04}, {0x6F05, 0x6F05}, {0x6F06, 0x6F06}, {0x6F07, 0x6F07}, + {0x6F08, 0x6F08}, {0x6F09, 0x6F09}, {0x6F0A, 0x6F0A}, {0x6F0B, 0x6F0B}, {0x6F0C, 0x6F0C}, {0x6F0D, 0x6F0D}, {0x6F0E, 0x6F0E}, + {0x6F0F, 0x6F0F}, {0x6F10, 0x6F10}, {0x6F11, 0x6F11}, {0x6F12, 0x6F12}, {0x6F13, 0x6F13}, {0x6F14, 0x6F14}, {0x6F15, 0x6F15}, + {0x6F16, 0x6F16}, {0x6F17, 0x6F17}, {0x6F18, 0x6F18}, {0x6F19, 0x6F19}, {0x6F1A, 0x6F1A}, {0x6F1B, 0x6F1B}, {0x6F1C, 0x6F1C}, + {0x6F1D, 0x6F1D}, {0x6F1E, 0x6F1E}, {0x6F1F, 0x6F1F}, {0x6F20, 0x6F20}, {0x6F21, 0x6F21}, {0x6F22, 0x6F22}, {0x6F23, 0x6F23}, + {0x6F24, 0x6F24}, {0x6F25, 0x6F25}, {0x6F26, 0x6F26}, {0x6F27, 0x6F27}, {0x6F28, 0x6F28}, {0x6F29, 0x6F29}, {0x6F2A, 0x6F2A}, + {0x6F2B, 0x6F2B}, {0x6F2C, 0x6F2C}, {0x6F2D, 0x6F2D}, {0x6F2E, 0x6F2E}, {0x6F2F, 0x6F2F}, {0x6F30, 0x6F30}, {0x6F31, 0x6F31}, + {0x6F32, 0x6F32}, {0x6F33, 0x6F33}, {0x6F34, 0x6F34}, {0x6F35, 0x6F35}, {0x6F36, 0x6F36}, {0x6F37, 0x6F37}, {0x6F38, 0x6F38}, + {0x6F39, 0x6F39}, {0x6F3A, 0x6F3A}, {0x6F3B, 0x6F3B}, {0x6F3C, 0x6F3C}, {0x6F3D, 0x6F3D}, {0x6F3E, 0x6F3E}, {0x6F3F, 0x6F3F}, + {0x6F40, 0x6F40}, {0x6F41, 0x6F41}, {0x6F42, 0x6F42}, {0x6F43, 0x6F43}, {0x6F44, 0x6F44}, {0x6F45, 0x6F45}, {0x6F46, 0x6F46}, + {0x6F47, 0x6F47}, {0x6F48, 0x6F48}, {0x6F49, 0x6F49}, {0x6F4A, 0x6F4A}, {0x6F4B, 0x6F4B}, {0x6F4C, 0x6F4C}, {0x6F4D, 0x6F4D}, + {0x6F4E, 0x6F4E}, {0x6F4F, 0x6F4F}, {0x6F50, 0x6F50}, {0x6F51, 0x6F51}, {0x6F52, 0x6F52}, {0x6F53, 0x6F53}, {0x6F54, 0x6F54}, + {0x6F55, 0x6F55}, {0x6F56, 0x6F56}, {0x6F57, 0x6F57}, {0x6F58, 0x6F58}, {0x6F59, 0x6F59}, {0x6F5A, 0x6F5A}, {0x6F5B, 0x6F5B}, + {0x6F5C, 0x6F5C}, {0x6F5D, 0x6F5D}, {0x6F5E, 0x6F5E}, {0x6F5F, 0x6F5F}, {0x6F60, 0x6F60}, {0x6F61, 0x6F61}, {0x6F62, 0x6F62}, + {0x6F63, 0x6F63}, {0x6F64, 0x6F64}, {0x6F65, 0x6F65}, {0x6F66, 0x6F66}, {0x6F67, 0x6F67}, {0x6F68, 0x6F68}, {0x6F69, 0x6F69}, + {0x6F6A, 0x6F6A}, {0x6F6B, 0x6F6B}, {0x6F6C, 0x6F6C}, {0x6F6D, 0x6F6D}, {0x6F6E, 0x6F6E}, {0x6F6F, 0x6F6F}, {0x6F70, 0x6F70}, + {0x6F71, 0x6F71}, {0x6F72, 0x6F72}, {0x6F73, 0x6F73}, {0x6F74, 0x6F74}, {0x6F75, 0x6F75}, {0x6F76, 0x6F76}, {0x6F77, 0x6F77}, + {0x6F78, 0x6F78}, {0x6F79, 0x6F79}, {0x6F7A, 0x6F7A}, {0x6F7B, 0x6F7B}, {0x6F7C, 0x6F7C}, {0x6F7D, 0x6F7D}, {0x6F7E, 0x6F7E}, + {0x6F7F, 0x6F7F}, {0x6F80, 0x6F80}, {0x6F81, 0x6F81}, {0x6F82, 0x6F82}, {0x6F83, 0x6F83}, {0x6F84, 0x6F84}, {0x6F85, 0x6F85}, + {0x6F86, 0x6F86}, {0x6F87, 0x6F87}, {0x6F88, 0x6F88}, {0x6F89, 0x6F89}, {0x6F8A, 0x6F8A}, {0x6F8B, 0x6F8B}, {0x6F8C, 0x6F8C}, + {0x6F8D, 0x6F8D}, {0x6F8E, 0x6F8E}, {0x6F8F, 0x6F8F}, {0x6F90, 0x6F90}, {0x6F91, 0x6F91}, {0x6F92, 0x6F92}, {0x6F93, 0x6F93}, + {0x6F94, 0x6F94}, {0x6F95, 0x6F95}, {0x6F96, 0x6F96}, {0x6F97, 0x6F97}, {0x6F98, 0x6F98}, {0x6F99, 0x6F99}, {0x6F9A, 0x6F9A}, + {0x6F9B, 0x6F9B}, {0x6F9C, 0x6F9C}, {0x6F9D, 0x6F9D}, {0x6F9E, 0x6F9E}, {0x6F9F, 0x6F9F}, {0x6FA0, 0x6FA0}, {0x6FA1, 0x6FA1}, + {0x6FA2, 0x6FA2}, {0x6FA3, 0x6FA3}, {0x6FA4, 0x6FA4}, {0x6FA5, 0x6FA5}, {0x6FA6, 0x6FA6}, {0x6FA7, 0x6FA7}, {0x6FA8, 0x6FA8}, + {0x6FA9, 0x6FA9}, {0x6FAA, 0x6FAA}, {0x6FAB, 0x6FAB}, {0x6FAC, 0x6FAC}, {0x6FAD, 0x6FAD}, {0x6FAE, 0x6FAE}, {0x6FAF, 0x6FAF}, + {0x6FB0, 0x6FB0}, {0x6FB1, 0x6FB1}, {0x6FB2, 0x6FB2}, {0x6FB3, 0x6FB3}, {0x6FB4, 0x6FB4}, {0x6FB5, 0x6FB5}, {0x6FB6, 0x6FB6}, + {0x6FB7, 0x6FB7}, {0x6FB8, 0x6FB8}, {0x6FB9, 0x6FB9}, {0x6FBA, 0x6FBA}, {0x6FBB, 0x6FBB}, {0x6FBC, 0x6FBC}, {0x6FBD, 0x6FBD}, + {0x6FBE, 0x6FBE}, {0x6FBF, 0x6FBF}, {0x6FC0, 0x6FC0}, {0x6FC1, 0x6FC1}, {0x6FC2, 0x6FC2}, {0x6FC3, 0x6FC3}, {0x6FC4, 0x6FC4}, + {0x6FC5, 0x6FC5}, {0x6FC6, 0x6FC6}, {0x6FC7, 0x6FC7}, {0x6FC8, 0x6FC8}, {0x6FC9, 0x6FC9}, {0x6FCA, 0x6FCA}, {0x6FCB, 0x6FCB}, + {0x6FCC, 0x6FCC}, {0x6FCD, 0x6FCD}, {0x6FCE, 0x6FCE}, {0x6FCF, 0x6FCF}, {0x6FD0, 0x6FD0}, {0x6FD1, 0x6FD1}, {0x6FD2, 0x6FD2}, + {0x6FD3, 0x6FD3}, {0x6FD4, 0x6FD4}, {0x6FD5, 0x6FD5}, {0x6FD6, 0x6FD6}, {0x6FD7, 0x6FD7}, {0x6FD8, 0x6FD8}, {0x6FD9, 0x6FD9}, + {0x6FDA, 0x6FDA}, {0x6FDB, 0x6FDB}, {0x6FDC, 0x6FDC}, {0x6FDD, 0x6FDD}, {0x6FDE, 0x6FDE}, {0x6FDF, 0x6FDF}, {0x6FE0, 0x6FE0}, + {0x6FE1, 0x6FE1}, {0x6FE2, 0x6FE2}, {0x6FE3, 0x6FE3}, {0x6FE4, 0x6FE4}, {0x6FE5, 0x6FE5}, {0x6FE6, 0x6FE6}, {0x6FE7, 0x6FE7}, + {0x6FE8, 0x6FE8}, {0x6FE9, 0x6FE9}, {0x6FEA, 0x6FEA}, {0x6FEB, 0x6FEB}, {0x6FEC, 0x6FEC}, {0x6FED, 0x6FED}, {0x6FEE, 0x6FEE}, + {0x6FEF, 0x6FEF}, {0x6FF0, 0x6FF0}, {0x6FF1, 0x6FF1}, {0x6FF2, 0x6FF2}, {0x6FF3, 0x6FF3}, {0x6FF4, 0x6FF4}, {0x6FF5, 0x6FF5}, + {0x6FF6, 0x6FF6}, {0x6FF7, 0x6FF7}, {0x6FF8, 0x6FF8}, {0x6FF9, 0x6FF9}, {0x6FFA, 0x6FFA}, {0x6FFB, 0x6FFB}, {0x6FFC, 0x6FFC}, + {0x6FFD, 0x6FFD}, {0x6FFE, 0x6FFE}, {0x6FFF, 0x6FFF}, {0x7000, 0x7000}, {0x7001, 0x7001}, {0x7002, 0x7002}, {0x7003, 0x7003}, + {0x7004, 0x7004}, {0x7005, 0x7005}, {0x7006, 0x7006}, {0x7007, 0x7007}, {0x7008, 0x7008}, {0x7009, 0x7009}, {0x700A, 0x700A}, + {0x700B, 0x700B}, {0x700C, 0x700C}, {0x700D, 0x700D}, {0x700E, 0x700E}, {0x700F, 0x700F}, {0x7010, 0x7010}, {0x7011, 0x7011}, + {0x7012, 0x7012}, {0x7013, 0x7013}, {0x7014, 0x7014}, {0x7015, 0x7015}, {0x7016, 0x7016}, {0x7017, 0x7017}, {0x7018, 0x7018}, + {0x7019, 0x7019}, {0x701A, 0x701A}, {0x701B, 0x701B}, {0x701C, 0x701C}, {0x701D, 0x701D}, {0x701E, 0x701E}, {0x701F, 0x701F}, + {0x7020, 0x7020}, {0x7021, 0x7021}, {0x7022, 0x7022}, {0x7023, 0x7023}, {0x7024, 0x7024}, {0x7025, 0x7025}, {0x7026, 0x7026}, + {0x7027, 0x7027}, {0x7028, 0x7028}, {0x7029, 0x7029}, {0x702A, 0x702A}, {0x702B, 0x702B}, {0x702C, 0x702C}, {0x702D, 0x702D}, + {0x702E, 0x702E}, {0x702F, 0x702F}, {0x7030, 0x7030}, {0x7031, 0x7031}, {0x7032, 0x7032}, {0x7033, 0x7033}, {0x7034, 0x7034}, + {0x7035, 0x7035}, {0x7036, 0x7036}, {0x7037, 0x7037}, {0x7038, 0x7038}, {0x7039, 0x7039}, {0x703A, 0x703A}, {0x703B, 0x703B}, + {0x703C, 0x703C}, {0x703D, 0x703D}, {0x703E, 0x703E}, {0x703F, 0x703F}, {0x7040, 0x7040}, {0x7041, 0x7041}, {0x7042, 0x7042}, + {0x7043, 0x7043}, {0x7044, 0x7044}, {0x7045, 0x7045}, {0x7046, 0x7046}, {0x7047, 0x7047}, {0x7048, 0x7048}, {0x7049, 0x7049}, + {0x704A, 0x704A}, {0x704B, 0x704B}, {0x704C, 0x704C}, {0x704D, 0x704D}, {0x704E, 0x704E}, {0x704F, 0x704F}, {0x7050, 0x7050}, + {0x7051, 0x7051}, {0x7052, 0x7052}, {0x7053, 0x7053}, {0x7054, 0x7054}, {0x7055, 0x7055}, {0x7056, 0x7056}, {0x7057, 0x7057}, + {0x7058, 0x7058}, {0x7059, 0x7059}, {0x705A, 0x705A}, {0x705B, 0x705B}, {0x705C, 0x705C}, {0x705D, 0x705D}, {0x705E, 0x705E}, + {0x705F, 0x705F}, {0x7060, 0x7060}, {0x7061, 0x7061}, {0x7062, 0x7062}, {0x7063, 0x7063}, {0x7064, 0x7064}, {0x7065, 0x7065}, + {0x7066, 0x7066}, {0x7067, 0x7067}, {0x7068, 0x7068}, {0x7069, 0x7069}, {0x706A, 0x706A}, {0x706B, 0x706B}, {0x706C, 0x706C}, + {0x706D, 0x706D}, {0x706E, 0x706E}, {0x706F, 0x706F}, {0x7070, 0x7070}, {0x7071, 0x7071}, {0x7072, 0x7072}, {0x7073, 0x7073}, + {0x7074, 0x7074}, {0x7075, 0x7075}, {0x7076, 0x7076}, {0x7077, 0x7077}, {0x7078, 0x7078}, {0x7079, 0x7079}, {0x707A, 0x707A}, + {0x707B, 0x707B}, {0x707C, 0x707C}, {0x707D, 0x707D}, {0x707E, 0x707E}, {0x707F, 0x707F}, {0x7080, 0x7080}, {0x7081, 0x7081}, + {0x7082, 0x7082}, {0x7083, 0x7083}, {0x7084, 0x7084}, {0x7085, 0x7085}, {0x7086, 0x7086}, {0x7087, 0x7087}, {0x7088, 0x7088}, + {0x7089, 0x7089}, {0x708A, 0x708A}, {0x708B, 0x708B}, {0x708C, 0x708C}, {0x708D, 0x708D}, {0x708E, 0x708E}, {0x708F, 0x708F}, + {0x7090, 0x7090}, {0x7091, 0x7091}, {0x7092, 0x7092}, {0x7093, 0x7093}, {0x7094, 0x7094}, {0x7095, 0x7095}, {0x7096, 0x7096}, + {0x7097, 0x7097}, {0x7098, 0x7098}, {0x7099, 0x7099}, {0x709A, 0x709A}, {0x709B, 0x709B}, {0x709C, 0x709C}, {0x709D, 0x709D}, + {0x709E, 0x709E}, {0x709F, 0x709F}, {0x70A0, 0x70A0}, {0x70A1, 0x70A1}, {0x70A2, 0x70A2}, {0x70A3, 0x70A3}, {0x70A4, 0x70A4}, + {0x70A5, 0x70A5}, {0x70A6, 0x70A6}, {0x70A7, 0x70A7}, {0x70A8, 0x70A8}, {0x70A9, 0x70A9}, {0x70AA, 0x70AA}, {0x70AB, 0x70AB}, + {0x70AC, 0x70AC}, {0x70AD, 0x70AD}, {0x70AE, 0x70AE}, {0x70AF, 0x70AF}, {0x70B0, 0x70B0}, {0x70B1, 0x70B1}, {0x70B2, 0x70B2}, + {0x70B3, 0x70B3}, {0x70B4, 0x70B4}, {0x70B5, 0x70B5}, {0x70B6, 0x70B6}, {0x70B7, 0x70B7}, {0x70B8, 0x70B8}, {0x70B9, 0x70B9}, + {0x70BA, 0x70BA}, {0x70BB, 0x70BB}, {0x70BC, 0x70BC}, {0x70BD, 0x70BD}, {0x70BE, 0x70BE}, {0x70BF, 0x70BF}, {0x70C0, 0x70C0}, + {0x70C1, 0x70C1}, {0x70C2, 0x70C2}, {0x70C3, 0x70C3}, {0x70C4, 0x70C4}, {0x70C5, 0x70C5}, {0x70C6, 0x70C6}, {0x70C7, 0x70C7}, + {0x70C8, 0x70C8}, {0x70C9, 0x70C9}, {0x70CA, 0x70CA}, {0x70CB, 0x70CB}, {0x70CC, 0x70CC}, {0x70CD, 0x70CD}, {0x70CE, 0x70CE}, + {0x70CF, 0x70CF}, {0x70D0, 0x70D0}, {0x70D1, 0x70D1}, {0x70D2, 0x70D2}, {0x70D3, 0x70D3}, {0x70D4, 0x70D4}, {0x70D5, 0x70D5}, + {0x70D6, 0x70D6}, {0x70D7, 0x70D7}, {0x70D8, 0x70D8}, {0x70D9, 0x70D9}, {0x70DA, 0x70DA}, {0x70DB, 0x70DB}, {0x70DC, 0x70DC}, + {0x70DD, 0x70DD}, {0x70DE, 0x70DE}, {0x70DF, 0x70DF}, {0x70E0, 0x70E0}, {0x70E1, 0x70E1}, {0x70E2, 0x70E2}, {0x70E3, 0x70E3}, + {0x70E4, 0x70E4}, {0x70E5, 0x70E5}, {0x70E6, 0x70E6}, {0x70E7, 0x70E7}, {0x70E8, 0x70E8}, {0x70E9, 0x70E9}, {0x70EA, 0x70EA}, + {0x70EB, 0x70EB}, {0x70EC, 0x70EC}, {0x70ED, 0x70ED}, {0x70EE, 0x70EE}, {0x70EF, 0x70EF}, {0x70F0, 0x70F0}, {0x70F1, 0x70F1}, + {0x70F2, 0x70F2}, {0x70F3, 0x70F3}, {0x70F4, 0x70F4}, {0x70F5, 0x70F5}, {0x70F6, 0x70F6}, {0x70F7, 0x70F7}, {0x70F8, 0x70F8}, + {0x70F9, 0x70F9}, {0x70FA, 0x70FA}, {0x70FB, 0x70FB}, {0x70FC, 0x70FC}, {0x70FD, 0x70FD}, {0x70FE, 0x70FE}, {0x70FF, 0x70FF}, + {0x7100, 0x7100}, {0x7101, 0x7101}, {0x7102, 0x7102}, {0x7103, 0x7103}, {0x7104, 0x7104}, {0x7105, 0x7105}, {0x7106, 0x7106}, + {0x7107, 0x7107}, {0x7108, 0x7108}, {0x7109, 0x7109}, {0x710A, 0x710A}, {0x710B, 0x710B}, {0x710C, 0x710C}, {0x710D, 0x710D}, + {0x710E, 0x710E}, {0x710F, 0x710F}, {0x7110, 0x7110}, {0x7111, 0x7111}, {0x7112, 0x7112}, {0x7113, 0x7113}, {0x7114, 0x7114}, + {0x7115, 0x7115}, {0x7116, 0x7116}, {0x7117, 0x7117}, {0x7118, 0x7118}, {0x7119, 0x7119}, {0x711A, 0x711A}, {0x711B, 0x711B}, + {0x711C, 0x711C}, {0x711D, 0x711D}, {0x711E, 0x711E}, {0x711F, 0x711F}, {0x7120, 0x7120}, {0x7121, 0x7121}, {0x7122, 0x7122}, + {0x7123, 0x7123}, {0x7124, 0x7124}, {0x7125, 0x7125}, {0x7126, 0x7126}, {0x7127, 0x7127}, {0x7128, 0x7128}, {0x7129, 0x7129}, + {0x712A, 0x712A}, {0x712B, 0x712B}, {0x712C, 0x712C}, {0x712D, 0x712D}, {0x712E, 0x712E}, {0x712F, 0x712F}, {0x7130, 0x7130}, + {0x7131, 0x7131}, {0x7132, 0x7132}, {0x7133, 0x7133}, {0x7134, 0x7134}, {0x7135, 0x7135}, {0x7136, 0x7136}, {0x7137, 0x7137}, + {0x7138, 0x7138}, {0x7139, 0x7139}, {0x713A, 0x713A}, {0x713B, 0x713B}, {0x713C, 0x713C}, {0x713D, 0x713D}, {0x713E, 0x713E}, + {0x713F, 0x713F}, {0x7140, 0x7140}, {0x7141, 0x7141}, {0x7142, 0x7142}, {0x7143, 0x7143}, {0x7144, 0x7144}, {0x7145, 0x7145}, + {0x7146, 0x7146}, {0x7147, 0x7147}, {0x7148, 0x7148}, {0x7149, 0x7149}, {0x714A, 0x714A}, {0x714B, 0x714B}, {0x714C, 0x714C}, + {0x714D, 0x714D}, {0x714E, 0x714E}, {0x714F, 0x714F}, {0x7150, 0x7150}, {0x7151, 0x7151}, {0x7152, 0x7152}, {0x7153, 0x7153}, + {0x7154, 0x7154}, {0x7155, 0x7155}, {0x7156, 0x7156}, {0x7157, 0x7157}, {0x7158, 0x7158}, {0x7159, 0x7159}, {0x715A, 0x715A}, + {0x715B, 0x715B}, {0x715C, 0x715C}, {0x715D, 0x715D}, {0x715E, 0x715E}, {0x715F, 0x715F}, {0x7160, 0x7160}, {0x7161, 0x7161}, + {0x7162, 0x7162}, {0x7163, 0x7163}, {0x7164, 0x7164}, {0x7165, 0x7165}, {0x7166, 0x7166}, {0x7167, 0x7167}, {0x7168, 0x7168}, + {0x7169, 0x7169}, {0x716A, 0x716A}, {0x716B, 0x716B}, {0x716C, 0x716C}, {0x716D, 0x716D}, {0x716E, 0x716E}, {0x716F, 0x716F}, + {0x7170, 0x7170}, {0x7171, 0x7171}, {0x7172, 0x7172}, {0x7173, 0x7173}, {0x7174, 0x7174}, {0x7175, 0x7175}, {0x7176, 0x7176}, + {0x7177, 0x7177}, {0x7178, 0x7178}, {0x7179, 0x7179}, {0x717A, 0x717A}, {0x717B, 0x717B}, {0x717C, 0x717C}, {0x717D, 0x717D}, + {0x717E, 0x717E}, {0x717F, 0x717F}, {0x7180, 0x7180}, {0x7181, 0x7181}, {0x7182, 0x7182}, {0x7183, 0x7183}, {0x7184, 0x7184}, + {0x7185, 0x7185}, {0x7186, 0x7186}, {0x7187, 0x7187}, {0x7188, 0x7188}, {0x7189, 0x7189}, {0x718A, 0x718A}, {0x718B, 0x718B}, + {0x718C, 0x718C}, {0x718D, 0x718D}, {0x718E, 0x718E}, {0x718F, 0x718F}, {0x7190, 0x7190}, {0x7191, 0x7191}, {0x7192, 0x7192}, + {0x7193, 0x7193}, {0x7194, 0x7194}, {0x7195, 0x7195}, {0x7196, 0x7196}, {0x7197, 0x7197}, {0x7198, 0x7198}, {0x7199, 0x7199}, + {0x719A, 0x719A}, {0x719B, 0x719B}, {0x719C, 0x719C}, {0x719D, 0x719D}, {0x719E, 0x719E}, {0x719F, 0x719F}, {0x71A0, 0x71A0}, + {0x71A1, 0x71A1}, {0x71A2, 0x71A2}, {0x71A3, 0x71A3}, {0x71A4, 0x71A4}, {0x71A5, 0x71A5}, {0x71A6, 0x71A6}, {0x71A7, 0x71A7}, + {0x71A8, 0x71A8}, {0x71A9, 0x71A9}, {0x71AA, 0x71AA}, {0x71AB, 0x71AB}, {0x71AC, 0x71AC}, {0x71AD, 0x71AD}, {0x71AE, 0x71AE}, + {0x71AF, 0x71AF}, {0x71B0, 0x71B0}, {0x71B1, 0x71B1}, {0x71B2, 0x71B2}, {0x71B3, 0x71B3}, {0x71B4, 0x71B4}, {0x71B5, 0x71B5}, + {0x71B6, 0x71B6}, {0x71B7, 0x71B7}, {0x71B8, 0x71B8}, {0x71B9, 0x71B9}, {0x71BA, 0x71BA}, {0x71BB, 0x71BB}, {0x71BC, 0x71BC}, + {0x71BD, 0x71BD}, {0x71BE, 0x71BE}, {0x71BF, 0x71BF}, {0x71C0, 0x71C0}, {0x71C1, 0x71C1}, {0x71C2, 0x71C2}, {0x71C3, 0x71C3}, + {0x71C4, 0x71C4}, {0x71C5, 0x71C5}, {0x71C6, 0x71C6}, {0x71C7, 0x71C7}, {0x71C8, 0x71C8}, {0x71C9, 0x71C9}, {0x71CA, 0x71CA}, + {0x71CB, 0x71CB}, {0x71CC, 0x71CC}, {0x71CD, 0x71CD}, {0x71CE, 0x71CE}, {0x71CF, 0x71CF}, {0x71D0, 0x71D0}, {0x71D1, 0x71D1}, + {0x71D2, 0x71D2}, {0x71D3, 0x71D3}, {0x71D4, 0x71D4}, {0x71D5, 0x71D5}, {0x71D6, 0x71D6}, {0x71D7, 0x71D7}, {0x71D8, 0x71D8}, + {0x71D9, 0x71D9}, {0x71DA, 0x71DA}, {0x71DB, 0x71DB}, {0x71DC, 0x71DC}, {0x71DD, 0x71DD}, {0x71DE, 0x71DE}, {0x71DF, 0x71DF}, + {0x71E0, 0x71E0}, {0x71E1, 0x71E1}, {0x71E2, 0x71E2}, {0x71E3, 0x71E3}, {0x71E4, 0x71E4}, {0x71E5, 0x71E5}, {0x71E6, 0x71E6}, + {0x71E7, 0x71E7}, {0x71E8, 0x71E8}, {0x71E9, 0x71E9}, {0x71EA, 0x71EA}, {0x71EB, 0x71EB}, {0x71EC, 0x71EC}, {0x71ED, 0x71ED}, + {0x71EE, 0x71EE}, {0x71EF, 0x71EF}, {0x71F0, 0x71F0}, {0x71F1, 0x71F1}, {0x71F2, 0x71F2}, {0x71F3, 0x71F3}, {0x71F4, 0x71F4}, + {0x71F5, 0x71F5}, {0x71F6, 0x71F6}, {0x71F7, 0x71F7}, {0x71F8, 0x71F8}, {0x71F9, 0x71F9}, {0x71FA, 0x71FA}, {0x71FB, 0x71FB}, + {0x71FC, 0x71FC}, {0x71FD, 0x71FD}, {0x71FE, 0x71FE}, {0x71FF, 0x71FF}, {0x7200, 0x7200}, {0x7201, 0x7201}, {0x7202, 0x7202}, + {0x7203, 0x7203}, {0x7204, 0x7204}, {0x7205, 0x7205}, {0x7206, 0x7206}, {0x7207, 0x7207}, {0x7208, 0x7208}, {0x7209, 0x7209}, + {0x720A, 0x720A}, {0x720B, 0x720B}, {0x720C, 0x720C}, {0x720D, 0x720D}, {0x720E, 0x720E}, {0x720F, 0x720F}, {0x7210, 0x7210}, + {0x7211, 0x7211}, {0x7212, 0x7212}, {0x7213, 0x7213}, {0x7214, 0x7214}, {0x7215, 0x7215}, {0x7216, 0x7216}, {0x7217, 0x7217}, + {0x7218, 0x7218}, {0x7219, 0x7219}, {0x721A, 0x721A}, {0x721B, 0x721B}, {0x721C, 0x721C}, {0x721D, 0x721D}, {0x721E, 0x721E}, + {0x721F, 0x721F}, {0x7220, 0x7220}, {0x7221, 0x7221}, {0x7222, 0x7222}, {0x7223, 0x7223}, {0x7224, 0x7224}, {0x7225, 0x7225}, + {0x7226, 0x7226}, {0x7227, 0x7227}, {0x7228, 0x7228}, {0x7229, 0x7229}, {0x722A, 0x722A}, {0x722B, 0x722B}, {0x722C, 0x722C}, + {0x722D, 0x722D}, {0x722E, 0x722E}, {0x722F, 0x722F}, {0x7230, 0x7230}, {0x7231, 0x7231}, {0x7232, 0x7232}, {0x7233, 0x7233}, + {0x7234, 0x7234}, {0x7235, 0x7235}, {0x7236, 0x7236}, {0x7237, 0x7237}, {0x7238, 0x7238}, {0x7239, 0x7239}, {0x723A, 0x723A}, + {0x723B, 0x723B}, {0x723C, 0x723C}, {0x723D, 0x723D}, {0x723E, 0x723E}, {0x723F, 0x723F}, {0x7240, 0x7240}, {0x7241, 0x7241}, + {0x7242, 0x7242}, {0x7243, 0x7243}, {0x7244, 0x7244}, {0x7245, 0x7245}, {0x7246, 0x7246}, {0x7247, 0x7247}, {0x7248, 0x7248}, + {0x7249, 0x7249}, {0x724A, 0x724A}, {0x724B, 0x724B}, {0x724C, 0x724C}, {0x724D, 0x724D}, {0x724E, 0x724E}, {0x724F, 0x724F}, + {0x7250, 0x7250}, {0x7251, 0x7251}, {0x7252, 0x7252}, {0x7253, 0x7253}, {0x7254, 0x7254}, {0x7255, 0x7255}, {0x7256, 0x7256}, + {0x7257, 0x7257}, {0x7258, 0x7258}, {0x7259, 0x7259}, {0x725A, 0x725A}, {0x725B, 0x725B}, {0x725C, 0x725C}, {0x725D, 0x725D}, + {0x725E, 0x725E}, {0x725F, 0x725F}, {0x7260, 0x7260}, {0x7261, 0x7261}, {0x7262, 0x7262}, {0x7263, 0x7263}, {0x7264, 0x7264}, + {0x7265, 0x7265}, {0x7266, 0x7266}, {0x7267, 0x7267}, {0x7268, 0x7268}, {0x7269, 0x7269}, {0x726A, 0x726A}, {0x726B, 0x726B}, + {0x726C, 0x726C}, {0x726D, 0x726D}, {0x726E, 0x726E}, {0x726F, 0x726F}, {0x7270, 0x7270}, {0x7271, 0x7271}, {0x7272, 0x7272}, + {0x7273, 0x7273}, {0x7274, 0x7274}, {0x7275, 0x7275}, {0x7276, 0x7276}, {0x7277, 0x7277}, {0x7278, 0x7278}, {0x7279, 0x7279}, + {0x727A, 0x727A}, {0x727B, 0x727B}, {0x727C, 0x727C}, {0x727D, 0x727D}, {0x727E, 0x727E}, {0x727F, 0x727F}, {0x7280, 0x7280}, + {0x7281, 0x7281}, {0x7282, 0x7282}, {0x7283, 0x7283}, {0x7284, 0x7284}, {0x7285, 0x7285}, {0x7286, 0x7286}, {0x7287, 0x7287}, + {0x7288, 0x7288}, {0x7289, 0x7289}, {0x728A, 0x728A}, {0x728B, 0x728B}, {0x728C, 0x728C}, {0x728D, 0x728D}, {0x728E, 0x728E}, + {0x728F, 0x728F}, {0x7290, 0x7290}, {0x7291, 0x7291}, {0x7292, 0x7292}, {0x7293, 0x7293}, {0x7294, 0x7294}, {0x7295, 0x7295}, + {0x7296, 0x7296}, {0x7297, 0x7297}, {0x7298, 0x7298}, {0x7299, 0x7299}, {0x729A, 0x729A}, {0x729B, 0x729B}, {0x729C, 0x729C}, + {0x729D, 0x729D}, {0x729E, 0x729E}, {0x729F, 0x729F}, {0x72A0, 0x72A0}, {0x72A1, 0x72A1}, {0x72A2, 0x72A2}, {0x72A3, 0x72A3}, + {0x72A4, 0x72A4}, {0x72A5, 0x72A5}, {0x72A6, 0x72A6}, {0x72A7, 0x72A7}, {0x72A8, 0x72A8}, {0x72A9, 0x72A9}, {0x72AA, 0x72AA}, + {0x72AB, 0x72AB}, {0x72AC, 0x72AC}, {0x72AD, 0x72AD}, {0x72AE, 0x72AE}, {0x72AF, 0x72AF}, {0x72B0, 0x72B0}, {0x72B1, 0x72B1}, + {0x72B2, 0x72B2}, {0x72B3, 0x72B3}, {0x72B4, 0x72B4}, {0x72B5, 0x72B5}, {0x72B6, 0x72B6}, {0x72B7, 0x72B7}, {0x72B8, 0x72B8}, + {0x72B9, 0x72B9}, {0x72BA, 0x72BA}, {0x72BB, 0x72BB}, {0x72BC, 0x72BC}, {0x72BD, 0x72BD}, {0x72BE, 0x72BE}, {0x72BF, 0x72BF}, + {0x72C0, 0x72C0}, {0x72C1, 0x72C1}, {0x72C2, 0x72C2}, {0x72C3, 0x72C3}, {0x72C4, 0x72C4}, {0x72C5, 0x72C5}, {0x72C6, 0x72C6}, + {0x72C7, 0x72C7}, {0x72C8, 0x72C8}, {0x72C9, 0x72C9}, {0x72CA, 0x72CA}, {0x72CB, 0x72CB}, {0x72CC, 0x72CC}, {0x72CD, 0x72CD}, + {0x72CE, 0x72CE}, {0x72CF, 0x72CF}, {0x72D0, 0x72D0}, {0x72D1, 0x72D1}, {0x72D2, 0x72D2}, {0x72D3, 0x72D3}, {0x72D4, 0x72D4}, + {0x72D5, 0x72D5}, {0x72D6, 0x72D6}, {0x72D7, 0x72D7}, {0x72D8, 0x72D8}, {0x72D9, 0x72D9}, {0x72DA, 0x72DA}, {0x72DB, 0x72DB}, + {0x72DC, 0x72DC}, {0x72DD, 0x72DD}, {0x72DE, 0x72DE}, {0x72DF, 0x72DF}, {0x72E0, 0x72E0}, {0x72E1, 0x72E1}, {0x72E2, 0x72E2}, + {0x72E3, 0x72E3}, {0x72E4, 0x72E4}, {0x72E5, 0x72E5}, {0x72E6, 0x72E6}, {0x72E7, 0x72E7}, {0x72E8, 0x72E8}, {0x72E9, 0x72E9}, + {0x72EA, 0x72EA}, {0x72EB, 0x72EB}, {0x72EC, 0x72EC}, {0x72ED, 0x72ED}, {0x72EE, 0x72EE}, {0x72EF, 0x72EF}, {0x72F0, 0x72F0}, + {0x72F1, 0x72F1}, {0x72F2, 0x72F2}, {0x72F3, 0x72F3}, {0x72F4, 0x72F4}, {0x72F5, 0x72F5}, {0x72F6, 0x72F6}, {0x72F7, 0x72F7}, + {0x72F8, 0x72F8}, {0x72F9, 0x72F9}, {0x72FA, 0x72FA}, {0x72FB, 0x72FB}, {0x72FC, 0x72FC}, {0x72FD, 0x72FD}, {0x72FE, 0x72FE}, + {0x72FF, 0x72FF}, {0x7300, 0x7300}, {0x7301, 0x7301}, {0x7302, 0x7302}, {0x7303, 0x7303}, {0x7304, 0x7304}, {0x7305, 0x7305}, + {0x7306, 0x7306}, {0x7307, 0x7307}, {0x7308, 0x7308}, {0x7309, 0x7309}, {0x730A, 0x730A}, {0x730B, 0x730B}, {0x730C, 0x730C}, + {0x730D, 0x730D}, {0x730E, 0x730E}, {0x730F, 0x730F}, {0x7310, 0x7310}, {0x7311, 0x7311}, {0x7312, 0x7312}, {0x7313, 0x7313}, + {0x7314, 0x7314}, {0x7315, 0x7315}, {0x7316, 0x7316}, {0x7317, 0x7317}, {0x7318, 0x7318}, {0x7319, 0x7319}, {0x731A, 0x731A}, + {0x731B, 0x731B}, {0x731C, 0x731C}, {0x731D, 0x731D}, {0x731E, 0x731E}, {0x731F, 0x731F}, {0x7320, 0x7320}, {0x7321, 0x7321}, + {0x7322, 0x7322}, {0x7323, 0x7323}, {0x7324, 0x7324}, {0x7325, 0x7325}, {0x7326, 0x7326}, {0x7327, 0x7327}, {0x7328, 0x7328}, + {0x7329, 0x7329}, {0x732A, 0x732A}, {0x732B, 0x732B}, {0x732C, 0x732C}, {0x732D, 0x732D}, {0x732E, 0x732E}, {0x732F, 0x732F}, + {0x7330, 0x7330}, {0x7331, 0x7331}, {0x7332, 0x7332}, {0x7333, 0x7333}, {0x7334, 0x7334}, {0x7335, 0x7335}, {0x7336, 0x7336}, + {0x7337, 0x7337}, {0x7338, 0x7338}, {0x7339, 0x7339}, {0x733A, 0x733A}, {0x733B, 0x733B}, {0x733C, 0x733C}, {0x733D, 0x733D}, + {0x733E, 0x733E}, {0x733F, 0x733F}, {0x7340, 0x7340}, {0x7341, 0x7341}, {0x7342, 0x7342}, {0x7343, 0x7343}, {0x7344, 0x7344}, + {0x7345, 0x7345}, {0x7346, 0x7346}, {0x7347, 0x7347}, {0x7348, 0x7348}, {0x7349, 0x7349}, {0x734A, 0x734A}, {0x734B, 0x734B}, + {0x734C, 0x734C}, {0x734D, 0x734D}, {0x734E, 0x734E}, {0x734F, 0x734F}, {0x7350, 0x7350}, {0x7351, 0x7351}, {0x7352, 0x7352}, + {0x7353, 0x7353}, {0x7354, 0x7354}, {0x7355, 0x7355}, {0x7356, 0x7356}, {0x7357, 0x7357}, {0x7358, 0x7358}, {0x7359, 0x7359}, + {0x735A, 0x735A}, {0x735B, 0x735B}, {0x735C, 0x735C}, {0x735D, 0x735D}, {0x735E, 0x735E}, {0x735F, 0x735F}, {0x7360, 0x7360}, + {0x7361, 0x7361}, {0x7362, 0x7362}, {0x7363, 0x7363}, {0x7364, 0x7364}, {0x7365, 0x7365}, {0x7366, 0x7366}, {0x7367, 0x7367}, + {0x7368, 0x7368}, {0x7369, 0x7369}, {0x736A, 0x736A}, {0x736B, 0x736B}, {0x736C, 0x736C}, {0x736D, 0x736D}, {0x736E, 0x736E}, + {0x736F, 0x736F}, {0x7370, 0x7370}, {0x7371, 0x7371}, {0x7372, 0x7372}, {0x7373, 0x7373}, {0x7374, 0x7374}, {0x7375, 0x7375}, + {0x7376, 0x7376}, {0x7377, 0x7377}, {0x7378, 0x7378}, {0x7379, 0x7379}, {0x737A, 0x737A}, {0x737B, 0x737B}, {0x737C, 0x737C}, + {0x737D, 0x737D}, {0x737E, 0x737E}, {0x737F, 0x737F}, {0x7380, 0x7380}, {0x7381, 0x7381}, {0x7382, 0x7382}, {0x7383, 0x7383}, + {0x7384, 0x7384}, {0x7385, 0x7385}, {0x7386, 0x7386}, {0x7387, 0x7387}, {0x7388, 0x7388}, {0x7389, 0x7389}, {0x738A, 0x738A}, + {0x738B, 0x738B}, {0x738C, 0x738C}, {0x738D, 0x738D}, {0x738E, 0x738E}, {0x738F, 0x738F}, {0x7390, 0x7390}, {0x7391, 0x7391}, + {0x7392, 0x7392}, {0x7393, 0x7393}, {0x7394, 0x7394}, {0x7395, 0x7395}, {0x7396, 0x7396}, {0x7397, 0x7397}, {0x7398, 0x7398}, + {0x7399, 0x7399}, {0x739A, 0x739A}, {0x739B, 0x739B}, {0x739C, 0x739C}, {0x739D, 0x739D}, {0x739E, 0x739E}, {0x739F, 0x739F}, + {0x73A0, 0x73A0}, {0x73A1, 0x73A1}, {0x73A2, 0x73A2}, {0x73A3, 0x73A3}, {0x73A4, 0x73A4}, {0x73A5, 0x73A5}, {0x73A6, 0x73A6}, + {0x73A7, 0x73A7}, {0x73A8, 0x73A8}, {0x73A9, 0x73A9}, {0x73AA, 0x73AA}, {0x73AB, 0x73AB}, {0x73AC, 0x73AC}, {0x73AD, 0x73AD}, + {0x73AE, 0x73AE}, {0x73AF, 0x73AF}, {0x73B0, 0x73B0}, {0x73B1, 0x73B1}, {0x73B2, 0x73B2}, {0x73B3, 0x73B3}, {0x73B4, 0x73B4}, + {0x73B5, 0x73B5}, {0x73B6, 0x73B6}, {0x73B7, 0x73B7}, {0x73B8, 0x73B8}, {0x73B9, 0x73B9}, {0x73BA, 0x73BA}, {0x73BB, 0x73BB}, + {0x73BC, 0x73BC}, {0x73BD, 0x73BD}, {0x73BE, 0x73BE}, {0x73BF, 0x73BF}, {0x73C0, 0x73C0}, {0x73C1, 0x73C1}, {0x73C2, 0x73C2}, + {0x73C3, 0x73C3}, {0x73C4, 0x73C4}, {0x73C5, 0x73C5}, {0x73C6, 0x73C6}, {0x73C7, 0x73C7}, {0x73C8, 0x73C8}, {0x73C9, 0x73C9}, + {0x73CA, 0x73CA}, {0x73CB, 0x73CB}, {0x73CC, 0x73CC}, {0x73CD, 0x73CD}, {0x73CE, 0x73CE}, {0x73CF, 0x73CF}, {0x73D0, 0x73D0}, + {0x73D1, 0x73D1}, {0x73D2, 0x73D2}, {0x73D3, 0x73D3}, {0x73D4, 0x73D4}, {0x73D5, 0x73D5}, {0x73D6, 0x73D6}, {0x73D7, 0x73D7}, + {0x73D8, 0x73D8}, {0x73D9, 0x73D9}, {0x73DA, 0x73DA}, {0x73DB, 0x73DB}, {0x73DC, 0x73DC}, {0x73DD, 0x73DD}, {0x73DE, 0x73DE}, + {0x73DF, 0x73DF}, {0x73E0, 0x73E0}, {0x73E1, 0x73E1}, {0x73E2, 0x73E2}, {0x73E3, 0x73E3}, {0x73E4, 0x73E4}, {0x73E5, 0x73E5}, + {0x73E6, 0x73E6}, {0x73E7, 0x73E7}, {0x73E8, 0x73E8}, {0x73E9, 0x73E9}, {0x73EA, 0x73EA}, {0x73EB, 0x73EB}, {0x73EC, 0x73EC}, + {0x73ED, 0x73ED}, {0x73EE, 0x73EE}, {0x73EF, 0x73EF}, {0x73F0, 0x73F0}, {0x73F1, 0x73F1}, {0x73F2, 0x73F2}, {0x73F3, 0x73F3}, + {0x73F4, 0x73F4}, {0x73F5, 0x73F5}, {0x73F6, 0x73F6}, {0x73F7, 0x73F7}, {0x73F8, 0x73F8}, {0x73F9, 0x73F9}, {0x73FA, 0x73FA}, + {0x73FB, 0x73FB}, {0x73FC, 0x73FC}, {0x73FD, 0x73FD}, {0x73FE, 0x73FE}, {0x73FF, 0x73FF}, {0x7400, 0x7400}, {0x7401, 0x7401}, + {0x7402, 0x7402}, {0x7403, 0x7403}, {0x7404, 0x7404}, {0x7405, 0x7405}, {0x7406, 0x7406}, {0x7407, 0x7407}, {0x7408, 0x7408}, + {0x7409, 0x7409}, {0x740A, 0x740A}, {0x740B, 0x740B}, {0x740C, 0x740C}, {0x740D, 0x740D}, {0x740E, 0x740E}, {0x740F, 0x740F}, + {0x7410, 0x7410}, {0x7411, 0x7411}, {0x7412, 0x7412}, {0x7413, 0x7413}, {0x7414, 0x7414}, {0x7415, 0x7415}, {0x7416, 0x7416}, + {0x7417, 0x7417}, {0x7418, 0x7418}, {0x7419, 0x7419}, {0x741A, 0x741A}, {0x741B, 0x741B}, {0x741C, 0x741C}, {0x741D, 0x741D}, + {0x741E, 0x741E}, {0x741F, 0x741F}, {0x7420, 0x7420}, {0x7421, 0x7421}, {0x7422, 0x7422}, {0x7423, 0x7423}, {0x7424, 0x7424}, + {0x7425, 0x7425}, {0x7426, 0x7426}, {0x7427, 0x7427}, {0x7428, 0x7428}, {0x7429, 0x7429}, {0x742A, 0x742A}, {0x742B, 0x742B}, + {0x742C, 0x742C}, {0x742D, 0x742D}, {0x742E, 0x742E}, {0x742F, 0x742F}, {0x7430, 0x7430}, {0x7431, 0x7431}, {0x7432, 0x7432}, + {0x7433, 0x7433}, {0x7434, 0x7434}, {0x7435, 0x7435}, {0x7436, 0x7436}, {0x7437, 0x7437}, {0x7438, 0x7438}, {0x7439, 0x7439}, + {0x743A, 0x743A}, {0x743B, 0x743B}, {0x743C, 0x743C}, {0x743D, 0x743D}, {0x743E, 0x743E}, {0x743F, 0x743F}, {0x7440, 0x7440}, + {0x7441, 0x7441}, {0x7442, 0x7442}, {0x7443, 0x7443}, {0x7444, 0x7444}, {0x7445, 0x7445}, {0x7446, 0x7446}, {0x7447, 0x7447}, + {0x7448, 0x7448}, {0x7449, 0x7449}, {0x744A, 0x744A}, {0x744B, 0x744B}, {0x744C, 0x744C}, {0x744D, 0x744D}, {0x744E, 0x744E}, + {0x744F, 0x744F}, {0x7450, 0x7450}, {0x7451, 0x7451}, {0x7452, 0x7452}, {0x7453, 0x7453}, {0x7454, 0x7454}, {0x7455, 0x7455}, + {0x7456, 0x7456}, {0x7457, 0x7457}, {0x7458, 0x7458}, {0x7459, 0x7459}, {0x745A, 0x745A}, {0x745B, 0x745B}, {0x745C, 0x745C}, + {0x745D, 0x745D}, {0x745E, 0x745E}, {0x745F, 0x745F}, {0x7460, 0x7460}, {0x7461, 0x7461}, {0x7462, 0x7462}, {0x7463, 0x7463}, + {0x7464, 0x7464}, {0x7465, 0x7465}, {0x7466, 0x7466}, {0x7467, 0x7467}, {0x7468, 0x7468}, {0x7469, 0x7469}, {0x746A, 0x746A}, + {0x746B, 0x746B}, {0x746C, 0x746C}, {0x746D, 0x746D}, {0x746E, 0x746E}, {0x746F, 0x746F}, {0x7470, 0x7470}, {0x7471, 0x7471}, + {0x7472, 0x7472}, {0x7473, 0x7473}, {0x7474, 0x7474}, {0x7475, 0x7475}, {0x7476, 0x7476}, {0x7477, 0x7477}, {0x7478, 0x7478}, + {0x7479, 0x7479}, {0x747A, 0x747A}, {0x747B, 0x747B}, {0x747C, 0x747C}, {0x747D, 0x747D}, {0x747E, 0x747E}, {0x747F, 0x747F}, + {0x7480, 0x7480}, {0x7481, 0x7481}, {0x7482, 0x7482}, {0x7483, 0x7483}, {0x7484, 0x7484}, {0x7485, 0x7485}, {0x7486, 0x7486}, + {0x7487, 0x7487}, {0x7488, 0x7488}, {0x7489, 0x7489}, {0x748A, 0x748A}, {0x748B, 0x748B}, {0x748C, 0x748C}, {0x748D, 0x748D}, + {0x748E, 0x748E}, {0x748F, 0x748F}, {0x7490, 0x7490}, {0x7491, 0x7491}, {0x7492, 0x7492}, {0x7493, 0x7493}, {0x7494, 0x7494}, + {0x7495, 0x7495}, {0x7496, 0x7496}, {0x7497, 0x7497}, {0x7498, 0x7498}, {0x7499, 0x7499}, {0x749A, 0x749A}, {0x749B, 0x749B}, + {0x749C, 0x749C}, {0x749D, 0x749D}, {0x749E, 0x749E}, {0x749F, 0x749F}, {0x74A0, 0x74A0}, {0x74A1, 0x74A1}, {0x74A2, 0x74A2}, + {0x74A3, 0x74A3}, {0x74A4, 0x74A4}, {0x74A5, 0x74A5}, {0x74A6, 0x74A6}, {0x74A7, 0x74A7}, {0x74A8, 0x74A8}, {0x74A9, 0x74A9}, + {0x74AA, 0x74AA}, {0x74AB, 0x74AB}, {0x74AC, 0x74AC}, {0x74AD, 0x74AD}, {0x74AE, 0x74AE}, {0x74AF, 0x74AF}, {0x74B0, 0x74B0}, + {0x74B1, 0x74B1}, {0x74B2, 0x74B2}, {0x74B3, 0x74B3}, {0x74B4, 0x74B4}, {0x74B5, 0x74B5}, {0x74B6, 0x74B6}, {0x74B7, 0x74B7}, + {0x74B8, 0x74B8}, {0x74B9, 0x74B9}, {0x74BA, 0x74BA}, {0x74BB, 0x74BB}, {0x74BC, 0x74BC}, {0x74BD, 0x74BD}, {0x74BE, 0x74BE}, + {0x74BF, 0x74BF}, {0x74C0, 0x74C0}, {0x74C1, 0x74C1}, {0x74C2, 0x74C2}, {0x74C3, 0x74C3}, {0x74C4, 0x74C4}, {0x74C5, 0x74C5}, + {0x74C6, 0x74C6}, {0x74C7, 0x74C7}, {0x74C8, 0x74C8}, {0x74C9, 0x74C9}, {0x74CA, 0x74CA}, {0x74CB, 0x74CB}, {0x74CC, 0x74CC}, + {0x74CD, 0x74CD}, {0x74CE, 0x74CE}, {0x74CF, 0x74CF}, {0x74D0, 0x74D0}, {0x74D1, 0x74D1}, {0x74D2, 0x74D2}, {0x74D3, 0x74D3}, + {0x74D4, 0x74D4}, {0x74D5, 0x74D5}, {0x74D6, 0x74D6}, {0x74D7, 0x74D7}, {0x74D8, 0x74D8}, {0x74D9, 0x74D9}, {0x74DA, 0x74DA}, + {0x74DB, 0x74DB}, {0x74DC, 0x74DC}, {0x74DD, 0x74DD}, {0x74DE, 0x74DE}, {0x74DF, 0x74DF}, {0x74E0, 0x74E0}, {0x74E1, 0x74E1}, + {0x74E2, 0x74E2}, {0x74E3, 0x74E3}, {0x74E4, 0x74E4}, {0x74E5, 0x74E5}, {0x74E6, 0x74E6}, {0x74E7, 0x74E7}, {0x74E8, 0x74E8}, + {0x74E9, 0x74E9}, {0x74EA, 0x74EA}, {0x74EB, 0x74EB}, {0x74EC, 0x74EC}, {0x74ED, 0x74ED}, {0x74EE, 0x74EE}, {0x74EF, 0x74EF}, + {0x74F0, 0x74F0}, {0x74F1, 0x74F1}, {0x74F2, 0x74F2}, {0x74F3, 0x74F3}, {0x74F4, 0x74F4}, {0x74F5, 0x74F5}, {0x74F6, 0x74F6}, + {0x74F7, 0x74F7}, {0x74F8, 0x74F8}, {0x74F9, 0x74F9}, {0x74FA, 0x74FA}, {0x74FB, 0x74FB}, {0x74FC, 0x74FC}, {0x74FD, 0x74FD}, + {0x74FE, 0x74FE}, {0x74FF, 0x74FF}, {0x7500, 0x7500}, {0x7501, 0x7501}, {0x7502, 0x7502}, {0x7503, 0x7503}, {0x7504, 0x7504}, + {0x7505, 0x7505}, {0x7506, 0x7506}, {0x7507, 0x7507}, {0x7508, 0x7508}, {0x7509, 0x7509}, {0x750A, 0x750A}, {0x750B, 0x750B}, + {0x750C, 0x750C}, {0x750D, 0x750D}, {0x750E, 0x750E}, {0x750F, 0x750F}, {0x7510, 0x7510}, {0x7511, 0x7511}, {0x7512, 0x7512}, + {0x7513, 0x7513}, {0x7514, 0x7514}, {0x7515, 0x7515}, {0x7516, 0x7516}, {0x7517, 0x7517}, {0x7518, 0x7518}, {0x7519, 0x7519}, + {0x751A, 0x751A}, {0x751B, 0x751B}, {0x751C, 0x751C}, {0x751D, 0x751D}, {0x751E, 0x751E}, {0x751F, 0x751F}, {0x7520, 0x7520}, + {0x7521, 0x7521}, {0x7522, 0x7522}, {0x7523, 0x7523}, {0x7524, 0x7524}, {0x7525, 0x7525}, {0x7526, 0x7526}, {0x7527, 0x7527}, + {0x7528, 0x7528}, {0x7529, 0x7529}, {0x752A, 0x752A}, {0x752B, 0x752B}, {0x752C, 0x752C}, {0x752D, 0x752D}, {0x752E, 0x752E}, + {0x752F, 0x752F}, {0x7530, 0x7530}, {0x7531, 0x7531}, {0x7532, 0x7532}, {0x7533, 0x7533}, {0x7534, 0x7534}, {0x7535, 0x7535}, + {0x7536, 0x7536}, {0x7537, 0x7537}, {0x7538, 0x7538}, {0x7539, 0x7539}, {0x753A, 0x753A}, {0x753B, 0x753B}, {0x753C, 0x753C}, + {0x753D, 0x753D}, {0x753E, 0x753E}, {0x753F, 0x753F}, {0x7540, 0x7540}, {0x7541, 0x7541}, {0x7542, 0x7542}, {0x7543, 0x7543}, + {0x7544, 0x7544}, {0x7545, 0x7545}, {0x7546, 0x7546}, {0x7547, 0x7547}, {0x7548, 0x7548}, {0x7549, 0x7549}, {0x754A, 0x754A}, + {0x754B, 0x754B}, {0x754C, 0x754C}, {0x754D, 0x754D}, {0x754E, 0x754E}, {0x754F, 0x754F}, {0x7550, 0x7550}, {0x7551, 0x7551}, + {0x7552, 0x7552}, {0x7553, 0x7553}, {0x7554, 0x7554}, {0x7555, 0x7555}, {0x7556, 0x7556}, {0x7557, 0x7557}, {0x7558, 0x7558}, + {0x7559, 0x7559}, {0x755A, 0x755A}, {0x755B, 0x755B}, {0x755C, 0x755C}, {0x755D, 0x755D}, {0x755E, 0x755E}, {0x755F, 0x755F}, + {0x7560, 0x7560}, {0x7561, 0x7561}, {0x7562, 0x7562}, {0x7563, 0x7563}, {0x7564, 0x7564}, {0x7565, 0x7565}, {0x7566, 0x7566}, + {0x7567, 0x7567}, {0x7568, 0x7568}, {0x7569, 0x7569}, {0x756A, 0x756A}, {0x756B, 0x756B}, {0x756C, 0x756C}, {0x756D, 0x756D}, + {0x756E, 0x756E}, {0x756F, 0x756F}, {0x7570, 0x7570}, {0x7571, 0x7571}, {0x7572, 0x7572}, {0x7573, 0x7573}, {0x7574, 0x7574}, + {0x7575, 0x7575}, {0x7576, 0x7576}, {0x7577, 0x7577}, {0x7578, 0x7578}, {0x7579, 0x7579}, {0x757A, 0x757A}, {0x757B, 0x757B}, + {0x757C, 0x757C}, {0x757D, 0x757D}, {0x757E, 0x757E}, {0x757F, 0x757F}, {0x7580, 0x7580}, {0x7581, 0x7581}, {0x7582, 0x7582}, + {0x7583, 0x7583}, {0x7584, 0x7584}, {0x7585, 0x7585}, {0x7586, 0x7586}, {0x7587, 0x7587}, {0x7588, 0x7588}, {0x7589, 0x7589}, + {0x758A, 0x758A}, {0x758B, 0x758B}, {0x758C, 0x758C}, {0x758D, 0x758D}, {0x758E, 0x758E}, {0x758F, 0x758F}, {0x7590, 0x7590}, + {0x7591, 0x7591}, {0x7592, 0x7592}, {0x7593, 0x7593}, {0x7594, 0x7594}, {0x7595, 0x7595}, {0x7596, 0x7596}, {0x7597, 0x7597}, + {0x7598, 0x7598}, {0x7599, 0x7599}, {0x759A, 0x759A}, {0x759B, 0x759B}, {0x759C, 0x759C}, {0x759D, 0x759D}, {0x759E, 0x759E}, + {0x759F, 0x759F}, {0x75A0, 0x75A0}, {0x75A1, 0x75A1}, {0x75A2, 0x75A2}, {0x75A3, 0x75A3}, {0x75A4, 0x75A4}, {0x75A5, 0x75A5}, + {0x75A6, 0x75A6}, {0x75A7, 0x75A7}, {0x75A8, 0x75A8}, {0x75A9, 0x75A9}, {0x75AA, 0x75AA}, {0x75AB, 0x75AB}, {0x75AC, 0x75AC}, + {0x75AD, 0x75AD}, {0x75AE, 0x75AE}, {0x75AF, 0x75AF}, {0x75B0, 0x75B0}, {0x75B1, 0x75B1}, {0x75B2, 0x75B2}, {0x75B3, 0x75B3}, + {0x75B4, 0x75B4}, {0x75B5, 0x75B5}, {0x75B6, 0x75B6}, {0x75B7, 0x75B7}, {0x75B8, 0x75B8}, {0x75B9, 0x75B9}, {0x75BA, 0x75BA}, + {0x75BB, 0x75BB}, {0x75BC, 0x75BC}, {0x75BD, 0x75BD}, {0x75BE, 0x75BE}, {0x75BF, 0x75BF}, {0x75C0, 0x75C0}, {0x75C1, 0x75C1}, + {0x75C2, 0x75C2}, {0x75C3, 0x75C3}, {0x75C4, 0x75C4}, {0x75C5, 0x75C5}, {0x75C6, 0x75C6}, {0x75C7, 0x75C7}, {0x75C8, 0x75C8}, + {0x75C9, 0x75C9}, {0x75CA, 0x75CA}, {0x75CB, 0x75CB}, {0x75CC, 0x75CC}, {0x75CD, 0x75CD}, {0x75CE, 0x75CE}, {0x75CF, 0x75CF}, + {0x75D0, 0x75D0}, {0x75D1, 0x75D1}, {0x75D2, 0x75D2}, {0x75D3, 0x75D3}, {0x75D4, 0x75D4}, {0x75D5, 0x75D5}, {0x75D6, 0x75D6}, + {0x75D7, 0x75D7}, {0x75D8, 0x75D8}, {0x75D9, 0x75D9}, {0x75DA, 0x75DA}, {0x75DB, 0x75DB}, {0x75DC, 0x75DC}, {0x75DD, 0x75DD}, + {0x75DE, 0x75DE}, {0x75DF, 0x75DF}, {0x75E0, 0x75E0}, {0x75E1, 0x75E1}, {0x75E2, 0x75E2}, {0x75E3, 0x75E3}, {0x75E4, 0x75E4}, + {0x75E5, 0x75E5}, {0x75E6, 0x75E6}, {0x75E7, 0x75E7}, {0x75E8, 0x75E8}, {0x75E9, 0x75E9}, {0x75EA, 0x75EA}, {0x75EB, 0x75EB}, + {0x75EC, 0x75EC}, {0x75ED, 0x75ED}, {0x75EE, 0x75EE}, {0x75EF, 0x75EF}, {0x75F0, 0x75F0}, {0x75F1, 0x75F1}, {0x75F2, 0x75F2}, + {0x75F3, 0x75F3}, {0x75F4, 0x75F4}, {0x75F5, 0x75F5}, {0x75F6, 0x75F6}, {0x75F7, 0x75F7}, {0x75F8, 0x75F8}, {0x75F9, 0x75F9}, + {0x75FA, 0x75FA}, {0x75FB, 0x75FB}, {0x75FC, 0x75FC}, {0x75FD, 0x75FD}, {0x75FE, 0x75FE}, {0x75FF, 0x75FF}, {0x7600, 0x7600}, + {0x7601, 0x7601}, {0x7602, 0x7602}, {0x7603, 0x7603}, {0x7604, 0x7604}, {0x7605, 0x7605}, {0x7606, 0x7606}, {0x7607, 0x7607}, + {0x7608, 0x7608}, {0x7609, 0x7609}, {0x760A, 0x760A}, {0x760B, 0x760B}, {0x760C, 0x760C}, {0x760D, 0x760D}, {0x760E, 0x760E}, + {0x760F, 0x760F}, {0x7610, 0x7610}, {0x7611, 0x7611}, {0x7612, 0x7612}, {0x7613, 0x7613}, {0x7614, 0x7614}, {0x7615, 0x7615}, + {0x7616, 0x7616}, {0x7617, 0x7617}, {0x7618, 0x7618}, {0x7619, 0x7619}, {0x761A, 0x761A}, {0x761B, 0x761B}, {0x761C, 0x761C}, + {0x761D, 0x761D}, {0x761E, 0x761E}, {0x761F, 0x761F}, {0x7620, 0x7620}, {0x7621, 0x7621}, {0x7622, 0x7622}, {0x7623, 0x7623}, + {0x7624, 0x7624}, {0x7625, 0x7625}, {0x7626, 0x7626}, {0x7627, 0x7627}, {0x7628, 0x7628}, {0x7629, 0x7629}, {0x762A, 0x762A}, + {0x762B, 0x762B}, {0x762C, 0x762C}, {0x762D, 0x762D}, {0x762E, 0x762E}, {0x762F, 0x762F}, {0x7630, 0x7630}, {0x7631, 0x7631}, + {0x7632, 0x7632}, {0x7633, 0x7633}, {0x7634, 0x7634}, {0x7635, 0x7635}, {0x7636, 0x7636}, {0x7637, 0x7637}, {0x7638, 0x7638}, + {0x7639, 0x7639}, {0x763A, 0x763A}, {0x763B, 0x763B}, {0x763C, 0x763C}, {0x763D, 0x763D}, {0x763E, 0x763E}, {0x763F, 0x763F}, + {0x7640, 0x7640}, {0x7641, 0x7641}, {0x7642, 0x7642}, {0x7643, 0x7643}, {0x7644, 0x7644}, {0x7645, 0x7645}, {0x7646, 0x7646}, + {0x7647, 0x7647}, {0x7648, 0x7648}, {0x7649, 0x7649}, {0x764A, 0x764A}, {0x764B, 0x764B}, {0x764C, 0x764C}, {0x764D, 0x764D}, + {0x764E, 0x764E}, {0x764F, 0x764F}, {0x7650, 0x7650}, {0x7651, 0x7651}, {0x7652, 0x7652}, {0x7653, 0x7653}, {0x7654, 0x7654}, + {0x7655, 0x7655}, {0x7656, 0x7656}, {0x7657, 0x7657}, {0x7658, 0x7658}, {0x7659, 0x7659}, {0x765A, 0x765A}, {0x765B, 0x765B}, + {0x765C, 0x765C}, {0x765D, 0x765D}, {0x765E, 0x765E}, {0x765F, 0x765F}, {0x7660, 0x7660}, {0x7661, 0x7661}, {0x7662, 0x7662}, + {0x7663, 0x7663}, {0x7664, 0x7664}, {0x7665, 0x7665}, {0x7666, 0x7666}, {0x7667, 0x7667}, {0x7668, 0x7668}, {0x7669, 0x7669}, + {0x766A, 0x766A}, {0x766B, 0x766B}, {0x766C, 0x766C}, {0x766D, 0x766D}, {0x766E, 0x766E}, {0x766F, 0x766F}, {0x7670, 0x7670}, + {0x7671, 0x7671}, {0x7672, 0x7672}, {0x7673, 0x7673}, {0x7674, 0x7674}, {0x7675, 0x7675}, {0x7676, 0x7676}, {0x7677, 0x7677}, + {0x7678, 0x7678}, {0x7679, 0x7679}, {0x767A, 0x767A}, {0x767B, 0x767B}, {0x767C, 0x767C}, {0x767D, 0x767D}, {0x767E, 0x767E}, + {0x767F, 0x767F}, {0x7680, 0x7680}, {0x7681, 0x7681}, {0x7682, 0x7682}, {0x7683, 0x7683}, {0x7684, 0x7684}, {0x7685, 0x7685}, + {0x7686, 0x7686}, {0x7687, 0x7687}, {0x7688, 0x7688}, {0x7689, 0x7689}, {0x768A, 0x768A}, {0x768B, 0x768B}, {0x768C, 0x768C}, + {0x768D, 0x768D}, {0x768E, 0x768E}, {0x768F, 0x768F}, {0x7690, 0x7690}, {0x7691, 0x7691}, {0x7692, 0x7692}, {0x7693, 0x7693}, + {0x7694, 0x7694}, {0x7695, 0x7695}, {0x7696, 0x7696}, {0x7697, 0x7697}, {0x7698, 0x7698}, {0x7699, 0x7699}, {0x769A, 0x769A}, + {0x769B, 0x769B}, {0x769C, 0x769C}, {0x769D, 0x769D}, {0x769E, 0x769E}, {0x769F, 0x769F}, {0x76A0, 0x76A0}, {0x76A1, 0x76A1}, + {0x76A2, 0x76A2}, {0x76A3, 0x76A3}, {0x76A4, 0x76A4}, {0x76A5, 0x76A5}, {0x76A6, 0x76A6}, {0x76A7, 0x76A7}, {0x76A8, 0x76A8}, + {0x76A9, 0x76A9}, {0x76AA, 0x76AA}, {0x76AB, 0x76AB}, {0x76AC, 0x76AC}, {0x76AD, 0x76AD}, {0x76AE, 0x76AE}, {0x76AF, 0x76AF}, + {0x76B0, 0x76B0}, {0x76B1, 0x76B1}, {0x76B2, 0x76B2}, {0x76B3, 0x76B3}, {0x76B4, 0x76B4}, {0x76B5, 0x76B5}, {0x76B6, 0x76B6}, + {0x76B7, 0x76B7}, {0x76B8, 0x76B8}, {0x76B9, 0x76B9}, {0x76BA, 0x76BA}, {0x76BB, 0x76BB}, {0x76BC, 0x76BC}, {0x76BD, 0x76BD}, + {0x76BE, 0x76BE}, {0x76BF, 0x76BF}, {0x76C0, 0x76C0}, {0x76C1, 0x76C1}, {0x76C2, 0x76C2}, {0x76C3, 0x76C3}, {0x76C4, 0x76C4}, + {0x76C5, 0x76C5}, {0x76C6, 0x76C6}, {0x76C7, 0x76C7}, {0x76C8, 0x76C8}, {0x76C9, 0x76C9}, {0x76CA, 0x76CA}, {0x76CB, 0x76CB}, + {0x76CC, 0x76CC}, {0x76CD, 0x76CD}, {0x76CE, 0x76CE}, {0x76CF, 0x76CF}, {0x76D0, 0x76D0}, {0x76D1, 0x76D1}, {0x76D2, 0x76D2}, + {0x76D3, 0x76D3}, {0x76D4, 0x76D4}, {0x76D5, 0x76D5}, {0x76D6, 0x76D6}, {0x76D7, 0x76D7}, {0x76D8, 0x76D8}, {0x76D9, 0x76D9}, + {0x76DA, 0x76DA}, {0x76DB, 0x76DB}, {0x76DC, 0x76DC}, {0x76DD, 0x76DD}, {0x76DE, 0x76DE}, {0x76DF, 0x76DF}, {0x76E0, 0x76E0}, + {0x76E1, 0x76E1}, {0x76E2, 0x76E2}, {0x76E3, 0x76E3}, {0x76E4, 0x76E4}, {0x76E5, 0x76E5}, {0x76E6, 0x76E6}, {0x76E7, 0x76E7}, + {0x76E8, 0x76E8}, {0x76E9, 0x76E9}, {0x76EA, 0x76EA}, {0x76EB, 0x76EB}, {0x76EC, 0x76EC}, {0x76ED, 0x76ED}, {0x76EE, 0x76EE}, + {0x76EF, 0x76EF}, {0x76F0, 0x76F0}, {0x76F1, 0x76F1}, {0x76F2, 0x76F2}, {0x76F3, 0x76F3}, {0x76F4, 0x76F4}, {0x76F5, 0x76F5}, + {0x76F6, 0x76F6}, {0x76F7, 0x76F7}, {0x76F8, 0x76F8}, {0x76F9, 0x76F9}, {0x76FA, 0x76FA}, {0x76FB, 0x76FB}, {0x76FC, 0x76FC}, + {0x76FD, 0x76FD}, {0x76FE, 0x76FE}, {0x76FF, 0x76FF}, {0x7700, 0x7700}, {0x7701, 0x7701}, {0x7702, 0x7702}, {0x7703, 0x7703}, + {0x7704, 0x7704}, {0x7705, 0x7705}, {0x7706, 0x7706}, {0x7707, 0x7707}, {0x7708, 0x7708}, {0x7709, 0x7709}, {0x770A, 0x770A}, + {0x770B, 0x770B}, {0x770C, 0x770C}, {0x770D, 0x770D}, {0x770E, 0x770E}, {0x770F, 0x770F}, {0x7710, 0x7710}, {0x7711, 0x7711}, + {0x7712, 0x7712}, {0x7713, 0x7713}, {0x7714, 0x7714}, {0x7715, 0x7715}, {0x7716, 0x7716}, {0x7717, 0x7717}, {0x7718, 0x7718}, + {0x7719, 0x7719}, {0x771A, 0x771A}, {0x771B, 0x771B}, {0x771C, 0x771C}, {0x771D, 0x771D}, {0x771E, 0x771E}, {0x771F, 0x771F}, + {0x7720, 0x7720}, {0x7721, 0x7721}, {0x7722, 0x7722}, {0x7723, 0x7723}, {0x7724, 0x7724}, {0x7725, 0x7725}, {0x7726, 0x7726}, + {0x7727, 0x7727}, {0x7728, 0x7728}, {0x7729, 0x7729}, {0x772A, 0x772A}, {0x772B, 0x772B}, {0x772C, 0x772C}, {0x772D, 0x772D}, + {0x772E, 0x772E}, {0x772F, 0x772F}, {0x7730, 0x7730}, {0x7731, 0x7731}, {0x7732, 0x7732}, {0x7733, 0x7733}, {0x7734, 0x7734}, + {0x7735, 0x7735}, {0x7736, 0x7736}, {0x7737, 0x7737}, {0x7738, 0x7738}, {0x7739, 0x7739}, {0x773A, 0x773A}, {0x773B, 0x773B}, + {0x773C, 0x773C}, {0x773D, 0x773D}, {0x773E, 0x773E}, {0x773F, 0x773F}, {0x7740, 0x7740}, {0x7741, 0x7741}, {0x7742, 0x7742}, + {0x7743, 0x7743}, {0x7744, 0x7744}, {0x7745, 0x7745}, {0x7746, 0x7746}, {0x7747, 0x7747}, {0x7748, 0x7748}, {0x7749, 0x7749}, + {0x774A, 0x774A}, {0x774B, 0x774B}, {0x774C, 0x774C}, {0x774D, 0x774D}, {0x774E, 0x774E}, {0x774F, 0x774F}, {0x7750, 0x7750}, + {0x7751, 0x7751}, {0x7752, 0x7752}, {0x7753, 0x7753}, {0x7754, 0x7754}, {0x7755, 0x7755}, {0x7756, 0x7756}, {0x7757, 0x7757}, + {0x7758, 0x7758}, {0x7759, 0x7759}, {0x775A, 0x775A}, {0x775B, 0x775B}, {0x775C, 0x775C}, {0x775D, 0x775D}, {0x775E, 0x775E}, + {0x775F, 0x775F}, {0x7760, 0x7760}, {0x7761, 0x7761}, {0x7762, 0x7762}, {0x7763, 0x7763}, {0x7764, 0x7764}, {0x7765, 0x7765}, + {0x7766, 0x7766}, {0x7767, 0x7767}, {0x7768, 0x7768}, {0x7769, 0x7769}, {0x776A, 0x776A}, {0x776B, 0x776B}, {0x776C, 0x776C}, + {0x776D, 0x776D}, {0x776E, 0x776E}, {0x776F, 0x776F}, {0x7770, 0x7770}, {0x7771, 0x7771}, {0x7772, 0x7772}, {0x7773, 0x7773}, + {0x7774, 0x7774}, {0x7775, 0x7775}, {0x7776, 0x7776}, {0x7777, 0x7777}, {0x7778, 0x7778}, {0x7779, 0x7779}, {0x777A, 0x777A}, + {0x777B, 0x777B}, {0x777C, 0x777C}, {0x777D, 0x777D}, {0x777E, 0x777E}, {0x777F, 0x777F}, {0x7780, 0x7780}, {0x7781, 0x7781}, + {0x7782, 0x7782}, {0x7783, 0x7783}, {0x7784, 0x7784}, {0x7785, 0x7785}, {0x7786, 0x7786}, {0x7787, 0x7787}, {0x7788, 0x7788}, + {0x7789, 0x7789}, {0x778A, 0x778A}, {0x778B, 0x778B}, {0x778C, 0x778C}, {0x778D, 0x778D}, {0x778E, 0x778E}, {0x778F, 0x778F}, + {0x7790, 0x7790}, {0x7791, 0x7791}, {0x7792, 0x7792}, {0x7793, 0x7793}, {0x7794, 0x7794}, {0x7795, 0x7795}, {0x7796, 0x7796}, + {0x7797, 0x7797}, {0x7798, 0x7798}, {0x7799, 0x7799}, {0x779A, 0x779A}, {0x779B, 0x779B}, {0x779C, 0x779C}, {0x779D, 0x779D}, + {0x779E, 0x779E}, {0x779F, 0x779F}, {0x77A0, 0x77A0}, {0x77A1, 0x77A1}, {0x77A2, 0x77A2}, {0x77A3, 0x77A3}, {0x77A4, 0x77A4}, + {0x77A5, 0x77A5}, {0x77A6, 0x77A6}, {0x77A7, 0x77A7}, {0x77A8, 0x77A8}, {0x77A9, 0x77A9}, {0x77AA, 0x77AA}, {0x77AB, 0x77AB}, + {0x77AC, 0x77AC}, {0x77AD, 0x77AD}, {0x77AE, 0x77AE}, {0x77AF, 0x77AF}, {0x77B0, 0x77B0}, {0x77B1, 0x77B1}, {0x77B2, 0x77B2}, + {0x77B3, 0x77B3}, {0x77B4, 0x77B4}, {0x77B5, 0x77B5}, {0x77B6, 0x77B6}, {0x77B7, 0x77B7}, {0x77B8, 0x77B8}, {0x77B9, 0x77B9}, + {0x77BA, 0x77BA}, {0x77BB, 0x77BB}, {0x77BC, 0x77BC}, {0x77BD, 0x77BD}, {0x77BE, 0x77BE}, {0x77BF, 0x77BF}, {0x77C0, 0x77C0}, + {0x77C1, 0x77C1}, {0x77C2, 0x77C2}, {0x77C3, 0x77C3}, {0x77C4, 0x77C4}, {0x77C5, 0x77C5}, {0x77C6, 0x77C6}, {0x77C7, 0x77C7}, + {0x77C8, 0x77C8}, {0x77C9, 0x77C9}, {0x77CA, 0x77CA}, {0x77CB, 0x77CB}, {0x77CC, 0x77CC}, {0x77CD, 0x77CD}, {0x77CE, 0x77CE}, + {0x77CF, 0x77CF}, {0x77D0, 0x77D0}, {0x77D1, 0x77D1}, {0x77D2, 0x77D2}, {0x77D3, 0x77D3}, {0x77D4, 0x77D4}, {0x77D5, 0x77D5}, + {0x77D6, 0x77D6}, {0x77D7, 0x77D7}, {0x77D8, 0x77D8}, {0x77D9, 0x77D9}, {0x77DA, 0x77DA}, {0x77DB, 0x77DB}, {0x77DC, 0x77DC}, + {0x77DD, 0x77DD}, {0x77DE, 0x77DE}, {0x77DF, 0x77DF}, {0x77E0, 0x77E0}, {0x77E1, 0x77E1}, {0x77E2, 0x77E2}, {0x77E3, 0x77E3}, + {0x77E4, 0x77E4}, {0x77E5, 0x77E5}, {0x77E6, 0x77E6}, {0x77E7, 0x77E7}, {0x77E8, 0x77E8}, {0x77E9, 0x77E9}, {0x77EA, 0x77EA}, + {0x77EB, 0x77EB}, {0x77EC, 0x77EC}, {0x77ED, 0x77ED}, {0x77EE, 0x77EE}, {0x77EF, 0x77EF}, {0x77F0, 0x77F0}, {0x77F1, 0x77F1}, + {0x77F2, 0x77F2}, {0x77F3, 0x77F3}, {0x77F4, 0x77F4}, {0x77F5, 0x77F5}, {0x77F6, 0x77F6}, {0x77F7, 0x77F7}, {0x77F8, 0x77F8}, + {0x77F9, 0x77F9}, {0x77FA, 0x77FA}, {0x77FB, 0x77FB}, {0x77FC, 0x77FC}, {0x77FD, 0x77FD}, {0x77FE, 0x77FE}, {0x77FF, 0x77FF}, + {0x7800, 0x7800}, {0x7801, 0x7801}, {0x7802, 0x7802}, {0x7803, 0x7803}, {0x7804, 0x7804}, {0x7805, 0x7805}, {0x7806, 0x7806}, + {0x7807, 0x7807}, {0x7808, 0x7808}, {0x7809, 0x7809}, {0x780A, 0x780A}, {0x780B, 0x780B}, {0x780C, 0x780C}, {0x780D, 0x780D}, + {0x780E, 0x780E}, {0x780F, 0x780F}, {0x7810, 0x7810}, {0x7811, 0x7811}, {0x7812, 0x7812}, {0x7813, 0x7813}, {0x7814, 0x7814}, + {0x7815, 0x7815}, {0x7816, 0x7816}, {0x7817, 0x7817}, {0x7818, 0x7818}, {0x7819, 0x7819}, {0x781A, 0x781A}, {0x781B, 0x781B}, + {0x781C, 0x781C}, {0x781D, 0x781D}, {0x781E, 0x781E}, {0x781F, 0x781F}, {0x7820, 0x7820}, {0x7821, 0x7821}, {0x7822, 0x7822}, + {0x7823, 0x7823}, {0x7824, 0x7824}, {0x7825, 0x7825}, {0x7826, 0x7826}, {0x7827, 0x7827}, {0x7828, 0x7828}, {0x7829, 0x7829}, + {0x782A, 0x782A}, {0x782B, 0x782B}, {0x782C, 0x782C}, {0x782D, 0x782D}, {0x782E, 0x782E}, {0x782F, 0x782F}, {0x7830, 0x7830}, + {0x7831, 0x7831}, {0x7832, 0x7832}, {0x7833, 0x7833}, {0x7834, 0x7834}, {0x7835, 0x7835}, {0x7836, 0x7836}, {0x7837, 0x7837}, + {0x7838, 0x7838}, {0x7839, 0x7839}, {0x783A, 0x783A}, {0x783B, 0x783B}, {0x783C, 0x783C}, {0x783D, 0x783D}, {0x783E, 0x783E}, + {0x783F, 0x783F}, {0x7840, 0x7840}, {0x7841, 0x7841}, {0x7842, 0x7842}, {0x7843, 0x7843}, {0x7844, 0x7844}, {0x7845, 0x7845}, + {0x7846, 0x7846}, {0x7847, 0x7847}, {0x7848, 0x7848}, {0x7849, 0x7849}, {0x784A, 0x784A}, {0x784B, 0x784B}, {0x784C, 0x784C}, + {0x784D, 0x784D}, {0x784E, 0x784E}, {0x784F, 0x784F}, {0x7850, 0x7850}, {0x7851, 0x7851}, {0x7852, 0x7852}, {0x7853, 0x7853}, + {0x7854, 0x7854}, {0x7855, 0x7855}, {0x7856, 0x7856}, {0x7857, 0x7857}, {0x7858, 0x7858}, {0x7859, 0x7859}, {0x785A, 0x785A}, + {0x785B, 0x785B}, {0x785C, 0x785C}, {0x785D, 0x785D}, {0x785E, 0x785E}, {0x785F, 0x785F}, {0x7860, 0x7860}, {0x7861, 0x7861}, + {0x7862, 0x7862}, {0x7863, 0x7863}, {0x7864, 0x7864}, {0x7865, 0x7865}, {0x7866, 0x7866}, {0x7867, 0x7867}, {0x7868, 0x7868}, + {0x7869, 0x7869}, {0x786A, 0x786A}, {0x786B, 0x786B}, {0x786C, 0x786C}, {0x786D, 0x786D}, {0x786E, 0x786E}, {0x786F, 0x786F}, + {0x7870, 0x7870}, {0x7871, 0x7871}, {0x7872, 0x7872}, {0x7873, 0x7873}, {0x7874, 0x7874}, {0x7875, 0x7875}, {0x7876, 0x7876}, + {0x7877, 0x7877}, {0x7878, 0x7878}, {0x7879, 0x7879}, {0x787A, 0x787A}, {0x787B, 0x787B}, {0x787C, 0x787C}, {0x787D, 0x787D}, + {0x787E, 0x787E}, {0x787F, 0x787F}, {0x7880, 0x7880}, {0x7881, 0x7881}, {0x7882, 0x7882}, {0x7883, 0x7883}, {0x7884, 0x7884}, + {0x7885, 0x7885}, {0x7886, 0x7886}, {0x7887, 0x7887}, {0x7888, 0x7888}, {0x7889, 0x7889}, {0x788A, 0x788A}, {0x788B, 0x788B}, + {0x788C, 0x788C}, {0x788D, 0x788D}, {0x788E, 0x788E}, {0x788F, 0x788F}, {0x7890, 0x7890}, {0x7891, 0x7891}, {0x7892, 0x7892}, + {0x7893, 0x7893}, {0x7894, 0x7894}, {0x7895, 0x7895}, {0x7896, 0x7896}, {0x7897, 0x7897}, {0x7898, 0x7898}, {0x7899, 0x7899}, + {0x789A, 0x789A}, {0x789B, 0x789B}, {0x789C, 0x789C}, {0x789D, 0x789D}, {0x789E, 0x789E}, {0x789F, 0x789F}, {0x78A0, 0x78A0}, + {0x78A1, 0x78A1}, {0x78A2, 0x78A2}, {0x78A3, 0x78A3}, {0x78A4, 0x78A4}, {0x78A5, 0x78A5}, {0x78A6, 0x78A6}, {0x78A7, 0x78A7}, + {0x78A8, 0x78A8}, {0x78A9, 0x78A9}, {0x78AA, 0x78AA}, {0x78AB, 0x78AB}, {0x78AC, 0x78AC}, {0x78AD, 0x78AD}, {0x78AE, 0x78AE}, + {0x78AF, 0x78AF}, {0x78B0, 0x78B0}, {0x78B1, 0x78B1}, {0x78B2, 0x78B2}, {0x78B3, 0x78B3}, {0x78B4, 0x78B4}, {0x78B5, 0x78B5}, + {0x78B6, 0x78B6}, {0x78B7, 0x78B7}, {0x78B8, 0x78B8}, {0x78B9, 0x78B9}, {0x78BA, 0x78BA}, {0x78BB, 0x78BB}, {0x78BC, 0x78BC}, + {0x78BD, 0x78BD}, {0x78BE, 0x78BE}, {0x78BF, 0x78BF}, {0x78C0, 0x78C0}, {0x78C1, 0x78C1}, {0x78C2, 0x78C2}, {0x78C3, 0x78C3}, + {0x78C4, 0x78C4}, {0x78C5, 0x78C5}, {0x78C6, 0x78C6}, {0x78C7, 0x78C7}, {0x78C8, 0x78C8}, {0x78C9, 0x78C9}, {0x78CA, 0x78CA}, + {0x78CB, 0x78CB}, {0x78CC, 0x78CC}, {0x78CD, 0x78CD}, {0x78CE, 0x78CE}, {0x78CF, 0x78CF}, {0x78D0, 0x78D0}, {0x78D1, 0x78D1}, + {0x78D2, 0x78D2}, {0x78D3, 0x78D3}, {0x78D4, 0x78D4}, {0x78D5, 0x78D5}, {0x78D6, 0x78D6}, {0x78D7, 0x78D7}, {0x78D8, 0x78D8}, + {0x78D9, 0x78D9}, {0x78DA, 0x78DA}, {0x78DB, 0x78DB}, {0x78DC, 0x78DC}, {0x78DD, 0x78DD}, {0x78DE, 0x78DE}, {0x78DF, 0x78DF}, + {0x78E0, 0x78E0}, {0x78E1, 0x78E1}, {0x78E2, 0x78E2}, {0x78E3, 0x78E3}, {0x78E4, 0x78E4}, {0x78E5, 0x78E5}, {0x78E6, 0x78E6}, + {0x78E7, 0x78E7}, {0x78E8, 0x78E8}, {0x78E9, 0x78E9}, {0x78EA, 0x78EA}, {0x78EB, 0x78EB}, {0x78EC, 0x78EC}, {0x78ED, 0x78ED}, + {0x78EE, 0x78EE}, {0x78EF, 0x78EF}, {0x78F0, 0x78F0}, {0x78F1, 0x78F1}, {0x78F2, 0x78F2}, {0x78F3, 0x78F3}, {0x78F4, 0x78F4}, + {0x78F5, 0x78F5}, {0x78F6, 0x78F6}, {0x78F7, 0x78F7}, {0x78F8, 0x78F8}, {0x78F9, 0x78F9}, {0x78FA, 0x78FA}, {0x78FB, 0x78FB}, + {0x78FC, 0x78FC}, {0x78FD, 0x78FD}, {0x78FE, 0x78FE}, {0x78FF, 0x78FF}, {0x7900, 0x7900}, {0x7901, 0x7901}, {0x7902, 0x7902}, + {0x7903, 0x7903}, {0x7904, 0x7904}, {0x7905, 0x7905}, {0x7906, 0x7906}, {0x7907, 0x7907}, {0x7908, 0x7908}, {0x7909, 0x7909}, + {0x790A, 0x790A}, {0x790B, 0x790B}, {0x790C, 0x790C}, {0x790D, 0x790D}, {0x790E, 0x790E}, {0x790F, 0x790F}, {0x7910, 0x7910}, + {0x7911, 0x7911}, {0x7912, 0x7912}, {0x7913, 0x7913}, {0x7914, 0x7914}, {0x7915, 0x7915}, {0x7916, 0x7916}, {0x7917, 0x7917}, + {0x7918, 0x7918}, {0x7919, 0x7919}, {0x791A, 0x791A}, {0x791B, 0x791B}, {0x791C, 0x791C}, {0x791D, 0x791D}, {0x791E, 0x791E}, + {0x791F, 0x791F}, {0x7920, 0x7920}, {0x7921, 0x7921}, {0x7922, 0x7922}, {0x7923, 0x7923}, {0x7924, 0x7924}, {0x7925, 0x7925}, + {0x7926, 0x7926}, {0x7927, 0x7927}, {0x7928, 0x7928}, {0x7929, 0x7929}, {0x792A, 0x792A}, {0x792B, 0x792B}, {0x792C, 0x792C}, + {0x792D, 0x792D}, {0x792E, 0x792E}, {0x792F, 0x792F}, {0x7930, 0x7930}, {0x7931, 0x7931}, {0x7932, 0x7932}, {0x7933, 0x7933}, + {0x7934, 0x7934}, {0x7935, 0x7935}, {0x7936, 0x7936}, {0x7937, 0x7937}, {0x7938, 0x7938}, {0x7939, 0x7939}, {0x793A, 0x793A}, + {0x793B, 0x793B}, {0x793C, 0x793C}, {0x793D, 0x793D}, {0x793E, 0x793E}, {0x793F, 0x793F}, {0x7940, 0x7940}, {0x7941, 0x7941}, + {0x7942, 0x7942}, {0x7943, 0x7943}, {0x7944, 0x7944}, {0x7945, 0x7945}, {0x7946, 0x7946}, {0x7947, 0x7947}, {0x7948, 0x7948}, + {0x7949, 0x7949}, {0x794A, 0x794A}, {0x794B, 0x794B}, {0x794C, 0x794C}, {0x794D, 0x794D}, {0x794E, 0x794E}, {0x794F, 0x794F}, + {0x7950, 0x7950}, {0x7951, 0x7951}, {0x7952, 0x7952}, {0x7953, 0x7953}, {0x7954, 0x7954}, {0x7955, 0x7955}, {0x7956, 0x7956}, + {0x7957, 0x7957}, {0x7958, 0x7958}, {0x7959, 0x7959}, {0x795A, 0x795A}, {0x795B, 0x795B}, {0x795C, 0x795C}, {0x795D, 0x795D}, + {0x795E, 0x795E}, {0x795F, 0x795F}, {0x7960, 0x7960}, {0x7961, 0x7961}, {0x7962, 0x7962}, {0x7963, 0x7963}, {0x7964, 0x7964}, + {0x7965, 0x7965}, {0x7966, 0x7966}, {0x7967, 0x7967}, {0x7968, 0x7968}, {0x7969, 0x7969}, {0x796A, 0x796A}, {0x796B, 0x796B}, + {0x796C, 0x796C}, {0x796D, 0x796D}, {0x796E, 0x796E}, {0x796F, 0x796F}, {0x7970, 0x7970}, {0x7971, 0x7971}, {0x7972, 0x7972}, + {0x7973, 0x7973}, {0x7974, 0x7974}, {0x7975, 0x7975}, {0x7976, 0x7976}, {0x7977, 0x7977}, {0x7978, 0x7978}, {0x7979, 0x7979}, + {0x797A, 0x797A}, {0x797B, 0x797B}, {0x797C, 0x797C}, {0x797D, 0x797D}, {0x797E, 0x797E}, {0x797F, 0x797F}, {0x7980, 0x7980}, + {0x7981, 0x7981}, {0x7982, 0x7982}, {0x7983, 0x7983}, {0x7984, 0x7984}, {0x7985, 0x7985}, {0x7986, 0x7986}, {0x7987, 0x7987}, + {0x7988, 0x7988}, {0x7989, 0x7989}, {0x798A, 0x798A}, {0x798B, 0x798B}, {0x798C, 0x798C}, {0x798D, 0x798D}, {0x798E, 0x798E}, + {0x798F, 0x798F}, {0x7990, 0x7990}, {0x7991, 0x7991}, {0x7992, 0x7992}, {0x7993, 0x7993}, {0x7994, 0x7994}, {0x7995, 0x7995}, + {0x7996, 0x7996}, {0x7997, 0x7997}, {0x7998, 0x7998}, {0x7999, 0x7999}, {0x799A, 0x799A}, {0x799B, 0x799B}, {0x799C, 0x799C}, + {0x799D, 0x799D}, {0x799E, 0x799E}, {0x799F, 0x799F}, {0x79A0, 0x79A0}, {0x79A1, 0x79A1}, {0x79A2, 0x79A2}, {0x79A3, 0x79A3}, + {0x79A4, 0x79A4}, {0x79A5, 0x79A5}, {0x79A6, 0x79A6}, {0x79A7, 0x79A7}, {0x79A8, 0x79A8}, {0x79A9, 0x79A9}, {0x79AA, 0x79AA}, + {0x79AB, 0x79AB}, {0x79AC, 0x79AC}, {0x79AD, 0x79AD}, {0x79AE, 0x79AE}, {0x79AF, 0x79AF}, {0x79B0, 0x79B0}, {0x79B1, 0x79B1}, + {0x79B2, 0x79B2}, {0x79B3, 0x79B3}, {0x79B4, 0x79B4}, {0x79B5, 0x79B5}, {0x79B6, 0x79B6}, {0x79B7, 0x79B7}, {0x79B8, 0x79B8}, + {0x79B9, 0x79B9}, {0x79BA, 0x79BA}, {0x79BB, 0x79BB}, {0x79BC, 0x79BC}, {0x79BD, 0x79BD}, {0x79BE, 0x79BE}, {0x79BF, 0x79BF}, + {0x79C0, 0x79C0}, {0x79C1, 0x79C1}, {0x79C2, 0x79C2}, {0x79C3, 0x79C3}, {0x79C4, 0x79C4}, {0x79C5, 0x79C5}, {0x79C6, 0x79C6}, + {0x79C7, 0x79C7}, {0x79C8, 0x79C8}, {0x79C9, 0x79C9}, {0x79CA, 0x79CA}, {0x79CB, 0x79CB}, {0x79CC, 0x79CC}, {0x79CD, 0x79CD}, + {0x79CE, 0x79CE}, {0x79CF, 0x79CF}, {0x79D0, 0x79D0}, {0x79D1, 0x79D1}, {0x79D2, 0x79D2}, {0x79D3, 0x79D3}, {0x79D4, 0x79D4}, + {0x79D5, 0x79D5}, {0x79D6, 0x79D6}, {0x79D7, 0x79D7}, {0x79D8, 0x79D8}, {0x79D9, 0x79D9}, {0x79DA, 0x79DA}, {0x79DB, 0x79DB}, + {0x79DC, 0x79DC}, {0x79DD, 0x79DD}, {0x79DE, 0x79DE}, {0x79DF, 0x79DF}, {0x79E0, 0x79E0}, {0x79E1, 0x79E1}, {0x79E2, 0x79E2}, + {0x79E3, 0x79E3}, {0x79E4, 0x79E4}, {0x79E5, 0x79E5}, {0x79E6, 0x79E6}, {0x79E7, 0x79E7}, {0x79E8, 0x79E8}, {0x79E9, 0x79E9}, + {0x79EA, 0x79EA}, {0x79EB, 0x79EB}, {0x79EC, 0x79EC}, {0x79ED, 0x79ED}, {0x79EE, 0x79EE}, {0x79EF, 0x79EF}, {0x79F0, 0x79F0}, + {0x79F1, 0x79F1}, {0x79F2, 0x79F2}, {0x79F3, 0x79F3}, {0x79F4, 0x79F4}, {0x79F5, 0x79F5}, {0x79F6, 0x79F6}, {0x79F7, 0x79F7}, + {0x79F8, 0x79F8}, {0x79F9, 0x79F9}, {0x79FA, 0x79FA}, {0x79FB, 0x79FB}, {0x79FC, 0x79FC}, {0x79FD, 0x79FD}, {0x79FE, 0x79FE}, + {0x79FF, 0x79FF}, {0x7A00, 0x7A00}, {0x7A01, 0x7A01}, {0x7A02, 0x7A02}, {0x7A03, 0x7A03}, {0x7A04, 0x7A04}, {0x7A05, 0x7A05}, + {0x7A06, 0x7A06}, {0x7A07, 0x7A07}, {0x7A08, 0x7A08}, {0x7A09, 0x7A09}, {0x7A0A, 0x7A0A}, {0x7A0B, 0x7A0B}, {0x7A0C, 0x7A0C}, + {0x7A0D, 0x7A0D}, {0x7A0E, 0x7A0E}, {0x7A0F, 0x7A0F}, {0x7A10, 0x7A10}, {0x7A11, 0x7A11}, {0x7A12, 0x7A12}, {0x7A13, 0x7A13}, + {0x7A14, 0x7A14}, {0x7A15, 0x7A15}, {0x7A16, 0x7A16}, {0x7A17, 0x7A17}, {0x7A18, 0x7A18}, {0x7A19, 0x7A19}, {0x7A1A, 0x7A1A}, + {0x7A1B, 0x7A1B}, {0x7A1C, 0x7A1C}, {0x7A1D, 0x7A1D}, {0x7A1E, 0x7A1E}, {0x7A1F, 0x7A1F}, {0x7A20, 0x7A20}, {0x7A21, 0x7A21}, + {0x7A22, 0x7A22}, {0x7A23, 0x7A23}, {0x7A24, 0x7A24}, {0x7A25, 0x7A25}, {0x7A26, 0x7A26}, {0x7A27, 0x7A27}, {0x7A28, 0x7A28}, + {0x7A29, 0x7A29}, {0x7A2A, 0x7A2A}, {0x7A2B, 0x7A2B}, {0x7A2C, 0x7A2C}, {0x7A2D, 0x7A2D}, {0x7A2E, 0x7A2E}, {0x7A2F, 0x7A2F}, + {0x7A30, 0x7A30}, {0x7A31, 0x7A31}, {0x7A32, 0x7A32}, {0x7A33, 0x7A33}, {0x7A34, 0x7A34}, {0x7A35, 0x7A35}, {0x7A36, 0x7A36}, + {0x7A37, 0x7A37}, {0x7A38, 0x7A38}, {0x7A39, 0x7A39}, {0x7A3A, 0x7A3A}, {0x7A3B, 0x7A3B}, {0x7A3C, 0x7A3C}, {0x7A3D, 0x7A3D}, + {0x7A3E, 0x7A3E}, {0x7A3F, 0x7A3F}, {0x7A40, 0x7A40}, {0x7A41, 0x7A41}, {0x7A42, 0x7A42}, {0x7A43, 0x7A43}, {0x7A44, 0x7A44}, + {0x7A45, 0x7A45}, {0x7A46, 0x7A46}, {0x7A47, 0x7A47}, {0x7A48, 0x7A48}, {0x7A49, 0x7A49}, {0x7A4A, 0x7A4A}, {0x7A4B, 0x7A4B}, + {0x7A4C, 0x7A4C}, {0x7A4D, 0x7A4D}, {0x7A4E, 0x7A4E}, {0x7A4F, 0x7A4F}, {0x7A50, 0x7A50}, {0x7A51, 0x7A51}, {0x7A52, 0x7A52}, + {0x7A53, 0x7A53}, {0x7A54, 0x7A54}, {0x7A55, 0x7A55}, {0x7A56, 0x7A56}, {0x7A57, 0x7A57}, {0x7A58, 0x7A58}, {0x7A59, 0x7A59}, + {0x7A5A, 0x7A5A}, {0x7A5B, 0x7A5B}, {0x7A5C, 0x7A5C}, {0x7A5D, 0x7A5D}, {0x7A5E, 0x7A5E}, {0x7A5F, 0x7A5F}, {0x7A60, 0x7A60}, + {0x7A61, 0x7A61}, {0x7A62, 0x7A62}, {0x7A63, 0x7A63}, {0x7A64, 0x7A64}, {0x7A65, 0x7A65}, {0x7A66, 0x7A66}, {0x7A67, 0x7A67}, + {0x7A68, 0x7A68}, {0x7A69, 0x7A69}, {0x7A6A, 0x7A6A}, {0x7A6B, 0x7A6B}, {0x7A6C, 0x7A6C}, {0x7A6D, 0x7A6D}, {0x7A6E, 0x7A6E}, + {0x7A6F, 0x7A6F}, {0x7A70, 0x7A70}, {0x7A71, 0x7A71}, {0x7A72, 0x7A72}, {0x7A73, 0x7A73}, {0x7A74, 0x7A74}, {0x7A75, 0x7A75}, + {0x7A76, 0x7A76}, {0x7A77, 0x7A77}, {0x7A78, 0x7A78}, {0x7A79, 0x7A79}, {0x7A7A, 0x7A7A}, {0x7A7B, 0x7A7B}, {0x7A7C, 0x7A7C}, + {0x7A7D, 0x7A7D}, {0x7A7E, 0x7A7E}, {0x7A7F, 0x7A7F}, {0x7A80, 0x7A80}, {0x7A81, 0x7A81}, {0x7A82, 0x7A82}, {0x7A83, 0x7A83}, + {0x7A84, 0x7A84}, {0x7A85, 0x7A85}, {0x7A86, 0x7A86}, {0x7A87, 0x7A87}, {0x7A88, 0x7A88}, {0x7A89, 0x7A89}, {0x7A8A, 0x7A8A}, + {0x7A8B, 0x7A8B}, {0x7A8C, 0x7A8C}, {0x7A8D, 0x7A8D}, {0x7A8E, 0x7A8E}, {0x7A8F, 0x7A8F}, {0x7A90, 0x7A90}, {0x7A91, 0x7A91}, + {0x7A92, 0x7A92}, {0x7A93, 0x7A93}, {0x7A94, 0x7A94}, {0x7A95, 0x7A95}, {0x7A96, 0x7A96}, {0x7A97, 0x7A97}, {0x7A98, 0x7A98}, + {0x7A99, 0x7A99}, {0x7A9A, 0x7A9A}, {0x7A9B, 0x7A9B}, {0x7A9C, 0x7A9C}, {0x7A9D, 0x7A9D}, {0x7A9E, 0x7A9E}, {0x7A9F, 0x7A9F}, + {0x7AA0, 0x7AA0}, {0x7AA1, 0x7AA1}, {0x7AA2, 0x7AA2}, {0x7AA3, 0x7AA3}, {0x7AA4, 0x7AA4}, {0x7AA5, 0x7AA5}, {0x7AA6, 0x7AA6}, + {0x7AA7, 0x7AA7}, {0x7AA8, 0x7AA8}, {0x7AA9, 0x7AA9}, {0x7AAA, 0x7AAA}, {0x7AAB, 0x7AAB}, {0x7AAC, 0x7AAC}, {0x7AAD, 0x7AAD}, + {0x7AAE, 0x7AAE}, {0x7AAF, 0x7AAF}, {0x7AB0, 0x7AB0}, {0x7AB1, 0x7AB1}, {0x7AB2, 0x7AB2}, {0x7AB3, 0x7AB3}, {0x7AB4, 0x7AB4}, + {0x7AB5, 0x7AB5}, {0x7AB6, 0x7AB6}, {0x7AB7, 0x7AB7}, {0x7AB8, 0x7AB8}, {0x7AB9, 0x7AB9}, {0x7ABA, 0x7ABA}, {0x7ABB, 0x7ABB}, + {0x7ABC, 0x7ABC}, {0x7ABD, 0x7ABD}, {0x7ABE, 0x7ABE}, {0x7ABF, 0x7ABF}, {0x7AC0, 0x7AC0}, {0x7AC1, 0x7AC1}, {0x7AC2, 0x7AC2}, + {0x7AC3, 0x7AC3}, {0x7AC4, 0x7AC4}, {0x7AC5, 0x7AC5}, {0x7AC6, 0x7AC6}, {0x7AC7, 0x7AC7}, {0x7AC8, 0x7AC8}, {0x7AC9, 0x7AC9}, + {0x7ACA, 0x7ACA}, {0x7ACB, 0x7ACB}, {0x7ACC, 0x7ACC}, {0x7ACD, 0x7ACD}, {0x7ACE, 0x7ACE}, {0x7ACF, 0x7ACF}, {0x7AD0, 0x7AD0}, + {0x7AD1, 0x7AD1}, {0x7AD2, 0x7AD2}, {0x7AD3, 0x7AD3}, {0x7AD4, 0x7AD4}, {0x7AD5, 0x7AD5}, {0x7AD6, 0x7AD6}, {0x7AD7, 0x7AD7}, + {0x7AD8, 0x7AD8}, {0x7AD9, 0x7AD9}, {0x7ADA, 0x7ADA}, {0x7ADB, 0x7ADB}, {0x7ADC, 0x7ADC}, {0x7ADD, 0x7ADD}, {0x7ADE, 0x7ADE}, + {0x7ADF, 0x7ADF}, {0x7AE0, 0x7AE0}, {0x7AE1, 0x7AE1}, {0x7AE2, 0x7AE2}, {0x7AE3, 0x7AE3}, {0x7AE4, 0x7AE4}, {0x7AE5, 0x7AE5}, + {0x7AE6, 0x7AE6}, {0x7AE7, 0x7AE7}, {0x7AE8, 0x7AE8}, {0x7AE9, 0x7AE9}, {0x7AEA, 0x7AEA}, {0x7AEB, 0x7AEB}, {0x7AEC, 0x7AEC}, + {0x7AED, 0x7AED}, {0x7AEE, 0x7AEE}, {0x7AEF, 0x7AEF}, {0x7AF0, 0x7AF0}, {0x7AF1, 0x7AF1}, {0x7AF2, 0x7AF2}, {0x7AF3, 0x7AF3}, + {0x7AF4, 0x7AF4}, {0x7AF5, 0x7AF5}, {0x7AF6, 0x7AF6}, {0x7AF7, 0x7AF7}, {0x7AF8, 0x7AF8}, {0x7AF9, 0x7AF9}, {0x7AFA, 0x7AFA}, + {0x7AFB, 0x7AFB}, {0x7AFC, 0x7AFC}, {0x7AFD, 0x7AFD}, {0x7AFE, 0x7AFE}, {0x7AFF, 0x7AFF}, {0x7B00, 0x7B00}, {0x7B01, 0x7B01}, + {0x7B02, 0x7B02}, {0x7B03, 0x7B03}, {0x7B04, 0x7B04}, {0x7B05, 0x7B05}, {0x7B06, 0x7B06}, {0x7B07, 0x7B07}, {0x7B08, 0x7B08}, + {0x7B09, 0x7B09}, {0x7B0A, 0x7B0A}, {0x7B0B, 0x7B0B}, {0x7B0C, 0x7B0C}, {0x7B0D, 0x7B0D}, {0x7B0E, 0x7B0E}, {0x7B0F, 0x7B0F}, + {0x7B10, 0x7B10}, {0x7B11, 0x7B11}, {0x7B12, 0x7B12}, {0x7B13, 0x7B13}, {0x7B14, 0x7B14}, {0x7B15, 0x7B15}, {0x7B16, 0x7B16}, + {0x7B17, 0x7B17}, {0x7B18, 0x7B18}, {0x7B19, 0x7B19}, {0x7B1A, 0x7B1A}, {0x7B1B, 0x7B1B}, {0x7B1C, 0x7B1C}, {0x7B1D, 0x7B1D}, + {0x7B1E, 0x7B1E}, {0x7B1F, 0x7B1F}, {0x7B20, 0x7B20}, {0x7B21, 0x7B21}, {0x7B22, 0x7B22}, {0x7B23, 0x7B23}, {0x7B24, 0x7B24}, + {0x7B25, 0x7B25}, {0x7B26, 0x7B26}, {0x7B27, 0x7B27}, {0x7B28, 0x7B28}, {0x7B29, 0x7B29}, {0x7B2A, 0x7B2A}, {0x7B2B, 0x7B2B}, + {0x7B2C, 0x7B2C}, {0x7B2D, 0x7B2D}, {0x7B2E, 0x7B2E}, {0x7B2F, 0x7B2F}, {0x7B30, 0x7B30}, {0x7B31, 0x7B31}, {0x7B32, 0x7B32}, + {0x7B33, 0x7B33}, {0x7B34, 0x7B34}, {0x7B35, 0x7B35}, {0x7B36, 0x7B36}, {0x7B37, 0x7B37}, {0x7B38, 0x7B38}, {0x7B39, 0x7B39}, + {0x7B3A, 0x7B3A}, {0x7B3B, 0x7B3B}, {0x7B3C, 0x7B3C}, {0x7B3D, 0x7B3D}, {0x7B3E, 0x7B3E}, {0x7B3F, 0x7B3F}, {0x7B40, 0x7B40}, + {0x7B41, 0x7B41}, {0x7B42, 0x7B42}, {0x7B43, 0x7B43}, {0x7B44, 0x7B44}, {0x7B45, 0x7B45}, {0x7B46, 0x7B46}, {0x7B47, 0x7B47}, + {0x7B48, 0x7B48}, {0x7B49, 0x7B49}, {0x7B4A, 0x7B4A}, {0x7B4B, 0x7B4B}, {0x7B4C, 0x7B4C}, {0x7B4D, 0x7B4D}, {0x7B4E, 0x7B4E}, + {0x7B4F, 0x7B4F}, {0x7B50, 0x7B50}, {0x7B51, 0x7B51}, {0x7B52, 0x7B52}, {0x7B53, 0x7B53}, {0x7B54, 0x7B54}, {0x7B55, 0x7B55}, + {0x7B56, 0x7B56}, {0x7B57, 0x7B57}, {0x7B58, 0x7B58}, {0x7B59, 0x7B59}, {0x7B5A, 0x7B5A}, {0x7B5B, 0x7B5B}, {0x7B5C, 0x7B5C}, + {0x7B5D, 0x7B5D}, {0x7B5E, 0x7B5E}, {0x7B5F, 0x7B5F}, {0x7B60, 0x7B60}, {0x7B61, 0x7B61}, {0x7B62, 0x7B62}, {0x7B63, 0x7B63}, + {0x7B64, 0x7B64}, {0x7B65, 0x7B65}, {0x7B66, 0x7B66}, {0x7B67, 0x7B67}, {0x7B68, 0x7B68}, {0x7B69, 0x7B69}, {0x7B6A, 0x7B6A}, + {0x7B6B, 0x7B6B}, {0x7B6C, 0x7B6C}, {0x7B6D, 0x7B6D}, {0x7B6E, 0x7B6E}, {0x7B6F, 0x7B6F}, {0x7B70, 0x7B70}, {0x7B71, 0x7B71}, + {0x7B72, 0x7B72}, {0x7B73, 0x7B73}, {0x7B74, 0x7B74}, {0x7B75, 0x7B75}, {0x7B76, 0x7B76}, {0x7B77, 0x7B77}, {0x7B78, 0x7B78}, + {0x7B79, 0x7B79}, {0x7B7A, 0x7B7A}, {0x7B7B, 0x7B7B}, {0x7B7C, 0x7B7C}, {0x7B7D, 0x7B7D}, {0x7B7E, 0x7B7E}, {0x7B7F, 0x7B7F}, + {0x7B80, 0x7B80}, {0x7B81, 0x7B81}, {0x7B82, 0x7B82}, {0x7B83, 0x7B83}, {0x7B84, 0x7B84}, {0x7B85, 0x7B85}, {0x7B86, 0x7B86}, + {0x7B87, 0x7B87}, {0x7B88, 0x7B88}, {0x7B89, 0x7B89}, {0x7B8A, 0x7B8A}, {0x7B8B, 0x7B8B}, {0x7B8C, 0x7B8C}, {0x7B8D, 0x7B8D}, + {0x7B8E, 0x7B8E}, {0x7B8F, 0x7B8F}, {0x7B90, 0x7B90}, {0x7B91, 0x7B91}, {0x7B92, 0x7B92}, {0x7B93, 0x7B93}, {0x7B94, 0x7B94}, + {0x7B95, 0x7B95}, {0x7B96, 0x7B96}, {0x7B97, 0x7B97}, {0x7B98, 0x7B98}, {0x7B99, 0x7B99}, {0x7B9A, 0x7B9A}, {0x7B9B, 0x7B9B}, + {0x7B9C, 0x7B9C}, {0x7B9D, 0x7B9D}, {0x7B9E, 0x7B9E}, {0x7B9F, 0x7B9F}, {0x7BA0, 0x7BA0}, {0x7BA1, 0x7BA1}, {0x7BA2, 0x7BA2}, + {0x7BA3, 0x7BA3}, {0x7BA4, 0x7BA4}, {0x7BA5, 0x7BA5}, {0x7BA6, 0x7BA6}, {0x7BA7, 0x7BA7}, {0x7BA8, 0x7BA8}, {0x7BA9, 0x7BA9}, + {0x7BAA, 0x7BAA}, {0x7BAB, 0x7BAB}, {0x7BAC, 0x7BAC}, {0x7BAD, 0x7BAD}, {0x7BAE, 0x7BAE}, {0x7BAF, 0x7BAF}, {0x7BB0, 0x7BB0}, + {0x7BB1, 0x7BB1}, {0x7BB2, 0x7BB2}, {0x7BB3, 0x7BB3}, {0x7BB4, 0x7BB4}, {0x7BB5, 0x7BB5}, {0x7BB6, 0x7BB6}, {0x7BB7, 0x7BB7}, + {0x7BB8, 0x7BB8}, {0x7BB9, 0x7BB9}, {0x7BBA, 0x7BBA}, {0x7BBB, 0x7BBB}, {0x7BBC, 0x7BBC}, {0x7BBD, 0x7BBD}, {0x7BBE, 0x7BBE}, + {0x7BBF, 0x7BBF}, {0x7BC0, 0x7BC0}, {0x7BC1, 0x7BC1}, {0x7BC2, 0x7BC2}, {0x7BC3, 0x7BC3}, {0x7BC4, 0x7BC4}, {0x7BC5, 0x7BC5}, + {0x7BC6, 0x7BC6}, {0x7BC7, 0x7BC7}, {0x7BC8, 0x7BC8}, {0x7BC9, 0x7BC9}, {0x7BCA, 0x7BCA}, {0x7BCB, 0x7BCB}, {0x7BCC, 0x7BCC}, + {0x7BCD, 0x7BCD}, {0x7BCE, 0x7BCE}, {0x7BCF, 0x7BCF}, {0x7BD0, 0x7BD0}, {0x7BD1, 0x7BD1}, {0x7BD2, 0x7BD2}, {0x7BD3, 0x7BD3}, + {0x7BD4, 0x7BD4}, {0x7BD5, 0x7BD5}, {0x7BD6, 0x7BD6}, {0x7BD7, 0x7BD7}, {0x7BD8, 0x7BD8}, {0x7BD9, 0x7BD9}, {0x7BDA, 0x7BDA}, + {0x7BDB, 0x7BDB}, {0x7BDC, 0x7BDC}, {0x7BDD, 0x7BDD}, {0x7BDE, 0x7BDE}, {0x7BDF, 0x7BDF}, {0x7BE0, 0x7BE0}, {0x7BE1, 0x7BE1}, + {0x7BE2, 0x7BE2}, {0x7BE3, 0x7BE3}, {0x7BE4, 0x7BE4}, {0x7BE5, 0x7BE5}, {0x7BE6, 0x7BE6}, {0x7BE7, 0x7BE7}, {0x7BE8, 0x7BE8}, + {0x7BE9, 0x7BE9}, {0x7BEA, 0x7BEA}, {0x7BEB, 0x7BEB}, {0x7BEC, 0x7BEC}, {0x7BED, 0x7BED}, {0x7BEE, 0x7BEE}, {0x7BEF, 0x7BEF}, + {0x7BF0, 0x7BF0}, {0x7BF1, 0x7BF1}, {0x7BF2, 0x7BF2}, {0x7BF3, 0x7BF3}, {0x7BF4, 0x7BF4}, {0x7BF5, 0x7BF5}, {0x7BF6, 0x7BF6}, + {0x7BF7, 0x7BF7}, {0x7BF8, 0x7BF8}, {0x7BF9, 0x7BF9}, {0x7BFA, 0x7BFA}, {0x7BFB, 0x7BFB}, {0x7BFC, 0x7BFC}, {0x7BFD, 0x7BFD}, + {0x7BFE, 0x7BFE}, {0x7BFF, 0x7BFF}, {0x7C00, 0x7C00}, {0x7C01, 0x7C01}, {0x7C02, 0x7C02}, {0x7C03, 0x7C03}, {0x7C04, 0x7C04}, + {0x7C05, 0x7C05}, {0x7C06, 0x7C06}, {0x7C07, 0x7C07}, {0x7C08, 0x7C08}, {0x7C09, 0x7C09}, {0x7C0A, 0x7C0A}, {0x7C0B, 0x7C0B}, + {0x7C0C, 0x7C0C}, {0x7C0D, 0x7C0D}, {0x7C0E, 0x7C0E}, {0x7C0F, 0x7C0F}, {0x7C10, 0x7C10}, {0x7C11, 0x7C11}, {0x7C12, 0x7C12}, + {0x7C13, 0x7C13}, {0x7C14, 0x7C14}, {0x7C15, 0x7C15}, {0x7C16, 0x7C16}, {0x7C17, 0x7C17}, {0x7C18, 0x7C18}, {0x7C19, 0x7C19}, + {0x7C1A, 0x7C1A}, {0x7C1B, 0x7C1B}, {0x7C1C, 0x7C1C}, {0x7C1D, 0x7C1D}, {0x7C1E, 0x7C1E}, {0x7C1F, 0x7C1F}, {0x7C20, 0x7C20}, + {0x7C21, 0x7C21}, {0x7C22, 0x7C22}, {0x7C23, 0x7C23}, {0x7C24, 0x7C24}, {0x7C25, 0x7C25}, {0x7C26, 0x7C26}, {0x7C27, 0x7C27}, + {0x7C28, 0x7C28}, {0x7C29, 0x7C29}, {0x7C2A, 0x7C2A}, {0x7C2B, 0x7C2B}, {0x7C2C, 0x7C2C}, {0x7C2D, 0x7C2D}, {0x7C2E, 0x7C2E}, + {0x7C2F, 0x7C2F}, {0x7C30, 0x7C30}, {0x7C31, 0x7C31}, {0x7C32, 0x7C32}, {0x7C33, 0x7C33}, {0x7C34, 0x7C34}, {0x7C35, 0x7C35}, + {0x7C36, 0x7C36}, {0x7C37, 0x7C37}, {0x7C38, 0x7C38}, {0x7C39, 0x7C39}, {0x7C3A, 0x7C3A}, {0x7C3B, 0x7C3B}, {0x7C3C, 0x7C3C}, + {0x7C3D, 0x7C3D}, {0x7C3E, 0x7C3E}, {0x7C3F, 0x7C3F}, {0x7C40, 0x7C40}, {0x7C41, 0x7C41}, {0x7C42, 0x7C42}, {0x7C43, 0x7C43}, + {0x7C44, 0x7C44}, {0x7C45, 0x7C45}, {0x7C46, 0x7C46}, {0x7C47, 0x7C47}, {0x7C48, 0x7C48}, {0x7C49, 0x7C49}, {0x7C4A, 0x7C4A}, + {0x7C4B, 0x7C4B}, {0x7C4C, 0x7C4C}, {0x7C4D, 0x7C4D}, {0x7C4E, 0x7C4E}, {0x7C4F, 0x7C4F}, {0x7C50, 0x7C50}, {0x7C51, 0x7C51}, + {0x7C52, 0x7C52}, {0x7C53, 0x7C53}, {0x7C54, 0x7C54}, {0x7C55, 0x7C55}, {0x7C56, 0x7C56}, {0x7C57, 0x7C57}, {0x7C58, 0x7C58}, + {0x7C59, 0x7C59}, {0x7C5A, 0x7C5A}, {0x7C5B, 0x7C5B}, {0x7C5C, 0x7C5C}, {0x7C5D, 0x7C5D}, {0x7C5E, 0x7C5E}, {0x7C5F, 0x7C5F}, + {0x7C60, 0x7C60}, {0x7C61, 0x7C61}, {0x7C62, 0x7C62}, {0x7C63, 0x7C63}, {0x7C64, 0x7C64}, {0x7C65, 0x7C65}, {0x7C66, 0x7C66}, + {0x7C67, 0x7C67}, {0x7C68, 0x7C68}, {0x7C69, 0x7C69}, {0x7C6A, 0x7C6A}, {0x7C6B, 0x7C6B}, {0x7C6C, 0x7C6C}, {0x7C6D, 0x7C6D}, + {0x7C6E, 0x7C6E}, {0x7C6F, 0x7C6F}, {0x7C70, 0x7C70}, {0x7C71, 0x7C71}, {0x7C72, 0x7C72}, {0x7C73, 0x7C73}, {0x7C74, 0x7C74}, + {0x7C75, 0x7C75}, {0x7C76, 0x7C76}, {0x7C77, 0x7C77}, {0x7C78, 0x7C78}, {0x7C79, 0x7C79}, {0x7C7A, 0x7C7A}, {0x7C7B, 0x7C7B}, + {0x7C7C, 0x7C7C}, {0x7C7D, 0x7C7D}, {0x7C7E, 0x7C7E}, {0x7C7F, 0x7C7F}, {0x7C80, 0x7C80}, {0x7C81, 0x7C81}, {0x7C82, 0x7C82}, + {0x7C83, 0x7C83}, {0x7C84, 0x7C84}, {0x7C85, 0x7C85}, {0x7C86, 0x7C86}, {0x7C87, 0x7C87}, {0x7C88, 0x7C88}, {0x7C89, 0x7C89}, + {0x7C8A, 0x7C8A}, {0x7C8B, 0x7C8B}, {0x7C8C, 0x7C8C}, {0x7C8D, 0x7C8D}, {0x7C8E, 0x7C8E}, {0x7C8F, 0x7C8F}, {0x7C90, 0x7C90}, + {0x7C91, 0x7C91}, {0x7C92, 0x7C92}, {0x7C93, 0x7C93}, {0x7C94, 0x7C94}, {0x7C95, 0x7C95}, {0x7C96, 0x7C96}, {0x7C97, 0x7C97}, + {0x7C98, 0x7C98}, {0x7C99, 0x7C99}, {0x7C9A, 0x7C9A}, {0x7C9B, 0x7C9B}, {0x7C9C, 0x7C9C}, {0x7C9D, 0x7C9D}, {0x7C9E, 0x7C9E}, + {0x7C9F, 0x7C9F}, {0x7CA0, 0x7CA0}, {0x7CA1, 0x7CA1}, {0x7CA2, 0x7CA2}, {0x7CA3, 0x7CA3}, {0x7CA4, 0x7CA4}, {0x7CA5, 0x7CA5}, + {0x7CA6, 0x7CA6}, {0x7CA7, 0x7CA7}, {0x7CA8, 0x7CA8}, {0x7CA9, 0x7CA9}, {0x7CAA, 0x7CAA}, {0x7CAB, 0x7CAB}, {0x7CAC, 0x7CAC}, + {0x7CAD, 0x7CAD}, {0x7CAE, 0x7CAE}, {0x7CAF, 0x7CAF}, {0x7CB0, 0x7CB0}, {0x7CB1, 0x7CB1}, {0x7CB2, 0x7CB2}, {0x7CB3, 0x7CB3}, + {0x7CB4, 0x7CB4}, {0x7CB5, 0x7CB5}, {0x7CB6, 0x7CB6}, {0x7CB7, 0x7CB7}, {0x7CB8, 0x7CB8}, {0x7CB9, 0x7CB9}, {0x7CBA, 0x7CBA}, + {0x7CBB, 0x7CBB}, {0x7CBC, 0x7CBC}, {0x7CBD, 0x7CBD}, {0x7CBE, 0x7CBE}, {0x7CBF, 0x7CBF}, {0x7CC0, 0x7CC0}, {0x7CC1, 0x7CC1}, + {0x7CC2, 0x7CC2}, {0x7CC3, 0x7CC3}, {0x7CC4, 0x7CC4}, {0x7CC5, 0x7CC5}, {0x7CC6, 0x7CC6}, {0x7CC7, 0x7CC7}, {0x7CC8, 0x7CC8}, + {0x7CC9, 0x7CC9}, {0x7CCA, 0x7CCA}, {0x7CCB, 0x7CCB}, {0x7CCC, 0x7CCC}, {0x7CCD, 0x7CCD}, {0x7CCE, 0x7CCE}, {0x7CCF, 0x7CCF}, + {0x7CD0, 0x7CD0}, {0x7CD1, 0x7CD1}, {0x7CD2, 0x7CD2}, {0x7CD3, 0x7CD3}, {0x7CD4, 0x7CD4}, {0x7CD5, 0x7CD5}, {0x7CD6, 0x7CD6}, + {0x7CD7, 0x7CD7}, {0x7CD8, 0x7CD8}, {0x7CD9, 0x7CD9}, {0x7CDA, 0x7CDA}, {0x7CDB, 0x7CDB}, {0x7CDC, 0x7CDC}, {0x7CDD, 0x7CDD}, + {0x7CDE, 0x7CDE}, {0x7CDF, 0x7CDF}, {0x7CE0, 0x7CE0}, {0x7CE1, 0x7CE1}, {0x7CE2, 0x7CE2}, {0x7CE3, 0x7CE3}, {0x7CE4, 0x7CE4}, + {0x7CE5, 0x7CE5}, {0x7CE6, 0x7CE6}, {0x7CE7, 0x7CE7}, {0x7CE8, 0x7CE8}, {0x7CE9, 0x7CE9}, {0x7CEA, 0x7CEA}, {0x7CEB, 0x7CEB}, + {0x7CEC, 0x7CEC}, {0x7CED, 0x7CED}, {0x7CEE, 0x7CEE}, {0x7CEF, 0x7CEF}, {0x7CF0, 0x7CF0}, {0x7CF1, 0x7CF1}, {0x7CF2, 0x7CF2}, + {0x7CF3, 0x7CF3}, {0x7CF4, 0x7CF4}, {0x7CF5, 0x7CF5}, {0x7CF6, 0x7CF6}, {0x7CF7, 0x7CF7}, {0x7CF8, 0x7CF8}, {0x7CF9, 0x7CF9}, + {0x7CFA, 0x7CFA}, {0x7CFB, 0x7CFB}, {0x7CFC, 0x7CFC}, {0x7CFD, 0x7CFD}, {0x7CFE, 0x7CFE}, {0x7CFF, 0x7CFF}, {0x7D00, 0x7D00}, + {0x7D01, 0x7D01}, {0x7D02, 0x7D02}, {0x7D03, 0x7D03}, {0x7D04, 0x7D04}, {0x7D05, 0x7D05}, {0x7D06, 0x7D06}, {0x7D07, 0x7D07}, + {0x7D08, 0x7D08}, {0x7D09, 0x7D09}, {0x7D0A, 0x7D0A}, {0x7D0B, 0x7D0B}, {0x7D0C, 0x7D0C}, {0x7D0D, 0x7D0D}, {0x7D0E, 0x7D0E}, + {0x7D0F, 0x7D0F}, {0x7D10, 0x7D10}, {0x7D11, 0x7D11}, {0x7D12, 0x7D12}, {0x7D13, 0x7D13}, {0x7D14, 0x7D14}, {0x7D15, 0x7D15}, + {0x7D16, 0x7D16}, {0x7D17, 0x7D17}, {0x7D18, 0x7D18}, {0x7D19, 0x7D19}, {0x7D1A, 0x7D1A}, {0x7D1B, 0x7D1B}, {0x7D1C, 0x7D1C}, + {0x7D1D, 0x7D1D}, {0x7D1E, 0x7D1E}, {0x7D1F, 0x7D1F}, {0x7D20, 0x7D20}, {0x7D21, 0x7D21}, {0x7D22, 0x7D22}, {0x7D23, 0x7D23}, + {0x7D24, 0x7D24}, {0x7D25, 0x7D25}, {0x7D26, 0x7D26}, {0x7D27, 0x7D27}, {0x7D28, 0x7D28}, {0x7D29, 0x7D29}, {0x7D2A, 0x7D2A}, + {0x7D2B, 0x7D2B}, {0x7D2C, 0x7D2C}, {0x7D2D, 0x7D2D}, {0x7D2E, 0x7D2E}, {0x7D2F, 0x7D2F}, {0x7D30, 0x7D30}, {0x7D31, 0x7D31}, + {0x7D32, 0x7D32}, {0x7D33, 0x7D33}, {0x7D34, 0x7D34}, {0x7D35, 0x7D35}, {0x7D36, 0x7D36}, {0x7D37, 0x7D37}, {0x7D38, 0x7D38}, + {0x7D39, 0x7D39}, {0x7D3A, 0x7D3A}, {0x7D3B, 0x7D3B}, {0x7D3C, 0x7D3C}, {0x7D3D, 0x7D3D}, {0x7D3E, 0x7D3E}, {0x7D3F, 0x7D3F}, + {0x7D40, 0x7D40}, {0x7D41, 0x7D41}, {0x7D42, 0x7D42}, {0x7D43, 0x7D43}, {0x7D44, 0x7D44}, {0x7D45, 0x7D45}, {0x7D46, 0x7D46}, + {0x7D47, 0x7D47}, {0x7D48, 0x7D48}, {0x7D49, 0x7D49}, {0x7D4A, 0x7D4A}, {0x7D4B, 0x7D4B}, {0x7D4C, 0x7D4C}, {0x7D4D, 0x7D4D}, + {0x7D4E, 0x7D4E}, {0x7D4F, 0x7D4F}, {0x7D50, 0x7D50}, {0x7D51, 0x7D51}, {0x7D52, 0x7D52}, {0x7D53, 0x7D53}, {0x7D54, 0x7D54}, + {0x7D55, 0x7D55}, {0x7D56, 0x7D56}, {0x7D57, 0x7D57}, {0x7D58, 0x7D58}, {0x7D59, 0x7D59}, {0x7D5A, 0x7D5A}, {0x7D5B, 0x7D5B}, + {0x7D5C, 0x7D5C}, {0x7D5D, 0x7D5D}, {0x7D5E, 0x7D5E}, {0x7D5F, 0x7D5F}, {0x7D60, 0x7D60}, {0x7D61, 0x7D61}, {0x7D62, 0x7D62}, + {0x7D63, 0x7D63}, {0x7D64, 0x7D64}, {0x7D65, 0x7D65}, {0x7D66, 0x7D66}, {0x7D67, 0x7D67}, {0x7D68, 0x7D68}, {0x7D69, 0x7D69}, + {0x7D6A, 0x7D6A}, {0x7D6B, 0x7D6B}, {0x7D6C, 0x7D6C}, {0x7D6D, 0x7D6D}, {0x7D6E, 0x7D6E}, {0x7D6F, 0x7D6F}, {0x7D70, 0x7D70}, + {0x7D71, 0x7D71}, {0x7D72, 0x7D72}, {0x7D73, 0x7D73}, {0x7D74, 0x7D74}, {0x7D75, 0x7D75}, {0x7D76, 0x7D76}, {0x7D77, 0x7D77}, + {0x7D78, 0x7D78}, {0x7D79, 0x7D79}, {0x7D7A, 0x7D7A}, {0x7D7B, 0x7D7B}, {0x7D7C, 0x7D7C}, {0x7D7D, 0x7D7D}, {0x7D7E, 0x7D7E}, + {0x7D7F, 0x7D7F}, {0x7D80, 0x7D80}, {0x7D81, 0x7D81}, {0x7D82, 0x7D82}, {0x7D83, 0x7D83}, {0x7D84, 0x7D84}, {0x7D85, 0x7D85}, + {0x7D86, 0x7D86}, {0x7D87, 0x7D87}, {0x7D88, 0x7D88}, {0x7D89, 0x7D89}, {0x7D8A, 0x7D8A}, {0x7D8B, 0x7D8B}, {0x7D8C, 0x7D8C}, + {0x7D8D, 0x7D8D}, {0x7D8E, 0x7D8E}, {0x7D8F, 0x7D8F}, {0x7D90, 0x7D90}, {0x7D91, 0x7D91}, {0x7D92, 0x7D92}, {0x7D93, 0x7D93}, + {0x7D94, 0x7D94}, {0x7D95, 0x7D95}, {0x7D96, 0x7D96}, {0x7D97, 0x7D97}, {0x7D98, 0x7D98}, {0x7D99, 0x7D99}, {0x7D9A, 0x7D9A}, + {0x7D9B, 0x7D9B}, {0x7D9C, 0x7D9C}, {0x7D9D, 0x7D9D}, {0x7D9E, 0x7D9E}, {0x7D9F, 0x7D9F}, {0x7DA0, 0x7DA0}, {0x7DA1, 0x7DA1}, + {0x7DA2, 0x7DA2}, {0x7DA3, 0x7DA3}, {0x7DA4, 0x7DA4}, {0x7DA5, 0x7DA5}, {0x7DA6, 0x7DA6}, {0x7DA7, 0x7DA7}, {0x7DA8, 0x7DA8}, + {0x7DA9, 0x7DA9}, {0x7DAA, 0x7DAA}, {0x7DAB, 0x7DAB}, {0x7DAC, 0x7DAC}, {0x7DAD, 0x7DAD}, {0x7DAE, 0x7DAE}, {0x7DAF, 0x7DAF}, + {0x7DB0, 0x7DB0}, {0x7DB1, 0x7DB1}, {0x7DB2, 0x7DB2}, {0x7DB3, 0x7DB3}, {0x7DB4, 0x7DB4}, {0x7DB5, 0x7DB5}, {0x7DB6, 0x7DB6}, + {0x7DB7, 0x7DB7}, {0x7DB8, 0x7DB8}, {0x7DB9, 0x7DB9}, {0x7DBA, 0x7DBA}, {0x7DBB, 0x7DBB}, {0x7DBC, 0x7DBC}, {0x7DBD, 0x7DBD}, + {0x7DBE, 0x7DBE}, {0x7DBF, 0x7DBF}, {0x7DC0, 0x7DC0}, {0x7DC1, 0x7DC1}, {0x7DC2, 0x7DC2}, {0x7DC3, 0x7DC3}, {0x7DC4, 0x7DC4}, + {0x7DC5, 0x7DC5}, {0x7DC6, 0x7DC6}, {0x7DC7, 0x7DC7}, {0x7DC8, 0x7DC8}, {0x7DC9, 0x7DC9}, {0x7DCA, 0x7DCA}, {0x7DCB, 0x7DCB}, + {0x7DCC, 0x7DCC}, {0x7DCD, 0x7DCD}, {0x7DCE, 0x7DCE}, {0x7DCF, 0x7DCF}, {0x7DD0, 0x7DD0}, {0x7DD1, 0x7DD1}, {0x7DD2, 0x7DD2}, + {0x7DD3, 0x7DD3}, {0x7DD4, 0x7DD4}, {0x7DD5, 0x7DD5}, {0x7DD6, 0x7DD6}, {0x7DD7, 0x7DD7}, {0x7DD8, 0x7DD8}, {0x7DD9, 0x7DD9}, + {0x7DDA, 0x7DDA}, {0x7DDB, 0x7DDB}, {0x7DDC, 0x7DDC}, {0x7DDD, 0x7DDD}, {0x7DDE, 0x7DDE}, {0x7DDF, 0x7DDF}, {0x7DE0, 0x7DE0}, + {0x7DE1, 0x7DE1}, {0x7DE2, 0x7DE2}, {0x7DE3, 0x7DE3}, {0x7DE4, 0x7DE4}, {0x7DE5, 0x7DE5}, {0x7DE6, 0x7DE6}, {0x7DE7, 0x7DE7}, + {0x7DE8, 0x7DE8}, {0x7DE9, 0x7DE9}, {0x7DEA, 0x7DEA}, {0x7DEB, 0x7DEB}, {0x7DEC, 0x7DEC}, {0x7DED, 0x7DED}, {0x7DEE, 0x7DEE}, + {0x7DEF, 0x7DEF}, {0x7DF0, 0x7DF0}, {0x7DF1, 0x7DF1}, {0x7DF2, 0x7DF2}, {0x7DF3, 0x7DF3}, {0x7DF4, 0x7DF4}, {0x7DF5, 0x7DF5}, + {0x7DF6, 0x7DF6}, {0x7DF7, 0x7DF7}, {0x7DF8, 0x7DF8}, {0x7DF9, 0x7DF9}, {0x7DFA, 0x7DFA}, {0x7DFB, 0x7DFB}, {0x7DFC, 0x7DFC}, + {0x7DFD, 0x7DFD}, {0x7DFE, 0x7DFE}, {0x7DFF, 0x7DFF}, {0x7E00, 0x7E00}, {0x7E01, 0x7E01}, {0x7E02, 0x7E02}, {0x7E03, 0x7E03}, + {0x7E04, 0x7E04}, {0x7E05, 0x7E05}, {0x7E06, 0x7E06}, {0x7E07, 0x7E07}, {0x7E08, 0x7E08}, {0x7E09, 0x7E09}, {0x7E0A, 0x7E0A}, + {0x7E0B, 0x7E0B}, {0x7E0C, 0x7E0C}, {0x7E0D, 0x7E0D}, {0x7E0E, 0x7E0E}, {0x7E0F, 0x7E0F}, {0x7E10, 0x7E10}, {0x7E11, 0x7E11}, + {0x7E12, 0x7E12}, {0x7E13, 0x7E13}, {0x7E14, 0x7E14}, {0x7E15, 0x7E15}, {0x7E16, 0x7E16}, {0x7E17, 0x7E17}, {0x7E18, 0x7E18}, + {0x7E19, 0x7E19}, {0x7E1A, 0x7E1A}, {0x7E1B, 0x7E1B}, {0x7E1C, 0x7E1C}, {0x7E1D, 0x7E1D}, {0x7E1E, 0x7E1E}, {0x7E1F, 0x7E1F}, + {0x7E20, 0x7E20}, {0x7E21, 0x7E21}, {0x7E22, 0x7E22}, {0x7E23, 0x7E23}, {0x7E24, 0x7E24}, {0x7E25, 0x7E25}, {0x7E26, 0x7E26}, + {0x7E27, 0x7E27}, {0x7E28, 0x7E28}, {0x7E29, 0x7E29}, {0x7E2A, 0x7E2A}, {0x7E2B, 0x7E2B}, {0x7E2C, 0x7E2C}, {0x7E2D, 0x7E2D}, + {0x7E2E, 0x7E2E}, {0x7E2F, 0x7E2F}, {0x7E30, 0x7E30}, {0x7E31, 0x7E31}, {0x7E32, 0x7E32}, {0x7E33, 0x7E33}, {0x7E34, 0x7E34}, + {0x7E35, 0x7E35}, {0x7E36, 0x7E36}, {0x7E37, 0x7E37}, {0x7E38, 0x7E38}, {0x7E39, 0x7E39}, {0x7E3A, 0x7E3A}, {0x7E3B, 0x7E3B}, + {0x7E3C, 0x7E3C}, {0x7E3D, 0x7E3D}, {0x7E3E, 0x7E3E}, {0x7E3F, 0x7E3F}, {0x7E40, 0x7E40}, {0x7E41, 0x7E41}, {0x7E42, 0x7E42}, + {0x7E43, 0x7E43}, {0x7E44, 0x7E44}, {0x7E45, 0x7E45}, {0x7E46, 0x7E46}, {0x7E47, 0x7E47}, {0x7E48, 0x7E48}, {0x7E49, 0x7E49}, + {0x7E4A, 0x7E4A}, {0x7E4B, 0x7E4B}, {0x7E4C, 0x7E4C}, {0x7E4D, 0x7E4D}, {0x7E4E, 0x7E4E}, {0x7E4F, 0x7E4F}, {0x7E50, 0x7E50}, + {0x7E51, 0x7E51}, {0x7E52, 0x7E52}, {0x7E53, 0x7E53}, {0x7E54, 0x7E54}, {0x7E55, 0x7E55}, {0x7E56, 0x7E56}, {0x7E57, 0x7E57}, + {0x7E58, 0x7E58}, {0x7E59, 0x7E59}, {0x7E5A, 0x7E5A}, {0x7E5B, 0x7E5B}, {0x7E5C, 0x7E5C}, {0x7E5D, 0x7E5D}, {0x7E5E, 0x7E5E}, + {0x7E5F, 0x7E5F}, {0x7E60, 0x7E60}, {0x7E61, 0x7E61}, {0x7E62, 0x7E62}, {0x7E63, 0x7E63}, {0x7E64, 0x7E64}, {0x7E65, 0x7E65}, + {0x7E66, 0x7E66}, {0x7E67, 0x7E67}, {0x7E68, 0x7E68}, {0x7E69, 0x7E69}, {0x7E6A, 0x7E6A}, {0x7E6B, 0x7E6B}, {0x7E6C, 0x7E6C}, + {0x7E6D, 0x7E6D}, {0x7E6E, 0x7E6E}, {0x7E6F, 0x7E6F}, {0x7E70, 0x7E70}, {0x7E71, 0x7E71}, {0x7E72, 0x7E72}, {0x7E73, 0x7E73}, + {0x7E74, 0x7E74}, {0x7E75, 0x7E75}, {0x7E76, 0x7E76}, {0x7E77, 0x7E77}, {0x7E78, 0x7E78}, {0x7E79, 0x7E79}, {0x7E7A, 0x7E7A}, + {0x7E7B, 0x7E7B}, {0x7E7C, 0x7E7C}, {0x7E7D, 0x7E7D}, {0x7E7E, 0x7E7E}, {0x7E7F, 0x7E7F}, {0x7E80, 0x7E80}, {0x7E81, 0x7E81}, + {0x7E82, 0x7E82}, {0x7E83, 0x7E83}, {0x7E84, 0x7E84}, {0x7E85, 0x7E85}, {0x7E86, 0x7E86}, {0x7E87, 0x7E87}, {0x7E88, 0x7E88}, + {0x7E89, 0x7E89}, {0x7E8A, 0x7E8A}, {0x7E8B, 0x7E8B}, {0x7E8C, 0x7E8C}, {0x7E8D, 0x7E8D}, {0x7E8E, 0x7E8E}, {0x7E8F, 0x7E8F}, + {0x7E90, 0x7E90}, {0x7E91, 0x7E91}, {0x7E92, 0x7E92}, {0x7E93, 0x7E93}, {0x7E94, 0x7E94}, {0x7E95, 0x7E95}, {0x7E96, 0x7E96}, + {0x7E97, 0x7E97}, {0x7E98, 0x7E98}, {0x7E99, 0x7E99}, {0x7E9A, 0x7E9A}, {0x7E9B, 0x7E9B}, {0x7E9C, 0x7E9C}, {0x7E9D, 0x7E9D}, + {0x7E9E, 0x7E9E}, {0x7E9F, 0x7E9F}, {0x7EA0, 0x7EA0}, {0x7EA1, 0x7EA1}, {0x7EA2, 0x7EA2}, {0x7EA3, 0x7EA3}, {0x7EA4, 0x7EA4}, + {0x7EA5, 0x7EA5}, {0x7EA6, 0x7EA6}, {0x7EA7, 0x7EA7}, {0x7EA8, 0x7EA8}, {0x7EA9, 0x7EA9}, {0x7EAA, 0x7EAA}, {0x7EAB, 0x7EAB}, + {0x7EAC, 0x7EAC}, {0x7EAD, 0x7EAD}, {0x7EAE, 0x7EAE}, {0x7EAF, 0x7EAF}, {0x7EB0, 0x7EB0}, {0x7EB1, 0x7EB1}, {0x7EB2, 0x7EB2}, + {0x7EB3, 0x7EB3}, {0x7EB4, 0x7EB4}, {0x7EB5, 0x7EB5}, {0x7EB6, 0x7EB6}, {0x7EB7, 0x7EB7}, {0x7EB8, 0x7EB8}, {0x7EB9, 0x7EB9}, + {0x7EBA, 0x7EBA}, {0x7EBB, 0x7EBB}, {0x7EBC, 0x7EBC}, {0x7EBD, 0x7EBD}, {0x7EBE, 0x7EBE}, {0x7EBF, 0x7EBF}, {0x7EC0, 0x7EC0}, + {0x7EC1, 0x7EC1}, {0x7EC2, 0x7EC2}, {0x7EC3, 0x7EC3}, {0x7EC4, 0x7EC4}, {0x7EC5, 0x7EC5}, {0x7EC6, 0x7EC6}, {0x7EC7, 0x7EC7}, + {0x7EC8, 0x7EC8}, {0x7EC9, 0x7EC9}, {0x7ECA, 0x7ECA}, {0x7ECB, 0x7ECB}, {0x7ECC, 0x7ECC}, {0x7ECD, 0x7ECD}, {0x7ECE, 0x7ECE}, + {0x7ECF, 0x7ECF}, {0x7ED0, 0x7ED0}, {0x7ED1, 0x7ED1}, {0x7ED2, 0x7ED2}, {0x7ED3, 0x7ED3}, {0x7ED4, 0x7ED4}, {0x7ED5, 0x7ED5}, + {0x7ED6, 0x7ED6}, {0x7ED7, 0x7ED7}, {0x7ED8, 0x7ED8}, {0x7ED9, 0x7ED9}, {0x7EDA, 0x7EDA}, {0x7EDB, 0x7EDB}, {0x7EDC, 0x7EDC}, + {0x7EDD, 0x7EDD}, {0x7EDE, 0x7EDE}, {0x7EDF, 0x7EDF}, {0x7EE0, 0x7EE0}, {0x7EE1, 0x7EE1}, {0x7EE2, 0x7EE2}, {0x7EE3, 0x7EE3}, + {0x7EE4, 0x7EE4}, {0x7EE5, 0x7EE5}, {0x7EE6, 0x7EE6}, {0x7EE7, 0x7EE7}, {0x7EE8, 0x7EE8}, {0x7EE9, 0x7EE9}, {0x7EEA, 0x7EEA}, + {0x7EEB, 0x7EEB}, {0x7EEC, 0x7EEC}, {0x7EED, 0x7EED}, {0x7EEE, 0x7EEE}, {0x7EEF, 0x7EEF}, {0x7EF0, 0x7EF0}, {0x7EF1, 0x7EF1}, + {0x7EF2, 0x7EF2}, {0x7EF3, 0x7EF3}, {0x7EF4, 0x7EF4}, {0x7EF5, 0x7EF5}, {0x7EF6, 0x7EF6}, {0x7EF7, 0x7EF7}, {0x7EF8, 0x7EF8}, + {0x7EF9, 0x7EF9}, {0x7EFA, 0x7EFA}, {0x7EFB, 0x7EFB}, {0x7EFC, 0x7EFC}, {0x7EFD, 0x7EFD}, {0x7EFE, 0x7EFE}, {0x7EFF, 0x7EFF}, + {0x7F00, 0x7F00}, {0x7F01, 0x7F01}, {0x7F02, 0x7F02}, {0x7F03, 0x7F03}, {0x7F04, 0x7F04}, {0x7F05, 0x7F05}, {0x7F06, 0x7F06}, + {0x7F07, 0x7F07}, {0x7F08, 0x7F08}, {0x7F09, 0x7F09}, {0x7F0A, 0x7F0A}, {0x7F0B, 0x7F0B}, {0x7F0C, 0x7F0C}, {0x7F0D, 0x7F0D}, + {0x7F0E, 0x7F0E}, {0x7F0F, 0x7F0F}, {0x7F10, 0x7F10}, {0x7F11, 0x7F11}, {0x7F12, 0x7F12}, {0x7F13, 0x7F13}, {0x7F14, 0x7F14}, + {0x7F15, 0x7F15}, {0x7F16, 0x7F16}, {0x7F17, 0x7F17}, {0x7F18, 0x7F18}, {0x7F19, 0x7F19}, {0x7F1A, 0x7F1A}, {0x7F1B, 0x7F1B}, + {0x7F1C, 0x7F1C}, {0x7F1D, 0x7F1D}, {0x7F1E, 0x7F1E}, {0x7F1F, 0x7F1F}, {0x7F20, 0x7F20}, {0x7F21, 0x7F21}, {0x7F22, 0x7F22}, + {0x7F23, 0x7F23}, {0x7F24, 0x7F24}, {0x7F25, 0x7F25}, {0x7F26, 0x7F26}, {0x7F27, 0x7F27}, {0x7F28, 0x7F28}, {0x7F29, 0x7F29}, + {0x7F2A, 0x7F2A}, {0x7F2B, 0x7F2B}, {0x7F2C, 0x7F2C}, {0x7F2D, 0x7F2D}, {0x7F2E, 0x7F2E}, {0x7F2F, 0x7F2F}, {0x7F30, 0x7F30}, + {0x7F31, 0x7F31}, {0x7F32, 0x7F32}, {0x7F33, 0x7F33}, {0x7F34, 0x7F34}, {0x7F35, 0x7F35}, {0x7F36, 0x7F36}, {0x7F37, 0x7F37}, + {0x7F38, 0x7F38}, {0x7F39, 0x7F39}, {0x7F3A, 0x7F3A}, {0x7F3B, 0x7F3B}, {0x7F3C, 0x7F3C}, {0x7F3D, 0x7F3D}, {0x7F3E, 0x7F3E}, + {0x7F3F, 0x7F3F}, {0x7F40, 0x7F40}, {0x7F41, 0x7F41}, {0x7F42, 0x7F42}, {0x7F43, 0x7F43}, {0x7F44, 0x7F44}, {0x7F45, 0x7F45}, + {0x7F46, 0x7F46}, {0x7F47, 0x7F47}, {0x7F48, 0x7F48}, {0x7F49, 0x7F49}, {0x7F4A, 0x7F4A}, {0x7F4B, 0x7F4B}, {0x7F4C, 0x7F4C}, + {0x7F4D, 0x7F4D}, {0x7F4E, 0x7F4E}, {0x7F4F, 0x7F4F}, {0x7F50, 0x7F50}, {0x7F51, 0x7F51}, {0x7F52, 0x7F52}, {0x7F53, 0x7F53}, + {0x7F54, 0x7F54}, {0x7F55, 0x7F55}, {0x7F56, 0x7F56}, {0x7F57, 0x7F57}, {0x7F58, 0x7F58}, {0x7F59, 0x7F59}, {0x7F5A, 0x7F5A}, + {0x7F5B, 0x7F5B}, {0x7F5C, 0x7F5C}, {0x7F5D, 0x7F5D}, {0x7F5E, 0x7F5E}, {0x7F5F, 0x7F5F}, {0x7F60, 0x7F60}, {0x7F61, 0x7F61}, + {0x7F62, 0x7F62}, {0x7F63, 0x7F63}, {0x7F64, 0x7F64}, {0x7F65, 0x7F65}, {0x7F66, 0x7F66}, {0x7F67, 0x7F67}, {0x7F68, 0x7F68}, + {0x7F69, 0x7F69}, {0x7F6A, 0x7F6A}, {0x7F6B, 0x7F6B}, {0x7F6C, 0x7F6C}, {0x7F6D, 0x7F6D}, {0x7F6E, 0x7F6E}, {0x7F6F, 0x7F6F}, + {0x7F70, 0x7F70}, {0x7F71, 0x7F71}, {0x7F72, 0x7F72}, {0x7F73, 0x7F73}, {0x7F74, 0x7F74}, {0x7F75, 0x7F75}, {0x7F76, 0x7F76}, + {0x7F77, 0x7F77}, {0x7F78, 0x7F78}, {0x7F79, 0x7F79}, {0x7F7A, 0x7F7A}, {0x7F7B, 0x7F7B}, {0x7F7C, 0x7F7C}, {0x7F7D, 0x7F7D}, + {0x7F7E, 0x7F7E}, {0x7F7F, 0x7F7F}, {0x7F80, 0x7F80}, {0x7F81, 0x7F81}, {0x7F82, 0x7F82}, {0x7F83, 0x7F83}, {0x7F84, 0x7F84}, + {0x7F85, 0x7F85}, {0x7F86, 0x7F86}, {0x7F87, 0x7F87}, {0x7F88, 0x7F88}, {0x7F89, 0x7F89}, {0x7F8A, 0x7F8A}, {0x7F8B, 0x7F8B}, + {0x7F8C, 0x7F8C}, {0x7F8D, 0x7F8D}, {0x7F8E, 0x7F8E}, {0x7F8F, 0x7F8F}, {0x7F90, 0x7F90}, {0x7F91, 0x7F91}, {0x7F92, 0x7F92}, + {0x7F93, 0x7F93}, {0x7F94, 0x7F94}, {0x7F95, 0x7F95}, {0x7F96, 0x7F96}, {0x7F97, 0x7F97}, {0x7F98, 0x7F98}, {0x7F99, 0x7F99}, + {0x7F9A, 0x7F9A}, {0x7F9B, 0x7F9B}, {0x7F9C, 0x7F9C}, {0x7F9D, 0x7F9D}, {0x7F9E, 0x7F9E}, {0x7F9F, 0x7F9F}, {0x7FA0, 0x7FA0}, + {0x7FA1, 0x7FA1}, {0x7FA2, 0x7FA2}, {0x7FA3, 0x7FA3}, {0x7FA4, 0x7FA4}, {0x7FA5, 0x7FA5}, {0x7FA6, 0x7FA6}, {0x7FA7, 0x7FA7}, + {0x7FA8, 0x7FA8}, {0x7FA9, 0x7FA9}, {0x7FAA, 0x7FAA}, {0x7FAB, 0x7FAB}, {0x7FAC, 0x7FAC}, {0x7FAD, 0x7FAD}, {0x7FAE, 0x7FAE}, + {0x7FAF, 0x7FAF}, {0x7FB0, 0x7FB0}, {0x7FB1, 0x7FB1}, {0x7FB2, 0x7FB2}, {0x7FB3, 0x7FB3}, {0x7FB4, 0x7FB4}, {0x7FB5, 0x7FB5}, + {0x7FB6, 0x7FB6}, {0x7FB7, 0x7FB7}, {0x7FB8, 0x7FB8}, {0x7FB9, 0x7FB9}, {0x7FBA, 0x7FBA}, {0x7FBB, 0x7FBB}, {0x7FBC, 0x7FBC}, + {0x7FBD, 0x7FBD}, {0x7FBE, 0x7FBE}, {0x7FBF, 0x7FBF}, {0x7FC0, 0x7FC0}, {0x7FC1, 0x7FC1}, {0x7FC2, 0x7FC2}, {0x7FC3, 0x7FC3}, + {0x7FC4, 0x7FC4}, {0x7FC5, 0x7FC5}, {0x7FC6, 0x7FC6}, {0x7FC7, 0x7FC7}, {0x7FC8, 0x7FC8}, {0x7FC9, 0x7FC9}, {0x7FCA, 0x7FCA}, + {0x7FCB, 0x7FCB}, {0x7FCC, 0x7FCC}, {0x7FCD, 0x7FCD}, {0x7FCE, 0x7FCE}, {0x7FCF, 0x7FCF}, {0x7FD0, 0x7FD0}, {0x7FD1, 0x7FD1}, + {0x7FD2, 0x7FD2}, {0x7FD3, 0x7FD3}, {0x7FD4, 0x7FD4}, {0x7FD5, 0x7FD5}, {0x7FD6, 0x7FD6}, {0x7FD7, 0x7FD7}, {0x7FD8, 0x7FD8}, + {0x7FD9, 0x7FD9}, {0x7FDA, 0x7FDA}, {0x7FDB, 0x7FDB}, {0x7FDC, 0x7FDC}, {0x7FDD, 0x7FDD}, {0x7FDE, 0x7FDE}, {0x7FDF, 0x7FDF}, + {0x7FE0, 0x7FE0}, {0x7FE1, 0x7FE1}, {0x7FE2, 0x7FE2}, {0x7FE3, 0x7FE3}, {0x7FE4, 0x7FE4}, {0x7FE5, 0x7FE5}, {0x7FE6, 0x7FE6}, + {0x7FE7, 0x7FE7}, {0x7FE8, 0x7FE8}, {0x7FE9, 0x7FE9}, {0x7FEA, 0x7FEA}, {0x7FEB, 0x7FEB}, {0x7FEC, 0x7FEC}, {0x7FED, 0x7FED}, + {0x7FEE, 0x7FEE}, {0x7FEF, 0x7FEF}, {0x7FF0, 0x7FF0}, {0x7FF1, 0x7FF1}, {0x7FF2, 0x7FF2}, {0x7FF3, 0x7FF3}, {0x7FF4, 0x7FF4}, + {0x7FF5, 0x7FF5}, {0x7FF6, 0x7FF6}, {0x7FF7, 0x7FF7}, {0x7FF8, 0x7FF8}, {0x7FF9, 0x7FF9}, {0x7FFA, 0x7FFA}, {0x7FFB, 0x7FFB}, + {0x7FFC, 0x7FFC}, {0x7FFD, 0x7FFD}, {0x7FFE, 0x7FFE}, {0x7FFF, 0x7FFF}, {0x8000, 0x8000}, {0x8001, 0x8001}, {0x8002, 0x8002}, + {0x8003, 0x8003}, {0x8004, 0x8004}, {0x8005, 0x8005}, {0x8006, 0x8006}, {0x8007, 0x8007}, {0x8008, 0x8008}, {0x8009, 0x8009}, + {0x800A, 0x800A}, {0x800B, 0x800B}, {0x800C, 0x800C}, {0x800D, 0x800D}, {0x800E, 0x800E}, {0x800F, 0x800F}, {0x8010, 0x8010}, + {0x8011, 0x8011}, {0x8012, 0x8012}, {0x8013, 0x8013}, {0x8014, 0x8014}, {0x8015, 0x8015}, {0x8016, 0x8016}, {0x8017, 0x8017}, + {0x8018, 0x8018}, {0x8019, 0x8019}, {0x801A, 0x801A}, {0x801B, 0x801B}, {0x801C, 0x801C}, {0x801D, 0x801D}, {0x801E, 0x801E}, + {0x801F, 0x801F}, {0x8020, 0x8020}, {0x8021, 0x8021}, {0x8022, 0x8022}, {0x8023, 0x8023}, {0x8024, 0x8024}, {0x8025, 0x8025}, + {0x8026, 0x8026}, {0x8027, 0x8027}, {0x8028, 0x8028}, {0x8029, 0x8029}, {0x802A, 0x802A}, {0x802B, 0x802B}, {0x802C, 0x802C}, + {0x802D, 0x802D}, {0x802E, 0x802E}, {0x802F, 0x802F}, {0x8030, 0x8030}, {0x8031, 0x8031}, {0x8032, 0x8032}, {0x8033, 0x8033}, + {0x8034, 0x8034}, {0x8035, 0x8035}, {0x8036, 0x8036}, {0x8037, 0x8037}, {0x8038, 0x8038}, {0x8039, 0x8039}, {0x803A, 0x803A}, + {0x803B, 0x803B}, {0x803C, 0x803C}, {0x803D, 0x803D}, {0x803E, 0x803E}, {0x803F, 0x803F}, {0x8040, 0x8040}, {0x8041, 0x8041}, + {0x8042, 0x8042}, {0x8043, 0x8043}, {0x8044, 0x8044}, {0x8045, 0x8045}, {0x8046, 0x8046}, {0x8047, 0x8047}, {0x8048, 0x8048}, + {0x8049, 0x8049}, {0x804A, 0x804A}, {0x804B, 0x804B}, {0x804C, 0x804C}, {0x804D, 0x804D}, {0x804E, 0x804E}, {0x804F, 0x804F}, + {0x8050, 0x8050}, {0x8051, 0x8051}, {0x8052, 0x8052}, {0x8053, 0x8053}, {0x8054, 0x8054}, {0x8055, 0x8055}, {0x8056, 0x8056}, + {0x8057, 0x8057}, {0x8058, 0x8058}, {0x8059, 0x8059}, {0x805A, 0x805A}, {0x805B, 0x805B}, {0x805C, 0x805C}, {0x805D, 0x805D}, + {0x805E, 0x805E}, {0x805F, 0x805F}, {0x8060, 0x8060}, {0x8061, 0x8061}, {0x8062, 0x8062}, {0x8063, 0x8063}, {0x8064, 0x8064}, + {0x8065, 0x8065}, {0x8066, 0x8066}, {0x8067, 0x8067}, {0x8068, 0x8068}, {0x8069, 0x8069}, {0x806A, 0x806A}, {0x806B, 0x806B}, + {0x806C, 0x806C}, {0x806D, 0x806D}, {0x806E, 0x806E}, {0x806F, 0x806F}, {0x8070, 0x8070}, {0x8071, 0x8071}, {0x8072, 0x8072}, + {0x8073, 0x8073}, {0x8074, 0x8074}, {0x8075, 0x8075}, {0x8076, 0x8076}, {0x8077, 0x8077}, {0x8078, 0x8078}, {0x8079, 0x8079}, + {0x807A, 0x807A}, {0x807B, 0x807B}, {0x807C, 0x807C}, {0x807D, 0x807D}, {0x807E, 0x807E}, {0x807F, 0x807F}, {0x8080, 0x8080}, + {0x8081, 0x8081}, {0x8082, 0x8082}, {0x8083, 0x8083}, {0x8084, 0x8084}, {0x8085, 0x8085}, {0x8086, 0x8086}, {0x8087, 0x8087}, + {0x8088, 0x8088}, {0x8089, 0x8089}, {0x808A, 0x808A}, {0x808B, 0x808B}, {0x808C, 0x808C}, {0x808D, 0x808D}, {0x808E, 0x808E}, + {0x808F, 0x808F}, {0x8090, 0x8090}, {0x8091, 0x8091}, {0x8092, 0x8092}, {0x8093, 0x8093}, {0x8094, 0x8094}, {0x8095, 0x8095}, + {0x8096, 0x8096}, {0x8097, 0x8097}, {0x8098, 0x8098}, {0x8099, 0x8099}, {0x809A, 0x809A}, {0x809B, 0x809B}, {0x809C, 0x809C}, + {0x809D, 0x809D}, {0x809E, 0x809E}, {0x809F, 0x809F}, {0x80A0, 0x80A0}, {0x80A1, 0x80A1}, {0x80A2, 0x80A2}, {0x80A3, 0x80A3}, + {0x80A4, 0x80A4}, {0x80A5, 0x80A5}, {0x80A6, 0x80A6}, {0x80A7, 0x80A7}, {0x80A8, 0x80A8}, {0x80A9, 0x80A9}, {0x80AA, 0x80AA}, + {0x80AB, 0x80AB}, {0x80AC, 0x80AC}, {0x80AD, 0x80AD}, {0x80AE, 0x80AE}, {0x80AF, 0x80AF}, {0x80B0, 0x80B0}, {0x80B1, 0x80B1}, + {0x80B2, 0x80B2}, {0x80B3, 0x80B3}, {0x80B4, 0x80B4}, {0x80B5, 0x80B5}, {0x80B6, 0x80B6}, {0x80B7, 0x80B7}, {0x80B8, 0x80B8}, + {0x80B9, 0x80B9}, {0x80BA, 0x80BA}, {0x80BB, 0x80BB}, {0x80BC, 0x80BC}, {0x80BD, 0x80BD}, {0x80BE, 0x80BE}, {0x80BF, 0x80BF}, + {0x80C0, 0x80C0}, {0x80C1, 0x80C1}, {0x80C2, 0x80C2}, {0x80C3, 0x80C3}, {0x80C4, 0x80C4}, {0x80C5, 0x80C5}, {0x80C6, 0x80C6}, + {0x80C7, 0x80C7}, {0x80C8, 0x80C8}, {0x80C9, 0x80C9}, {0x80CA, 0x80CA}, {0x80CB, 0x80CB}, {0x80CC, 0x80CC}, {0x80CD, 0x80CD}, + {0x80CE, 0x80CE}, {0x80CF, 0x80CF}, {0x80D0, 0x80D0}, {0x80D1, 0x80D1}, {0x80D2, 0x80D2}, {0x80D3, 0x80D3}, {0x80D4, 0x80D4}, + {0x80D5, 0x80D5}, {0x80D6, 0x80D6}, {0x80D7, 0x80D7}, {0x80D8, 0x80D8}, {0x80D9, 0x80D9}, {0x80DA, 0x80DA}, {0x80DB, 0x80DB}, + {0x80DC, 0x80DC}, {0x80DD, 0x80DD}, {0x80DE, 0x80DE}, {0x80DF, 0x80DF}, {0x80E0, 0x80E0}, {0x80E1, 0x80E1}, {0x80E2, 0x80E2}, + {0x80E3, 0x80E3}, {0x80E4, 0x80E4}, {0x80E5, 0x80E5}, {0x80E6, 0x80E6}, {0x80E7, 0x80E7}, {0x80E8, 0x80E8}, {0x80E9, 0x80E9}, + {0x80EA, 0x80EA}, {0x80EB, 0x80EB}, {0x80EC, 0x80EC}, {0x80ED, 0x80ED}, {0x80EE, 0x80EE}, {0x80EF, 0x80EF}, {0x80F0, 0x80F0}, + {0x80F1, 0x80F1}, {0x80F2, 0x80F2}, {0x80F3, 0x80F3}, {0x80F4, 0x80F4}, {0x80F5, 0x80F5}, {0x80F6, 0x80F6}, {0x80F7, 0x80F7}, + {0x80F8, 0x80F8}, {0x80F9, 0x80F9}, {0x80FA, 0x80FA}, {0x80FB, 0x80FB}, {0x80FC, 0x80FC}, {0x80FD, 0x80FD}, {0x80FE, 0x80FE}, + {0x80FF, 0x80FF}, {0x8100, 0x8100}, {0x8101, 0x8101}, {0x8102, 0x8102}, {0x8103, 0x8103}, {0x8104, 0x8104}, {0x8105, 0x8105}, + {0x8106, 0x8106}, {0x8107, 0x8107}, {0x8108, 0x8108}, {0x8109, 0x8109}, {0x810A, 0x810A}, {0x810B, 0x810B}, {0x810C, 0x810C}, + {0x810D, 0x810D}, {0x810E, 0x810E}, {0x810F, 0x810F}, {0x8110, 0x8110}, {0x8111, 0x8111}, {0x8112, 0x8112}, {0x8113, 0x8113}, + {0x8114, 0x8114}, {0x8115, 0x8115}, {0x8116, 0x8116}, {0x8117, 0x8117}, {0x8118, 0x8118}, {0x8119, 0x8119}, {0x811A, 0x811A}, + {0x811B, 0x811B}, {0x811C, 0x811C}, {0x811D, 0x811D}, {0x811E, 0x811E}, {0x811F, 0x811F}, {0x8120, 0x8120}, {0x8121, 0x8121}, + {0x8122, 0x8122}, {0x8123, 0x8123}, {0x8124, 0x8124}, {0x8125, 0x8125}, {0x8126, 0x8126}, {0x8127, 0x8127}, {0x8128, 0x8128}, + {0x8129, 0x8129}, {0x812A, 0x812A}, {0x812B, 0x812B}, {0x812C, 0x812C}, {0x812D, 0x812D}, {0x812E, 0x812E}, {0x812F, 0x812F}, + {0x8130, 0x8130}, {0x8131, 0x8131}, {0x8132, 0x8132}, {0x8133, 0x8133}, {0x8134, 0x8134}, {0x8135, 0x8135}, {0x8136, 0x8136}, + {0x8137, 0x8137}, {0x8138, 0x8138}, {0x8139, 0x8139}, {0x813A, 0x813A}, {0x813B, 0x813B}, {0x813C, 0x813C}, {0x813D, 0x813D}, + {0x813E, 0x813E}, {0x813F, 0x813F}, {0x8140, 0x8140}, {0x8141, 0x8141}, {0x8142, 0x8142}, {0x8143, 0x8143}, {0x8144, 0x8144}, + {0x8145, 0x8145}, {0x8146, 0x8146}, {0x8147, 0x8147}, {0x8148, 0x8148}, {0x8149, 0x8149}, {0x814A, 0x814A}, {0x814B, 0x814B}, + {0x814C, 0x814C}, {0x814D, 0x814D}, {0x814E, 0x814E}, {0x814F, 0x814F}, {0x8150, 0x8150}, {0x8151, 0x8151}, {0x8152, 0x8152}, + {0x8153, 0x8153}, {0x8154, 0x8154}, {0x8155, 0x8155}, {0x8156, 0x8156}, {0x8157, 0x8157}, {0x8158, 0x8158}, {0x8159, 0x8159}, + {0x815A, 0x815A}, {0x815B, 0x815B}, {0x815C, 0x815C}, {0x815D, 0x815D}, {0x815E, 0x815E}, {0x815F, 0x815F}, {0x8160, 0x8160}, + {0x8161, 0x8161}, {0x8162, 0x8162}, {0x8163, 0x8163}, {0x8164, 0x8164}, {0x8165, 0x8165}, {0x8166, 0x8166}, {0x8167, 0x8167}, + {0x8168, 0x8168}, {0x8169, 0x8169}, {0x816A, 0x816A}, {0x816B, 0x816B}, {0x816C, 0x816C}, {0x816D, 0x816D}, {0x816E, 0x816E}, + {0x816F, 0x816F}, {0x8170, 0x8170}, {0x8171, 0x8171}, {0x8172, 0x8172}, {0x8173, 0x8173}, {0x8174, 0x8174}, {0x8175, 0x8175}, + {0x8176, 0x8176}, {0x8177, 0x8177}, {0x8178, 0x8178}, {0x8179, 0x8179}, {0x817A, 0x817A}, {0x817B, 0x817B}, {0x817C, 0x817C}, + {0x817D, 0x817D}, {0x817E, 0x817E}, {0x817F, 0x817F}, {0x8180, 0x8180}, {0x8181, 0x8181}, {0x8182, 0x8182}, {0x8183, 0x8183}, + {0x8184, 0x8184}, {0x8185, 0x8185}, {0x8186, 0x8186}, {0x8187, 0x8187}, {0x8188, 0x8188}, {0x8189, 0x8189}, {0x818A, 0x818A}, + {0x818B, 0x818B}, {0x818C, 0x818C}, {0x818D, 0x818D}, {0x818E, 0x818E}, {0x818F, 0x818F}, {0x8190, 0x8190}, {0x8191, 0x8191}, + {0x8192, 0x8192}, {0x8193, 0x8193}, {0x8194, 0x8194}, {0x8195, 0x8195}, {0x8196, 0x8196}, {0x8197, 0x8197}, {0x8198, 0x8198}, + {0x8199, 0x8199}, {0x819A, 0x819A}, {0x819B, 0x819B}, {0x819C, 0x819C}, {0x819D, 0x819D}, {0x819E, 0x819E}, {0x819F, 0x819F}, + {0x81A0, 0x81A0}, {0x81A1, 0x81A1}, {0x81A2, 0x81A2}, {0x81A3, 0x81A3}, {0x81A4, 0x81A4}, {0x81A5, 0x81A5}, {0x81A6, 0x81A6}, + {0x81A7, 0x81A7}, {0x81A8, 0x81A8}, {0x81A9, 0x81A9}, {0x81AA, 0x81AA}, {0x81AB, 0x81AB}, {0x81AC, 0x81AC}, {0x81AD, 0x81AD}, + {0x81AE, 0x81AE}, {0x81AF, 0x81AF}, {0x81B0, 0x81B0}, {0x81B1, 0x81B1}, {0x81B2, 0x81B2}, {0x81B3, 0x81B3}, {0x81B4, 0x81B4}, + {0x81B5, 0x81B5}, {0x81B6, 0x81B6}, {0x81B7, 0x81B7}, {0x81B8, 0x81B8}, {0x81B9, 0x81B9}, {0x81BA, 0x81BA}, {0x81BB, 0x81BB}, + {0x81BC, 0x81BC}, {0x81BD, 0x81BD}, {0x81BE, 0x81BE}, {0x81BF, 0x81BF}, {0x81C0, 0x81C0}, {0x81C1, 0x81C1}, {0x81C2, 0x81C2}, + {0x81C3, 0x81C3}, {0x81C4, 0x81C4}, {0x81C5, 0x81C5}, {0x81C6, 0x81C6}, {0x81C7, 0x81C7}, {0x81C8, 0x81C8}, {0x81C9, 0x81C9}, + {0x81CA, 0x81CA}, {0x81CB, 0x81CB}, {0x81CC, 0x81CC}, {0x81CD, 0x81CD}, {0x81CE, 0x81CE}, {0x81CF, 0x81CF}, {0x81D0, 0x81D0}, + {0x81D1, 0x81D1}, {0x81D2, 0x81D2}, {0x81D3, 0x81D3}, {0x81D4, 0x81D4}, {0x81D5, 0x81D5}, {0x81D6, 0x81D6}, {0x81D7, 0x81D7}, + {0x81D8, 0x81D8}, {0x81D9, 0x81D9}, {0x81DA, 0x81DA}, {0x81DB, 0x81DB}, {0x81DC, 0x81DC}, {0x81DD, 0x81DD}, {0x81DE, 0x81DE}, + {0x81DF, 0x81DF}, {0x81E0, 0x81E0}, {0x81E1, 0x81E1}, {0x81E2, 0x81E2}, {0x81E3, 0x81E3}, {0x81E4, 0x81E4}, {0x81E5, 0x81E5}, + {0x81E6, 0x81E6}, {0x81E7, 0x81E7}, {0x81E8, 0x81E8}, {0x81E9, 0x81E9}, {0x81EA, 0x81EA}, {0x81EB, 0x81EB}, {0x81EC, 0x81EC}, + {0x81ED, 0x81ED}, {0x81EE, 0x81EE}, {0x81EF, 0x81EF}, {0x81F0, 0x81F0}, {0x81F1, 0x81F1}, {0x81F2, 0x81F2}, {0x81F3, 0x81F3}, + {0x81F4, 0x81F4}, {0x81F5, 0x81F5}, {0x81F6, 0x81F6}, {0x81F7, 0x81F7}, {0x81F8, 0x81F8}, {0x81F9, 0x81F9}, {0x81FA, 0x81FA}, + {0x81FB, 0x81FB}, {0x81FC, 0x81FC}, {0x81FD, 0x81FD}, {0x81FE, 0x81FE}, {0x81FF, 0x81FF}, {0x8200, 0x8200}, {0x8201, 0x8201}, + {0x8202, 0x8202}, {0x8203, 0x8203}, {0x8204, 0x8204}, {0x8205, 0x8205}, {0x8206, 0x8206}, {0x8207, 0x8207}, {0x8208, 0x8208}, + {0x8209, 0x8209}, {0x820A, 0x820A}, {0x820B, 0x820B}, {0x820C, 0x820C}, {0x820D, 0x820D}, {0x820E, 0x820E}, {0x820F, 0x820F}, + {0x8210, 0x8210}, {0x8211, 0x8211}, {0x8212, 0x8212}, {0x8213, 0x8213}, {0x8214, 0x8214}, {0x8215, 0x8215}, {0x8216, 0x8216}, + {0x8217, 0x8217}, {0x8218, 0x8218}, {0x8219, 0x8219}, {0x821A, 0x821A}, {0x821B, 0x821B}, {0x821C, 0x821C}, {0x821D, 0x821D}, + {0x821E, 0x821E}, {0x821F, 0x821F}, {0x8220, 0x8220}, {0x8221, 0x8221}, {0x8222, 0x8222}, {0x8223, 0x8223}, {0x8224, 0x8224}, + {0x8225, 0x8225}, {0x8226, 0x8226}, {0x8227, 0x8227}, {0x8228, 0x8228}, {0x8229, 0x8229}, {0x822A, 0x822A}, {0x822B, 0x822B}, + {0x822C, 0x822C}, {0x822D, 0x822D}, {0x822E, 0x822E}, {0x822F, 0x822F}, {0x8230, 0x8230}, {0x8231, 0x8231}, {0x8232, 0x8232}, + {0x8233, 0x8233}, {0x8234, 0x8234}, {0x8235, 0x8235}, {0x8236, 0x8236}, {0x8237, 0x8237}, {0x8238, 0x8238}, {0x8239, 0x8239}, + {0x823A, 0x823A}, {0x823B, 0x823B}, {0x823C, 0x823C}, {0x823D, 0x823D}, {0x823E, 0x823E}, {0x823F, 0x823F}, {0x8240, 0x8240}, + {0x8241, 0x8241}, {0x8242, 0x8242}, {0x8243, 0x8243}, {0x8244, 0x8244}, {0x8245, 0x8245}, {0x8246, 0x8246}, {0x8247, 0x8247}, + {0x8248, 0x8248}, {0x8249, 0x8249}, {0x824A, 0x824A}, {0x824B, 0x824B}, {0x824C, 0x824C}, {0x824D, 0x824D}, {0x824E, 0x824E}, + {0x824F, 0x824F}, {0x8250, 0x8250}, {0x8251, 0x8251}, {0x8252, 0x8252}, {0x8253, 0x8253}, {0x8254, 0x8254}, {0x8255, 0x8255}, + {0x8256, 0x8256}, {0x8257, 0x8257}, {0x8258, 0x8258}, {0x8259, 0x8259}, {0x825A, 0x825A}, {0x825B, 0x825B}, {0x825C, 0x825C}, + {0x825D, 0x825D}, {0x825E, 0x825E}, {0x825F, 0x825F}, {0x8260, 0x8260}, {0x8261, 0x8261}, {0x8262, 0x8262}, {0x8263, 0x8263}, + {0x8264, 0x8264}, {0x8265, 0x8265}, {0x8266, 0x8266}, {0x8267, 0x8267}, {0x8268, 0x8268}, {0x8269, 0x8269}, {0x826A, 0x826A}, + {0x826B, 0x826B}, {0x826C, 0x826C}, {0x826D, 0x826D}, {0x826E, 0x826E}, {0x826F, 0x826F}, {0x8270, 0x8270}, {0x8271, 0x8271}, + {0x8272, 0x8272}, {0x8273, 0x8273}, {0x8274, 0x8274}, {0x8275, 0x8275}, {0x8276, 0x8276}, {0x8277, 0x8277}, {0x8278, 0x8278}, + {0x8279, 0x8279}, {0x827A, 0x827A}, {0x827B, 0x827B}, {0x827C, 0x827C}, {0x827D, 0x827D}, {0x827E, 0x827E}, {0x827F, 0x827F}, + {0x8280, 0x8280}, {0x8281, 0x8281}, {0x8282, 0x8282}, {0x8283, 0x8283}, {0x8284, 0x8284}, {0x8285, 0x8285}, {0x8286, 0x8286}, + {0x8287, 0x8287}, {0x8288, 0x8288}, {0x8289, 0x8289}, {0x828A, 0x828A}, {0x828B, 0x828B}, {0x828C, 0x828C}, {0x828D, 0x828D}, + {0x828E, 0x828E}, {0x828F, 0x828F}, {0x8290, 0x8290}, {0x8291, 0x8291}, {0x8292, 0x8292}, {0x8293, 0x8293}, {0x8294, 0x8294}, + {0x8295, 0x8295}, {0x8296, 0x8296}, {0x8297, 0x8297}, {0x8298, 0x8298}, {0x8299, 0x8299}, {0x829A, 0x829A}, {0x829B, 0x829B}, + {0x829C, 0x829C}, {0x829D, 0x829D}, {0x829E, 0x829E}, {0x829F, 0x829F}, {0x82A0, 0x82A0}, {0x82A1, 0x82A1}, {0x82A2, 0x82A2}, + {0x82A3, 0x82A3}, {0x82A4, 0x82A4}, {0x82A5, 0x82A5}, {0x82A6, 0x82A6}, {0x82A7, 0x82A7}, {0x82A8, 0x82A8}, {0x82A9, 0x82A9}, + {0x82AA, 0x82AA}, {0x82AB, 0x82AB}, {0x82AC, 0x82AC}, {0x82AD, 0x82AD}, {0x82AE, 0x82AE}, {0x82AF, 0x82AF}, {0x82B0, 0x82B0}, + {0x82B1, 0x82B1}, {0x82B2, 0x82B2}, {0x82B3, 0x82B3}, {0x82B4, 0x82B4}, {0x82B5, 0x82B5}, {0x82B6, 0x82B6}, {0x82B7, 0x82B7}, + {0x82B8, 0x82B8}, {0x82B9, 0x82B9}, {0x82BA, 0x82BA}, {0x82BB, 0x82BB}, {0x82BC, 0x82BC}, {0x82BD, 0x82BD}, {0x82BE, 0x82BE}, + {0x82BF, 0x82BF}, {0x82C0, 0x82C0}, {0x82C1, 0x82C1}, {0x82C2, 0x82C2}, {0x82C3, 0x82C3}, {0x82C4, 0x82C4}, {0x82C5, 0x82C5}, + {0x82C6, 0x82C6}, {0x82C7, 0x82C7}, {0x82C8, 0x82C8}, {0x82C9, 0x82C9}, {0x82CA, 0x82CA}, {0x82CB, 0x82CB}, {0x82CC, 0x82CC}, + {0x82CD, 0x82CD}, {0x82CE, 0x82CE}, {0x82CF, 0x82CF}, {0x82D0, 0x82D0}, {0x82D1, 0x82D1}, {0x82D2, 0x82D2}, {0x82D3, 0x82D3}, + {0x82D4, 0x82D4}, {0x82D5, 0x82D5}, {0x82D6, 0x82D6}, {0x82D7, 0x82D7}, {0x82D8, 0x82D8}, {0x82D9, 0x82D9}, {0x82DA, 0x82DA}, + {0x82DB, 0x82DB}, {0x82DC, 0x82DC}, {0x82DD, 0x82DD}, {0x82DE, 0x82DE}, {0x82DF, 0x82DF}, {0x82E0, 0x82E0}, {0x82E1, 0x82E1}, + {0x82E2, 0x82E2}, {0x82E3, 0x82E3}, {0x82E4, 0x82E4}, {0x82E5, 0x82E5}, {0x82E6, 0x82E6}, {0x82E7, 0x82E7}, {0x82E8, 0x82E8}, + {0x82E9, 0x82E9}, {0x82EA, 0x82EA}, {0x82EB, 0x82EB}, {0x82EC, 0x82EC}, {0x82ED, 0x82ED}, {0x82EE, 0x82EE}, {0x82EF, 0x82EF}, + {0x82F0, 0x82F0}, {0x82F1, 0x82F1}, {0x82F2, 0x82F2}, {0x82F3, 0x82F3}, {0x82F4, 0x82F4}, {0x82F5, 0x82F5}, {0x82F6, 0x82F6}, + {0x82F7, 0x82F7}, {0x82F8, 0x82F8}, {0x82F9, 0x82F9}, {0x82FA, 0x82FA}, {0x82FB, 0x82FB}, {0x82FC, 0x82FC}, {0x82FD, 0x82FD}, + {0x82FE, 0x82FE}, {0x82FF, 0x82FF}, {0x8300, 0x8300}, {0x8301, 0x8301}, {0x8302, 0x8302}, {0x8303, 0x8303}, {0x8304, 0x8304}, + {0x8305, 0x8305}, {0x8306, 0x8306}, {0x8307, 0x8307}, {0x8308, 0x8308}, {0x8309, 0x8309}, {0x830A, 0x830A}, {0x830B, 0x830B}, + {0x830C, 0x830C}, {0x830D, 0x830D}, {0x830E, 0x830E}, {0x830F, 0x830F}, {0x8310, 0x8310}, {0x8311, 0x8311}, {0x8312, 0x8312}, + {0x8313, 0x8313}, {0x8314, 0x8314}, {0x8315, 0x8315}, {0x8316, 0x8316}, {0x8317, 0x8317}, {0x8318, 0x8318}, {0x8319, 0x8319}, + {0x831A, 0x831A}, {0x831B, 0x831B}, {0x831C, 0x831C}, {0x831D, 0x831D}, {0x831E, 0x831E}, {0x831F, 0x831F}, {0x8320, 0x8320}, + {0x8321, 0x8321}, {0x8322, 0x8322}, {0x8323, 0x8323}, {0x8324, 0x8324}, {0x8325, 0x8325}, {0x8326, 0x8326}, {0x8327, 0x8327}, + {0x8328, 0x8328}, {0x8329, 0x8329}, {0x832A, 0x832A}, {0x832B, 0x832B}, {0x832C, 0x832C}, {0x832D, 0x832D}, {0x832E, 0x832E}, + {0x832F, 0x832F}, {0x8330, 0x8330}, {0x8331, 0x8331}, {0x8332, 0x8332}, {0x8333, 0x8333}, {0x8334, 0x8334}, {0x8335, 0x8335}, + {0x8336, 0x8336}, {0x8337, 0x8337}, {0x8338, 0x8338}, {0x8339, 0x8339}, {0x833A, 0x833A}, {0x833B, 0x833B}, {0x833C, 0x833C}, + {0x833D, 0x833D}, {0x833E, 0x833E}, {0x833F, 0x833F}, {0x8340, 0x8340}, {0x8341, 0x8341}, {0x8342, 0x8342}, {0x8343, 0x8343}, + {0x8344, 0x8344}, {0x8345, 0x8345}, {0x8346, 0x8346}, {0x8347, 0x8347}, {0x8348, 0x8348}, {0x8349, 0x8349}, {0x834A, 0x834A}, + {0x834B, 0x834B}, {0x834C, 0x834C}, {0x834D, 0x834D}, {0x834E, 0x834E}, {0x834F, 0x834F}, {0x8350, 0x8350}, {0x8351, 0x8351}, + {0x8352, 0x8352}, {0x8353, 0x8353}, {0x8354, 0x8354}, {0x8355, 0x8355}, {0x8356, 0x8356}, {0x8357, 0x8357}, {0x8358, 0x8358}, + {0x8359, 0x8359}, {0x835A, 0x835A}, {0x835B, 0x835B}, {0x835C, 0x835C}, {0x835D, 0x835D}, {0x835E, 0x835E}, {0x835F, 0x835F}, + {0x8360, 0x8360}, {0x8361, 0x8361}, {0x8362, 0x8362}, {0x8363, 0x8363}, {0x8364, 0x8364}, {0x8365, 0x8365}, {0x8366, 0x8366}, + {0x8367, 0x8367}, {0x8368, 0x8368}, {0x8369, 0x8369}, {0x836A, 0x836A}, {0x836B, 0x836B}, {0x836C, 0x836C}, {0x836D, 0x836D}, + {0x836E, 0x836E}, {0x836F, 0x836F}, {0x8370, 0x8370}, {0x8371, 0x8371}, {0x8372, 0x8372}, {0x8373, 0x8373}, {0x8374, 0x8374}, + {0x8375, 0x8375}, {0x8376, 0x8376}, {0x8377, 0x8377}, {0x8378, 0x8378}, {0x8379, 0x8379}, {0x837A, 0x837A}, {0x837B, 0x837B}, + {0x837C, 0x837C}, {0x837D, 0x837D}, {0x837E, 0x837E}, {0x837F, 0x837F}, {0x8380, 0x8380}, {0x8381, 0x8381}, {0x8382, 0x8382}, + {0x8383, 0x8383}, {0x8384, 0x8384}, {0x8385, 0x8385}, {0x8386, 0x8386}, {0x8387, 0x8387}, {0x8388, 0x8388}, {0x8389, 0x8389}, + {0x838A, 0x838A}, {0x838B, 0x838B}, {0x838C, 0x838C}, {0x838D, 0x838D}, {0x838E, 0x838E}, {0x838F, 0x838F}, {0x8390, 0x8390}, + {0x8391, 0x8391}, {0x8392, 0x8392}, {0x8393, 0x8393}, {0x8394, 0x8394}, {0x8395, 0x8395}, {0x8396, 0x8396}, {0x8397, 0x8397}, + {0x8398, 0x8398}, {0x8399, 0x8399}, {0x839A, 0x839A}, {0x839B, 0x839B}, {0x839C, 0x839C}, {0x839D, 0x839D}, {0x839E, 0x839E}, + {0x839F, 0x839F}, {0x83A0, 0x83A0}, {0x83A1, 0x83A1}, {0x83A2, 0x83A2}, {0x83A3, 0x83A3}, {0x83A4, 0x83A4}, {0x83A5, 0x83A5}, + {0x83A6, 0x83A6}, {0x83A7, 0x83A7}, {0x83A8, 0x83A8}, {0x83A9, 0x83A9}, {0x83AA, 0x83AA}, {0x83AB, 0x83AB}, {0x83AC, 0x83AC}, + {0x83AD, 0x83AD}, {0x83AE, 0x83AE}, {0x83AF, 0x83AF}, {0x83B0, 0x83B0}, {0x83B1, 0x83B1}, {0x83B2, 0x83B2}, {0x83B3, 0x83B3}, + {0x83B4, 0x83B4}, {0x83B5, 0x83B5}, {0x83B6, 0x83B6}, {0x83B7, 0x83B7}, {0x83B8, 0x83B8}, {0x83B9, 0x83B9}, {0x83BA, 0x83BA}, + {0x83BB, 0x83BB}, {0x83BC, 0x83BC}, {0x83BD, 0x83BD}, {0x83BE, 0x83BE}, {0x83BF, 0x83BF}, {0x83C0, 0x83C0}, {0x83C1, 0x83C1}, + {0x83C2, 0x83C2}, {0x83C3, 0x83C3}, {0x83C4, 0x83C4}, {0x83C5, 0x83C5}, {0x83C6, 0x83C6}, {0x83C7, 0x83C7}, {0x83C8, 0x83C8}, + {0x83C9, 0x83C9}, {0x83CA, 0x83CA}, {0x83CB, 0x83CB}, {0x83CC, 0x83CC}, {0x83CD, 0x83CD}, {0x83CE, 0x83CE}, {0x83CF, 0x83CF}, + {0x83D0, 0x83D0}, {0x83D1, 0x83D1}, {0x83D2, 0x83D2}, {0x83D3, 0x83D3}, {0x83D4, 0x83D4}, {0x83D5, 0x83D5}, {0x83D6, 0x83D6}, + {0x83D7, 0x83D7}, {0x83D8, 0x83D8}, {0x83D9, 0x83D9}, {0x83DA, 0x83DA}, {0x83DB, 0x83DB}, {0x83DC, 0x83DC}, {0x83DD, 0x83DD}, + {0x83DE, 0x83DE}, {0x83DF, 0x83DF}, {0x83E0, 0x83E0}, {0x83E1, 0x83E1}, {0x83E2, 0x83E2}, {0x83E3, 0x83E3}, {0x83E4, 0x83E4}, + {0x83E5, 0x83E5}, {0x83E6, 0x83E6}, {0x83E7, 0x83E7}, {0x83E8, 0x83E8}, {0x83E9, 0x83E9}, {0x83EA, 0x83EA}, {0x83EB, 0x83EB}, + {0x83EC, 0x83EC}, {0x83ED, 0x83ED}, {0x83EE, 0x83EE}, {0x83EF, 0x83EF}, {0x83F0, 0x83F0}, {0x83F1, 0x83F1}, {0x83F2, 0x83F2}, + {0x83F3, 0x83F3}, {0x83F4, 0x83F4}, {0x83F5, 0x83F5}, {0x83F6, 0x83F6}, {0x83F7, 0x83F7}, {0x83F8, 0x83F8}, {0x83F9, 0x83F9}, + {0x83FA, 0x83FA}, {0x83FB, 0x83FB}, {0x83FC, 0x83FC}, {0x83FD, 0x83FD}, {0x83FE, 0x83FE}, {0x83FF, 0x83FF}, {0x8400, 0x8400}, + {0x8401, 0x8401}, {0x8402, 0x8402}, {0x8403, 0x8403}, {0x8404, 0x8404}, {0x8405, 0x8405}, {0x8406, 0x8406}, {0x8407, 0x8407}, + {0x8408, 0x8408}, {0x8409, 0x8409}, {0x840A, 0x840A}, {0x840B, 0x840B}, {0x840C, 0x840C}, {0x840D, 0x840D}, {0x840E, 0x840E}, + {0x840F, 0x840F}, {0x8410, 0x8410}, {0x8411, 0x8411}, {0x8412, 0x8412}, {0x8413, 0x8413}, {0x8414, 0x8414}, {0x8415, 0x8415}, + {0x8416, 0x8416}, {0x8417, 0x8417}, {0x8418, 0x8418}, {0x8419, 0x8419}, {0x841A, 0x841A}, {0x841B, 0x841B}, {0x841C, 0x841C}, + {0x841D, 0x841D}, {0x841E, 0x841E}, {0x841F, 0x841F}, {0x8420, 0x8420}, {0x8421, 0x8421}, {0x8422, 0x8422}, {0x8423, 0x8423}, + {0x8424, 0x8424}, {0x8425, 0x8425}, {0x8426, 0x8426}, {0x8427, 0x8427}, {0x8428, 0x8428}, {0x8429, 0x8429}, {0x842A, 0x842A}, + {0x842B, 0x842B}, {0x842C, 0x842C}, {0x842D, 0x842D}, {0x842E, 0x842E}, {0x842F, 0x842F}, {0x8430, 0x8430}, {0x8431, 0x8431}, + {0x8432, 0x8432}, {0x8433, 0x8433}, {0x8434, 0x8434}, {0x8435, 0x8435}, {0x8436, 0x8436}, {0x8437, 0x8437}, {0x8438, 0x8438}, + {0x8439, 0x8439}, {0x843A, 0x843A}, {0x843B, 0x843B}, {0x843C, 0x843C}, {0x843D, 0x843D}, {0x843E, 0x843E}, {0x843F, 0x843F}, + {0x8440, 0x8440}, {0x8441, 0x8441}, {0x8442, 0x8442}, {0x8443, 0x8443}, {0x8444, 0x8444}, {0x8445, 0x8445}, {0x8446, 0x8446}, + {0x8447, 0x8447}, {0x8448, 0x8448}, {0x8449, 0x8449}, {0x844A, 0x844A}, {0x844B, 0x844B}, {0x844C, 0x844C}, {0x844D, 0x844D}, + {0x844E, 0x844E}, {0x844F, 0x844F}, {0x8450, 0x8450}, {0x8451, 0x8451}, {0x8452, 0x8452}, {0x8453, 0x8453}, {0x8454, 0x8454}, + {0x8455, 0x8455}, {0x8456, 0x8456}, {0x8457, 0x8457}, {0x8458, 0x8458}, {0x8459, 0x8459}, {0x845A, 0x845A}, {0x845B, 0x845B}, + {0x845C, 0x845C}, {0x845D, 0x845D}, {0x845E, 0x845E}, {0x845F, 0x845F}, {0x8460, 0x8460}, {0x8461, 0x8461}, {0x8462, 0x8462}, + {0x8463, 0x8463}, {0x8464, 0x8464}, {0x8465, 0x8465}, {0x8466, 0x8466}, {0x8467, 0x8467}, {0x8468, 0x8468}, {0x8469, 0x8469}, + {0x846A, 0x846A}, {0x846B, 0x846B}, {0x846C, 0x846C}, {0x846D, 0x846D}, {0x846E, 0x846E}, {0x846F, 0x846F}, {0x8470, 0x8470}, + {0x8471, 0x8471}, {0x8472, 0x8472}, {0x8473, 0x8473}, {0x8474, 0x8474}, {0x8475, 0x8475}, {0x8476, 0x8476}, {0x8477, 0x8477}, + {0x8478, 0x8478}, {0x8479, 0x8479}, {0x847A, 0x847A}, {0x847B, 0x847B}, {0x847C, 0x847C}, {0x847D, 0x847D}, {0x847E, 0x847E}, + {0x847F, 0x847F}, {0x8480, 0x8480}, {0x8481, 0x8481}, {0x8482, 0x8482}, {0x8483, 0x8483}, {0x8484, 0x8484}, {0x8485, 0x8485}, + {0x8486, 0x8486}, {0x8487, 0x8487}, {0x8488, 0x8488}, {0x8489, 0x8489}, {0x848A, 0x848A}, {0x848B, 0x848B}, {0x848C, 0x848C}, + {0x848D, 0x848D}, {0x848E, 0x848E}, {0x848F, 0x848F}, {0x8490, 0x8490}, {0x8491, 0x8491}, {0x8492, 0x8492}, {0x8493, 0x8493}, + {0x8494, 0x8494}, {0x8495, 0x8495}, {0x8496, 0x8496}, {0x8497, 0x8497}, {0x8498, 0x8498}, {0x8499, 0x8499}, {0x849A, 0x849A}, + {0x849B, 0x849B}, {0x849C, 0x849C}, {0x849D, 0x849D}, {0x849E, 0x849E}, {0x849F, 0x849F}, {0x84A0, 0x84A0}, {0x84A1, 0x84A1}, + {0x84A2, 0x84A2}, {0x84A3, 0x84A3}, {0x84A4, 0x84A4}, {0x84A5, 0x84A5}, {0x84A6, 0x84A6}, {0x84A7, 0x84A7}, {0x84A8, 0x84A8}, + {0x84A9, 0x84A9}, {0x84AA, 0x84AA}, {0x84AB, 0x84AB}, {0x84AC, 0x84AC}, {0x84AD, 0x84AD}, {0x84AE, 0x84AE}, {0x84AF, 0x84AF}, + {0x84B0, 0x84B0}, {0x84B1, 0x84B1}, {0x84B2, 0x84B2}, {0x84B3, 0x84B3}, {0x84B4, 0x84B4}, {0x84B5, 0x84B5}, {0x84B6, 0x84B6}, + {0x84B7, 0x84B7}, {0x84B8, 0x84B8}, {0x84B9, 0x84B9}, {0x84BA, 0x84BA}, {0x84BB, 0x84BB}, {0x84BC, 0x84BC}, {0x84BD, 0x84BD}, + {0x84BE, 0x84BE}, {0x84BF, 0x84BF}, {0x84C0, 0x84C0}, {0x84C1, 0x84C1}, {0x84C2, 0x84C2}, {0x84C3, 0x84C3}, {0x84C4, 0x84C4}, + {0x84C5, 0x84C5}, {0x84C6, 0x84C6}, {0x84C7, 0x84C7}, {0x84C8, 0x84C8}, {0x84C9, 0x84C9}, {0x84CA, 0x84CA}, {0x84CB, 0x84CB}, + {0x84CC, 0x84CC}, {0x84CD, 0x84CD}, {0x84CE, 0x84CE}, {0x84CF, 0x84CF}, {0x84D0, 0x84D0}, {0x84D1, 0x84D1}, {0x84D2, 0x84D2}, + {0x84D3, 0x84D3}, {0x84D4, 0x84D4}, {0x84D5, 0x84D5}, {0x84D6, 0x84D6}, {0x84D7, 0x84D7}, {0x84D8, 0x84D8}, {0x84D9, 0x84D9}, + {0x84DA, 0x84DA}, {0x84DB, 0x84DB}, {0x84DC, 0x84DC}, {0x84DD, 0x84DD}, {0x84DE, 0x84DE}, {0x84DF, 0x84DF}, {0x84E0, 0x84E0}, + {0x84E1, 0x84E1}, {0x84E2, 0x84E2}, {0x84E3, 0x84E3}, {0x84E4, 0x84E4}, {0x84E5, 0x84E5}, {0x84E6, 0x84E6}, {0x84E7, 0x84E7}, + {0x84E8, 0x84E8}, {0x84E9, 0x84E9}, {0x84EA, 0x84EA}, {0x84EB, 0x84EB}, {0x84EC, 0x84EC}, {0x84ED, 0x84ED}, {0x84EE, 0x84EE}, + {0x84EF, 0x84EF}, {0x84F0, 0x84F0}, {0x84F1, 0x84F1}, {0x84F2, 0x84F2}, {0x84F3, 0x84F3}, {0x84F4, 0x84F4}, {0x84F5, 0x84F5}, + {0x84F6, 0x84F6}, {0x84F7, 0x84F7}, {0x84F8, 0x84F8}, {0x84F9, 0x84F9}, {0x84FA, 0x84FA}, {0x84FB, 0x84FB}, {0x84FC, 0x84FC}, + {0x84FD, 0x84FD}, {0x84FE, 0x84FE}, {0x84FF, 0x84FF}, {0x8500, 0x8500}, {0x8501, 0x8501}, {0x8502, 0x8502}, {0x8503, 0x8503}, + {0x8504, 0x8504}, {0x8505, 0x8505}, {0x8506, 0x8506}, {0x8507, 0x8507}, {0x8508, 0x8508}, {0x8509, 0x8509}, {0x850A, 0x850A}, + {0x850B, 0x850B}, {0x850C, 0x850C}, {0x850D, 0x850D}, {0x850E, 0x850E}, {0x850F, 0x850F}, {0x8510, 0x8510}, {0x8511, 0x8511}, + {0x8512, 0x8512}, {0x8513, 0x8513}, {0x8514, 0x8514}, {0x8515, 0x8515}, {0x8516, 0x8516}, {0x8517, 0x8517}, {0x8518, 0x8518}, + {0x8519, 0x8519}, {0x851A, 0x851A}, {0x851B, 0x851B}, {0x851C, 0x851C}, {0x851D, 0x851D}, {0x851E, 0x851E}, {0x851F, 0x851F}, + {0x8520, 0x8520}, {0x8521, 0x8521}, {0x8522, 0x8522}, {0x8523, 0x8523}, {0x8524, 0x8524}, {0x8525, 0x8525}, {0x8526, 0x8526}, + {0x8527, 0x8527}, {0x8528, 0x8528}, {0x8529, 0x8529}, {0x852A, 0x852A}, {0x852B, 0x852B}, {0x852C, 0x852C}, {0x852D, 0x852D}, + {0x852E, 0x852E}, {0x852F, 0x852F}, {0x8530, 0x8530}, {0x8531, 0x8531}, {0x8532, 0x8532}, {0x8533, 0x8533}, {0x8534, 0x8534}, + {0x8535, 0x8535}, {0x8536, 0x8536}, {0x8537, 0x8537}, {0x8538, 0x8538}, {0x8539, 0x8539}, {0x853A, 0x853A}, {0x853B, 0x853B}, + {0x853C, 0x853C}, {0x853D, 0x853D}, {0x853E, 0x853E}, {0x853F, 0x853F}, {0x8540, 0x8540}, {0x8541, 0x8541}, {0x8542, 0x8542}, + {0x8543, 0x8543}, {0x8544, 0x8544}, {0x8545, 0x8545}, {0x8546, 0x8546}, {0x8547, 0x8547}, {0x8548, 0x8548}, {0x8549, 0x8549}, + {0x854A, 0x854A}, {0x854B, 0x854B}, {0x854C, 0x854C}, {0x854D, 0x854D}, {0x854E, 0x854E}, {0x854F, 0x854F}, {0x8550, 0x8550}, + {0x8551, 0x8551}, {0x8552, 0x8552}, {0x8553, 0x8553}, {0x8554, 0x8554}, {0x8555, 0x8555}, {0x8556, 0x8556}, {0x8557, 0x8557}, + {0x8558, 0x8558}, {0x8559, 0x8559}, {0x855A, 0x855A}, {0x855B, 0x855B}, {0x855C, 0x855C}, {0x855D, 0x855D}, {0x855E, 0x855E}, + {0x855F, 0x855F}, {0x8560, 0x8560}, {0x8561, 0x8561}, {0x8562, 0x8562}, {0x8563, 0x8563}, {0x8564, 0x8564}, {0x8565, 0x8565}, + {0x8566, 0x8566}, {0x8567, 0x8567}, {0x8568, 0x8568}, {0x8569, 0x8569}, {0x856A, 0x856A}, {0x856B, 0x856B}, {0x856C, 0x856C}, + {0x856D, 0x856D}, {0x856E, 0x856E}, {0x856F, 0x856F}, {0x8570, 0x8570}, {0x8571, 0x8571}, {0x8572, 0x8572}, {0x8573, 0x8573}, + {0x8574, 0x8574}, {0x8575, 0x8575}, {0x8576, 0x8576}, {0x8577, 0x8577}, {0x8578, 0x8578}, {0x8579, 0x8579}, {0x857A, 0x857A}, + {0x857B, 0x857B}, {0x857C, 0x857C}, {0x857D, 0x857D}, {0x857E, 0x857E}, {0x857F, 0x857F}, {0x8580, 0x8580}, {0x8581, 0x8581}, + {0x8582, 0x8582}, {0x8583, 0x8583}, {0x8584, 0x8584}, {0x8585, 0x8585}, {0x8586, 0x8586}, {0x8587, 0x8587}, {0x8588, 0x8588}, + {0x8589, 0x8589}, {0x858A, 0x858A}, {0x858B, 0x858B}, {0x858C, 0x858C}, {0x858D, 0x858D}, {0x858E, 0x858E}, {0x858F, 0x858F}, + {0x8590, 0x8590}, {0x8591, 0x8591}, {0x8592, 0x8592}, {0x8593, 0x8593}, {0x8594, 0x8594}, {0x8595, 0x8595}, {0x8596, 0x8596}, + {0x8597, 0x8597}, {0x8598, 0x8598}, {0x8599, 0x8599}, {0x859A, 0x859A}, {0x859B, 0x859B}, {0x859C, 0x859C}, {0x859D, 0x859D}, + {0x859E, 0x859E}, {0x859F, 0x859F}, {0x85A0, 0x85A0}, {0x85A1, 0x85A1}, {0x85A2, 0x85A2}, {0x85A3, 0x85A3}, {0x85A4, 0x85A4}, + {0x85A5, 0x85A5}, {0x85A6, 0x85A6}, {0x85A7, 0x85A7}, {0x85A8, 0x85A8}, {0x85A9, 0x85A9}, {0x85AA, 0x85AA}, {0x85AB, 0x85AB}, + {0x85AC, 0x85AC}, {0x85AD, 0x85AD}, {0x85AE, 0x85AE}, {0x85AF, 0x85AF}, {0x85B0, 0x85B0}, {0x85B1, 0x85B1}, {0x85B2, 0x85B2}, + {0x85B3, 0x85B3}, {0x85B4, 0x85B4}, {0x85B5, 0x85B5}, {0x85B6, 0x85B6}, {0x85B7, 0x85B7}, {0x85B8, 0x85B8}, {0x85B9, 0x85B9}, + {0x85BA, 0x85BA}, {0x85BB, 0x85BB}, {0x85BC, 0x85BC}, {0x85BD, 0x85BD}, {0x85BE, 0x85BE}, {0x85BF, 0x85BF}, {0x85C0, 0x85C0}, + {0x85C1, 0x85C1}, {0x85C2, 0x85C2}, {0x85C3, 0x85C3}, {0x85C4, 0x85C4}, {0x85C5, 0x85C5}, {0x85C6, 0x85C6}, {0x85C7, 0x85C7}, + {0x85C8, 0x85C8}, {0x85C9, 0x85C9}, {0x85CA, 0x85CA}, {0x85CB, 0x85CB}, {0x85CC, 0x85CC}, {0x85CD, 0x85CD}, {0x85CE, 0x85CE}, + {0x85CF, 0x85CF}, {0x85D0, 0x85D0}, {0x85D1, 0x85D1}, {0x85D2, 0x85D2}, {0x85D3, 0x85D3}, {0x85D4, 0x85D4}, {0x85D5, 0x85D5}, + {0x85D6, 0x85D6}, {0x85D7, 0x85D7}, {0x85D8, 0x85D8}, {0x85D9, 0x85D9}, {0x85DA, 0x85DA}, {0x85DB, 0x85DB}, {0x85DC, 0x85DC}, + {0x85DD, 0x85DD}, {0x85DE, 0x85DE}, {0x85DF, 0x85DF}, {0x85E0, 0x85E0}, {0x85E1, 0x85E1}, {0x85E2, 0x85E2}, {0x85E3, 0x85E3}, + {0x85E4, 0x85E4}, {0x85E5, 0x85E5}, {0x85E6, 0x85E6}, {0x85E7, 0x85E7}, {0x85E8, 0x85E8}, {0x85E9, 0x85E9}, {0x85EA, 0x85EA}, + {0x85EB, 0x85EB}, {0x85EC, 0x85EC}, {0x85ED, 0x85ED}, {0x85EE, 0x85EE}, {0x85EF, 0x85EF}, {0x85F0, 0x85F0}, {0x85F1, 0x85F1}, + {0x85F2, 0x85F2}, {0x85F3, 0x85F3}, {0x85F4, 0x85F4}, {0x85F5, 0x85F5}, {0x85F6, 0x85F6}, {0x85F7, 0x85F7}, {0x85F8, 0x85F8}, + {0x85F9, 0x85F9}, {0x85FA, 0x85FA}, {0x85FB, 0x85FB}, {0x85FC, 0x85FC}, {0x85FD, 0x85FD}, {0x85FE, 0x85FE}, {0x85FF, 0x85FF}, + {0x8600, 0x8600}, {0x8601, 0x8601}, {0x8602, 0x8602}, {0x8603, 0x8603}, {0x8604, 0x8604}, {0x8605, 0x8605}, {0x8606, 0x8606}, + {0x8607, 0x8607}, {0x8608, 0x8608}, {0x8609, 0x8609}, {0x860A, 0x860A}, {0x860B, 0x860B}, {0x860C, 0x860C}, {0x860D, 0x860D}, + {0x860E, 0x860E}, {0x860F, 0x860F}, {0x8610, 0x8610}, {0x8611, 0x8611}, {0x8612, 0x8612}, {0x8613, 0x8613}, {0x8614, 0x8614}, + {0x8615, 0x8615}, {0x8616, 0x8616}, {0x8617, 0x8617}, {0x8618, 0x8618}, {0x8619, 0x8619}, {0x861A, 0x861A}, {0x861B, 0x861B}, + {0x861C, 0x861C}, {0x861D, 0x861D}, {0x861E, 0x861E}, {0x861F, 0x861F}, {0x8620, 0x8620}, {0x8621, 0x8621}, {0x8622, 0x8622}, + {0x8623, 0x8623}, {0x8624, 0x8624}, {0x8625, 0x8625}, {0x8626, 0x8626}, {0x8627, 0x8627}, {0x8628, 0x8628}, {0x8629, 0x8629}, + {0x862A, 0x862A}, {0x862B, 0x862B}, {0x862C, 0x862C}, {0x862D, 0x862D}, {0x862E, 0x862E}, {0x862F, 0x862F}, {0x8630, 0x8630}, + {0x8631, 0x8631}, {0x8632, 0x8632}, {0x8633, 0x8633}, {0x8634, 0x8634}, {0x8635, 0x8635}, {0x8636, 0x8636}, {0x8637, 0x8637}, + {0x8638, 0x8638}, {0x8639, 0x8639}, {0x863A, 0x863A}, {0x863B, 0x863B}, {0x863C, 0x863C}, {0x863D, 0x863D}, {0x863E, 0x863E}, + {0x863F, 0x863F}, {0x8640, 0x8640}, {0x8641, 0x8641}, {0x8642, 0x8642}, {0x8643, 0x8643}, {0x8644, 0x8644}, {0x8645, 0x8645}, + {0x8646, 0x8646}, {0x8647, 0x8647}, {0x8648, 0x8648}, {0x8649, 0x8649}, {0x864A, 0x864A}, {0x864B, 0x864B}, {0x864C, 0x864C}, + {0x864D, 0x864D}, {0x864E, 0x864E}, {0x864F, 0x864F}, {0x8650, 0x8650}, {0x8651, 0x8651}, {0x8652, 0x8652}, {0x8653, 0x8653}, + {0x8654, 0x8654}, {0x8655, 0x8655}, {0x8656, 0x8656}, {0x8657, 0x8657}, {0x8658, 0x8658}, {0x8659, 0x8659}, {0x865A, 0x865A}, + {0x865B, 0x865B}, {0x865C, 0x865C}, {0x865D, 0x865D}, {0x865E, 0x865E}, {0x865F, 0x865F}, {0x8660, 0x8660}, {0x8661, 0x8661}, + {0x8662, 0x8662}, {0x8663, 0x8663}, {0x8664, 0x8664}, {0x8665, 0x8665}, {0x8666, 0x8666}, {0x8667, 0x8667}, {0x8668, 0x8668}, + {0x8669, 0x8669}, {0x866A, 0x866A}, {0x866B, 0x866B}, {0x866C, 0x866C}, {0x866D, 0x866D}, {0x866E, 0x866E}, {0x866F, 0x866F}, + {0x8670, 0x8670}, {0x8671, 0x8671}, {0x8672, 0x8672}, {0x8673, 0x8673}, {0x8674, 0x8674}, {0x8675, 0x8675}, {0x8676, 0x8676}, + {0x8677, 0x8677}, {0x8678, 0x8678}, {0x8679, 0x8679}, {0x867A, 0x867A}, {0x867B, 0x867B}, {0x867C, 0x867C}, {0x867D, 0x867D}, + {0x867E, 0x867E}, {0x867F, 0x867F}, {0x8680, 0x8680}, {0x8681, 0x8681}, {0x8682, 0x8682}, {0x8683, 0x8683}, {0x8684, 0x8684}, + {0x8685, 0x8685}, {0x8686, 0x8686}, {0x8687, 0x8687}, {0x8688, 0x8688}, {0x8689, 0x8689}, {0x868A, 0x868A}, {0x868B, 0x868B}, + {0x868C, 0x868C}, {0x868D, 0x868D}, {0x868E, 0x868E}, {0x868F, 0x868F}, {0x8690, 0x8690}, {0x8691, 0x8691}, {0x8692, 0x8692}, + {0x8693, 0x8693}, {0x8694, 0x8694}, {0x8695, 0x8695}, {0x8696, 0x8696}, {0x8697, 0x8697}, {0x8698, 0x8698}, {0x8699, 0x8699}, + {0x869A, 0x869A}, {0x869B, 0x869B}, {0x869C, 0x869C}, {0x869D, 0x869D}, {0x869E, 0x869E}, {0x869F, 0x869F}, {0x86A0, 0x86A0}, + {0x86A1, 0x86A1}, {0x86A2, 0x86A2}, {0x86A3, 0x86A3}, {0x86A4, 0x86A4}, {0x86A5, 0x86A5}, {0x86A6, 0x86A6}, {0x86A7, 0x86A7}, + {0x86A8, 0x86A8}, {0x86A9, 0x86A9}, {0x86AA, 0x86AA}, {0x86AB, 0x86AB}, {0x86AC, 0x86AC}, {0x86AD, 0x86AD}, {0x86AE, 0x86AE}, + {0x86AF, 0x86AF}, {0x86B0, 0x86B0}, {0x86B1, 0x86B1}, {0x86B2, 0x86B2}, {0x86B3, 0x86B3}, {0x86B4, 0x86B4}, {0x86B5, 0x86B5}, + {0x86B6, 0x86B6}, {0x86B7, 0x86B7}, {0x86B8, 0x86B8}, {0x86B9, 0x86B9}, {0x86BA, 0x86BA}, {0x86BB, 0x86BB}, {0x86BC, 0x86BC}, + {0x86BD, 0x86BD}, {0x86BE, 0x86BE}, {0x86BF, 0x86BF}, {0x86C0, 0x86C0}, {0x86C1, 0x86C1}, {0x86C2, 0x86C2}, {0x86C3, 0x86C3}, + {0x86C4, 0x86C4}, {0x86C5, 0x86C5}, {0x86C6, 0x86C6}, {0x86C7, 0x86C7}, {0x86C8, 0x86C8}, {0x86C9, 0x86C9}, {0x86CA, 0x86CA}, + {0x86CB, 0x86CB}, {0x86CC, 0x86CC}, {0x86CD, 0x86CD}, {0x86CE, 0x86CE}, {0x86CF, 0x86CF}, {0x86D0, 0x86D0}, {0x86D1, 0x86D1}, + {0x86D2, 0x86D2}, {0x86D3, 0x86D3}, {0x86D4, 0x86D4}, {0x86D5, 0x86D5}, {0x86D6, 0x86D6}, {0x86D7, 0x86D7}, {0x86D8, 0x86D8}, + {0x86D9, 0x86D9}, {0x86DA, 0x86DA}, {0x86DB, 0x86DB}, {0x86DC, 0x86DC}, {0x86DD, 0x86DD}, {0x86DE, 0x86DE}, {0x86DF, 0x86DF}, + {0x86E0, 0x86E0}, {0x86E1, 0x86E1}, {0x86E2, 0x86E2}, {0x86E3, 0x86E3}, {0x86E4, 0x86E4}, {0x86E5, 0x86E5}, {0x86E6, 0x86E6}, + {0x86E7, 0x86E7}, {0x86E8, 0x86E8}, {0x86E9, 0x86E9}, {0x86EA, 0x86EA}, {0x86EB, 0x86EB}, {0x86EC, 0x86EC}, {0x86ED, 0x86ED}, + {0x86EE, 0x86EE}, {0x86EF, 0x86EF}, {0x86F0, 0x86F0}, {0x86F1, 0x86F1}, {0x86F2, 0x86F2}, {0x86F3, 0x86F3}, {0x86F4, 0x86F4}, + {0x86F5, 0x86F5}, {0x86F6, 0x86F6}, {0x86F7, 0x86F7}, {0x86F8, 0x86F8}, {0x86F9, 0x86F9}, {0x86FA, 0x86FA}, {0x86FB, 0x86FB}, + {0x86FC, 0x86FC}, {0x86FD, 0x86FD}, {0x86FE, 0x86FE}, {0x86FF, 0x86FF}, {0x8700, 0x8700}, {0x8701, 0x8701}, {0x8702, 0x8702}, + {0x8703, 0x8703}, {0x8704, 0x8704}, {0x8705, 0x8705}, {0x8706, 0x8706}, {0x8707, 0x8707}, {0x8708, 0x8708}, {0x8709, 0x8709}, + {0x870A, 0x870A}, {0x870B, 0x870B}, {0x870C, 0x870C}, {0x870D, 0x870D}, {0x870E, 0x870E}, {0x870F, 0x870F}, {0x8710, 0x8710}, + {0x8711, 0x8711}, {0x8712, 0x8712}, {0x8713, 0x8713}, {0x8714, 0x8714}, {0x8715, 0x8715}, {0x8716, 0x8716}, {0x8717, 0x8717}, + {0x8718, 0x8718}, {0x8719, 0x8719}, {0x871A, 0x871A}, {0x871B, 0x871B}, {0x871C, 0x871C}, {0x871D, 0x871D}, {0x871E, 0x871E}, + {0x871F, 0x871F}, {0x8720, 0x8720}, {0x8721, 0x8721}, {0x8722, 0x8722}, {0x8723, 0x8723}, {0x8724, 0x8724}, {0x8725, 0x8725}, + {0x8726, 0x8726}, {0x8727, 0x8727}, {0x8728, 0x8728}, {0x8729, 0x8729}, {0x872A, 0x872A}, {0x872B, 0x872B}, {0x872C, 0x872C}, + {0x872D, 0x872D}, {0x872E, 0x872E}, {0x872F, 0x872F}, {0x8730, 0x8730}, {0x8731, 0x8731}, {0x8732, 0x8732}, {0x8733, 0x8733}, + {0x8734, 0x8734}, {0x8735, 0x8735}, {0x8736, 0x8736}, {0x8737, 0x8737}, {0x8738, 0x8738}, {0x8739, 0x8739}, {0x873A, 0x873A}, + {0x873B, 0x873B}, {0x873C, 0x873C}, {0x873D, 0x873D}, {0x873E, 0x873E}, {0x873F, 0x873F}, {0x8740, 0x8740}, {0x8741, 0x8741}, + {0x8742, 0x8742}, {0x8743, 0x8743}, {0x8744, 0x8744}, {0x8745, 0x8745}, {0x8746, 0x8746}, {0x8747, 0x8747}, {0x8748, 0x8748}, + {0x8749, 0x8749}, {0x874A, 0x874A}, {0x874B, 0x874B}, {0x874C, 0x874C}, {0x874D, 0x874D}, {0x874E, 0x874E}, {0x874F, 0x874F}, + {0x8750, 0x8750}, {0x8751, 0x8751}, {0x8752, 0x8752}, {0x8753, 0x8753}, {0x8754, 0x8754}, {0x8755, 0x8755}, {0x8756, 0x8756}, + {0x8757, 0x8757}, {0x8758, 0x8758}, {0x8759, 0x8759}, {0x875A, 0x875A}, {0x875B, 0x875B}, {0x875C, 0x875C}, {0x875D, 0x875D}, + {0x875E, 0x875E}, {0x875F, 0x875F}, {0x8760, 0x8760}, {0x8761, 0x8761}, {0x8762, 0x8762}, {0x8763, 0x8763}, {0x8764, 0x8764}, + {0x8765, 0x8765}, {0x8766, 0x8766}, {0x8767, 0x8767}, {0x8768, 0x8768}, {0x8769, 0x8769}, {0x876A, 0x876A}, {0x876B, 0x876B}, + {0x876C, 0x876C}, {0x876D, 0x876D}, {0x876E, 0x876E}, {0x876F, 0x876F}, {0x8770, 0x8770}, {0x8771, 0x8771}, {0x8772, 0x8772}, + {0x8773, 0x8773}, {0x8774, 0x8774}, {0x8775, 0x8775}, {0x8776, 0x8776}, {0x8777, 0x8777}, {0x8778, 0x8778}, {0x8779, 0x8779}, + {0x877A, 0x877A}, {0x877B, 0x877B}, {0x877C, 0x877C}, {0x877D, 0x877D}, {0x877E, 0x877E}, {0x877F, 0x877F}, {0x8780, 0x8780}, + {0x8781, 0x8781}, {0x8782, 0x8782}, {0x8783, 0x8783}, {0x8784, 0x8784}, {0x8785, 0x8785}, {0x8786, 0x8786}, {0x8787, 0x8787}, + {0x8788, 0x8788}, {0x8789, 0x8789}, {0x878A, 0x878A}, {0x878B, 0x878B}, {0x878C, 0x878C}, {0x878D, 0x878D}, {0x878E, 0x878E}, + {0x878F, 0x878F}, {0x8790, 0x8790}, {0x8791, 0x8791}, {0x8792, 0x8792}, {0x8793, 0x8793}, {0x8794, 0x8794}, {0x8795, 0x8795}, + {0x8796, 0x8796}, {0x8797, 0x8797}, {0x8798, 0x8798}, {0x8799, 0x8799}, {0x879A, 0x879A}, {0x879B, 0x879B}, {0x879C, 0x879C}, + {0x879D, 0x879D}, {0x879E, 0x879E}, {0x879F, 0x879F}, {0x87A0, 0x87A0}, {0x87A1, 0x87A1}, {0x87A2, 0x87A2}, {0x87A3, 0x87A3}, + {0x87A4, 0x87A4}, {0x87A5, 0x87A5}, {0x87A6, 0x87A6}, {0x87A7, 0x87A7}, {0x87A8, 0x87A8}, {0x87A9, 0x87A9}, {0x87AA, 0x87AA}, + {0x87AB, 0x87AB}, {0x87AC, 0x87AC}, {0x87AD, 0x87AD}, {0x87AE, 0x87AE}, {0x87AF, 0x87AF}, {0x87B0, 0x87B0}, {0x87B1, 0x87B1}, + {0x87B2, 0x87B2}, {0x87B3, 0x87B3}, {0x87B4, 0x87B4}, {0x87B5, 0x87B5}, {0x87B6, 0x87B6}, {0x87B7, 0x87B7}, {0x87B8, 0x87B8}, + {0x87B9, 0x87B9}, {0x87BA, 0x87BA}, {0x87BB, 0x87BB}, {0x87BC, 0x87BC}, {0x87BD, 0x87BD}, {0x87BE, 0x87BE}, {0x87BF, 0x87BF}, + {0x87C0, 0x87C0}, {0x87C1, 0x87C1}, {0x87C2, 0x87C2}, {0x87C3, 0x87C3}, {0x87C4, 0x87C4}, {0x87C5, 0x87C5}, {0x87C6, 0x87C6}, + {0x87C7, 0x87C7}, {0x87C8, 0x87C8}, {0x87C9, 0x87C9}, {0x87CA, 0x87CA}, {0x87CB, 0x87CB}, {0x87CC, 0x87CC}, {0x87CD, 0x87CD}, + {0x87CE, 0x87CE}, {0x87CF, 0x87CF}, {0x87D0, 0x87D0}, {0x87D1, 0x87D1}, {0x87D2, 0x87D2}, {0x87D3, 0x87D3}, {0x87D4, 0x87D4}, + {0x87D5, 0x87D5}, {0x87D6, 0x87D6}, {0x87D7, 0x87D7}, {0x87D8, 0x87D8}, {0x87D9, 0x87D9}, {0x87DA, 0x87DA}, {0x87DB, 0x87DB}, + {0x87DC, 0x87DC}, {0x87DD, 0x87DD}, {0x87DE, 0x87DE}, {0x87DF, 0x87DF}, {0x87E0, 0x87E0}, {0x87E1, 0x87E1}, {0x87E2, 0x87E2}, + {0x87E3, 0x87E3}, {0x87E4, 0x87E4}, {0x87E5, 0x87E5}, {0x87E6, 0x87E6}, {0x87E7, 0x87E7}, {0x87E8, 0x87E8}, {0x87E9, 0x87E9}, + {0x87EA, 0x87EA}, {0x87EB, 0x87EB}, {0x87EC, 0x87EC}, {0x87ED, 0x87ED}, {0x87EE, 0x87EE}, {0x87EF, 0x87EF}, {0x87F0, 0x87F0}, + {0x87F1, 0x87F1}, {0x87F2, 0x87F2}, {0x87F3, 0x87F3}, {0x87F4, 0x87F4}, {0x87F5, 0x87F5}, {0x87F6, 0x87F6}, {0x87F7, 0x87F7}, + {0x87F8, 0x87F8}, {0x87F9, 0x87F9}, {0x87FA, 0x87FA}, {0x87FB, 0x87FB}, {0x87FC, 0x87FC}, {0x87FD, 0x87FD}, {0x87FE, 0x87FE}, + {0x87FF, 0x87FF}, {0x8800, 0x8800}, {0x8801, 0x8801}, {0x8802, 0x8802}, {0x8803, 0x8803}, {0x8804, 0x8804}, {0x8805, 0x8805}, + {0x8806, 0x8806}, {0x8807, 0x8807}, {0x8808, 0x8808}, {0x8809, 0x8809}, {0x880A, 0x880A}, {0x880B, 0x880B}, {0x880C, 0x880C}, + {0x880D, 0x880D}, {0x880E, 0x880E}, {0x880F, 0x880F}, {0x8810, 0x8810}, {0x8811, 0x8811}, {0x8812, 0x8812}, {0x8813, 0x8813}, + {0x8814, 0x8814}, {0x8815, 0x8815}, {0x8816, 0x8816}, {0x8817, 0x8817}, {0x8818, 0x8818}, {0x8819, 0x8819}, {0x881A, 0x881A}, + {0x881B, 0x881B}, {0x881C, 0x881C}, {0x881D, 0x881D}, {0x881E, 0x881E}, {0x881F, 0x881F}, {0x8820, 0x8820}, {0x8821, 0x8821}, + {0x8822, 0x8822}, {0x8823, 0x8823}, {0x8824, 0x8824}, {0x8825, 0x8825}, {0x8826, 0x8826}, {0x8827, 0x8827}, {0x8828, 0x8828}, + {0x8829, 0x8829}, {0x882A, 0x882A}, {0x882B, 0x882B}, {0x882C, 0x882C}, {0x882D, 0x882D}, {0x882E, 0x882E}, {0x882F, 0x882F}, + {0x8830, 0x8830}, {0x8831, 0x8831}, {0x8832, 0x8832}, {0x8833, 0x8833}, {0x8834, 0x8834}, {0x8835, 0x8835}, {0x8836, 0x8836}, + {0x8837, 0x8837}, {0x8838, 0x8838}, {0x8839, 0x8839}, {0x883A, 0x883A}, {0x883B, 0x883B}, {0x883C, 0x883C}, {0x883D, 0x883D}, + {0x883E, 0x883E}, {0x883F, 0x883F}, {0x8840, 0x8840}, {0x8841, 0x8841}, {0x8842, 0x8842}, {0x8843, 0x8843}, {0x8844, 0x8844}, + {0x8845, 0x8845}, {0x8846, 0x8846}, {0x8847, 0x8847}, {0x8848, 0x8848}, {0x8849, 0x8849}, {0x884A, 0x884A}, {0x884B, 0x884B}, + {0x884C, 0x884C}, {0x884D, 0x884D}, {0x884E, 0x884E}, {0x884F, 0x884F}, {0x8850, 0x8850}, {0x8851, 0x8851}, {0x8852, 0x8852}, + {0x8853, 0x8853}, {0x8854, 0x8854}, {0x8855, 0x8855}, {0x8856, 0x8856}, {0x8857, 0x8857}, {0x8858, 0x8858}, {0x8859, 0x8859}, + {0x885A, 0x885A}, {0x885B, 0x885B}, {0x885C, 0x885C}, {0x885D, 0x885D}, {0x885E, 0x885E}, {0x885F, 0x885F}, {0x8860, 0x8860}, + {0x8861, 0x8861}, {0x8862, 0x8862}, {0x8863, 0x8863}, {0x8864, 0x8864}, {0x8865, 0x8865}, {0x8866, 0x8866}, {0x8867, 0x8867}, + {0x8868, 0x8868}, {0x8869, 0x8869}, {0x886A, 0x886A}, {0x886B, 0x886B}, {0x886C, 0x886C}, {0x886D, 0x886D}, {0x886E, 0x886E}, + {0x886F, 0x886F}, {0x8870, 0x8870}, {0x8871, 0x8871}, {0x8872, 0x8872}, {0x8873, 0x8873}, {0x8874, 0x8874}, {0x8875, 0x8875}, + {0x8876, 0x8876}, {0x8877, 0x8877}, {0x8878, 0x8878}, {0x8879, 0x8879}, {0x887A, 0x887A}, {0x887B, 0x887B}, {0x887C, 0x887C}, + {0x887D, 0x887D}, {0x887E, 0x887E}, {0x887F, 0x887F}, {0x8880, 0x8880}, {0x8881, 0x8881}, {0x8882, 0x8882}, {0x8883, 0x8883}, + {0x8884, 0x8884}, {0x8885, 0x8885}, {0x8886, 0x8886}, {0x8887, 0x8887}, {0x8888, 0x8888}, {0x8889, 0x8889}, {0x888A, 0x888A}, + {0x888B, 0x888B}, {0x888C, 0x888C}, {0x888D, 0x888D}, {0x888E, 0x888E}, {0x888F, 0x888F}, {0x8890, 0x8890}, {0x8891, 0x8891}, + {0x8892, 0x8892}, {0x8893, 0x8893}, {0x8894, 0x8894}, {0x8895, 0x8895}, {0x8896, 0x8896}, {0x8897, 0x8897}, {0x8898, 0x8898}, + {0x8899, 0x8899}, {0x889A, 0x889A}, {0x889B, 0x889B}, {0x889C, 0x889C}, {0x889D, 0x889D}, {0x889E, 0x889E}, {0x889F, 0x889F}, + {0x88A0, 0x88A0}, {0x88A1, 0x88A1}, {0x88A2, 0x88A2}, {0x88A3, 0x88A3}, {0x88A4, 0x88A4}, {0x88A5, 0x88A5}, {0x88A6, 0x88A6}, + {0x88A7, 0x88A7}, {0x88A8, 0x88A8}, {0x88A9, 0x88A9}, {0x88AA, 0x88AA}, {0x88AB, 0x88AB}, {0x88AC, 0x88AC}, {0x88AD, 0x88AD}, + {0x88AE, 0x88AE}, {0x88AF, 0x88AF}, {0x88B0, 0x88B0}, {0x88B1, 0x88B1}, {0x88B2, 0x88B2}, {0x88B3, 0x88B3}, {0x88B4, 0x88B4}, + {0x88B5, 0x88B5}, {0x88B6, 0x88B6}, {0x88B7, 0x88B7}, {0x88B8, 0x88B8}, {0x88B9, 0x88B9}, {0x88BA, 0x88BA}, {0x88BB, 0x88BB}, + {0x88BC, 0x88BC}, {0x88BD, 0x88BD}, {0x88BE, 0x88BE}, {0x88BF, 0x88BF}, {0x88C0, 0x88C0}, {0x88C1, 0x88C1}, {0x88C2, 0x88C2}, + {0x88C3, 0x88C3}, {0x88C4, 0x88C4}, {0x88C5, 0x88C5}, {0x88C6, 0x88C6}, {0x88C7, 0x88C7}, {0x88C8, 0x88C8}, {0x88C9, 0x88C9}, + {0x88CA, 0x88CA}, {0x88CB, 0x88CB}, {0x88CC, 0x88CC}, {0x88CD, 0x88CD}, {0x88CE, 0x88CE}, {0x88CF, 0x88CF}, {0x88D0, 0x88D0}, + {0x88D1, 0x88D1}, {0x88D2, 0x88D2}, {0x88D3, 0x88D3}, {0x88D4, 0x88D4}, {0x88D5, 0x88D5}, {0x88D6, 0x88D6}, {0x88D7, 0x88D7}, + {0x88D8, 0x88D8}, {0x88D9, 0x88D9}, {0x88DA, 0x88DA}, {0x88DB, 0x88DB}, {0x88DC, 0x88DC}, {0x88DD, 0x88DD}, {0x88DE, 0x88DE}, + {0x88DF, 0x88DF}, {0x88E0, 0x88E0}, {0x88E1, 0x88E1}, {0x88E2, 0x88E2}, {0x88E3, 0x88E3}, {0x88E4, 0x88E4}, {0x88E5, 0x88E5}, + {0x88E6, 0x88E6}, {0x88E7, 0x88E7}, {0x88E8, 0x88E8}, {0x88E9, 0x88E9}, {0x88EA, 0x88EA}, {0x88EB, 0x88EB}, {0x88EC, 0x88EC}, + {0x88ED, 0x88ED}, {0x88EE, 0x88EE}, {0x88EF, 0x88EF}, {0x88F0, 0x88F0}, {0x88F1, 0x88F1}, {0x88F2, 0x88F2}, {0x88F3, 0x88F3}, + {0x88F4, 0x88F4}, {0x88F5, 0x88F5}, {0x88F6, 0x88F6}, {0x88F7, 0x88F7}, {0x88F8, 0x88F8}, {0x88F9, 0x88F9}, {0x88FA, 0x88FA}, + {0x88FB, 0x88FB}, {0x88FC, 0x88FC}, {0x88FD, 0x88FD}, {0x88FE, 0x88FE}, {0x88FF, 0x88FF}, {0x8900, 0x8900}, {0x8901, 0x8901}, + {0x8902, 0x8902}, {0x8903, 0x8903}, {0x8904, 0x8904}, {0x8905, 0x8905}, {0x8906, 0x8906}, {0x8907, 0x8907}, {0x8908, 0x8908}, + {0x8909, 0x8909}, {0x890A, 0x890A}, {0x890B, 0x890B}, {0x890C, 0x890C}, {0x890D, 0x890D}, {0x890E, 0x890E}, {0x890F, 0x890F}, + {0x8910, 0x8910}, {0x8911, 0x8911}, {0x8912, 0x8912}, {0x8913, 0x8913}, {0x8914, 0x8914}, {0x8915, 0x8915}, {0x8916, 0x8916}, + {0x8917, 0x8917}, {0x8918, 0x8918}, {0x8919, 0x8919}, {0x891A, 0x891A}, {0x891B, 0x891B}, {0x891C, 0x891C}, {0x891D, 0x891D}, + {0x891E, 0x891E}, {0x891F, 0x891F}, {0x8920, 0x8920}, {0x8921, 0x8921}, {0x8922, 0x8922}, {0x8923, 0x8923}, {0x8924, 0x8924}, + {0x8925, 0x8925}, {0x8926, 0x8926}, {0x8927, 0x8927}, {0x8928, 0x8928}, {0x8929, 0x8929}, {0x892A, 0x892A}, {0x892B, 0x892B}, + {0x892C, 0x892C}, {0x892D, 0x892D}, {0x892E, 0x892E}, {0x892F, 0x892F}, {0x8930, 0x8930}, {0x8931, 0x8931}, {0x8932, 0x8932}, + {0x8933, 0x8933}, {0x8934, 0x8934}, {0x8935, 0x8935}, {0x8936, 0x8936}, {0x8937, 0x8937}, {0x8938, 0x8938}, {0x8939, 0x8939}, + {0x893A, 0x893A}, {0x893B, 0x893B}, {0x893C, 0x893C}, {0x893D, 0x893D}, {0x893E, 0x893E}, {0x893F, 0x893F}, {0x8940, 0x8940}, + {0x8941, 0x8941}, {0x8942, 0x8942}, {0x8943, 0x8943}, {0x8944, 0x8944}, {0x8945, 0x8945}, {0x8946, 0x8946}, {0x8947, 0x8947}, + {0x8948, 0x8948}, {0x8949, 0x8949}, {0x894A, 0x894A}, {0x894B, 0x894B}, {0x894C, 0x894C}, {0x894D, 0x894D}, {0x894E, 0x894E}, + {0x894F, 0x894F}, {0x8950, 0x8950}, {0x8951, 0x8951}, {0x8952, 0x8952}, {0x8953, 0x8953}, {0x8954, 0x8954}, {0x8955, 0x8955}, + {0x8956, 0x8956}, {0x8957, 0x8957}, {0x8958, 0x8958}, {0x8959, 0x8959}, {0x895A, 0x895A}, {0x895B, 0x895B}, {0x895C, 0x895C}, + {0x895D, 0x895D}, {0x895E, 0x895E}, {0x895F, 0x895F}, {0x8960, 0x8960}, {0x8961, 0x8961}, {0x8962, 0x8962}, {0x8963, 0x8963}, + {0x8964, 0x8964}, {0x8965, 0x8965}, {0x8966, 0x8966}, {0x8967, 0x8967}, {0x8968, 0x8968}, {0x8969, 0x8969}, {0x896A, 0x896A}, + {0x896B, 0x896B}, {0x896C, 0x896C}, {0x896D, 0x896D}, {0x896E, 0x896E}, {0x896F, 0x896F}, {0x8970, 0x8970}, {0x8971, 0x8971}, + {0x8972, 0x8972}, {0x8973, 0x8973}, {0x8974, 0x8974}, {0x8975, 0x8975}, {0x8976, 0x8976}, {0x8977, 0x8977}, {0x8978, 0x8978}, + {0x8979, 0x8979}, {0x897A, 0x897A}, {0x897B, 0x897B}, {0x897C, 0x897C}, {0x897D, 0x897D}, {0x897E, 0x897E}, {0x897F, 0x897F}, + {0x8980, 0x8980}, {0x8981, 0x8981}, {0x8982, 0x8982}, {0x8983, 0x8983}, {0x8984, 0x8984}, {0x8985, 0x8985}, {0x8986, 0x8986}, + {0x8987, 0x8987}, {0x8988, 0x8988}, {0x8989, 0x8989}, {0x898A, 0x898A}, {0x898B, 0x898B}, {0x898C, 0x898C}, {0x898D, 0x898D}, + {0x898E, 0x898E}, {0x898F, 0x898F}, {0x8990, 0x8990}, {0x8991, 0x8991}, {0x8992, 0x8992}, {0x8993, 0x8993}, {0x8994, 0x8994}, + {0x8995, 0x8995}, {0x8996, 0x8996}, {0x8997, 0x8997}, {0x8998, 0x8998}, {0x8999, 0x8999}, {0x899A, 0x899A}, {0x899B, 0x899B}, + {0x899C, 0x899C}, {0x899D, 0x899D}, {0x899E, 0x899E}, {0x899F, 0x899F}, {0x89A0, 0x89A0}, {0x89A1, 0x89A1}, {0x89A2, 0x89A2}, + {0x89A3, 0x89A3}, {0x89A4, 0x89A4}, {0x89A5, 0x89A5}, {0x89A6, 0x89A6}, {0x89A7, 0x89A7}, {0x89A8, 0x89A8}, {0x89A9, 0x89A9}, + {0x89AA, 0x89AA}, {0x89AB, 0x89AB}, {0x89AC, 0x89AC}, {0x89AD, 0x89AD}, {0x89AE, 0x89AE}, {0x89AF, 0x89AF}, {0x89B0, 0x89B0}, + {0x89B1, 0x89B1}, {0x89B2, 0x89B2}, {0x89B3, 0x89B3}, {0x89B4, 0x89B4}, {0x89B5, 0x89B5}, {0x89B6, 0x89B6}, {0x89B7, 0x89B7}, + {0x89B8, 0x89B8}, {0x89B9, 0x89B9}, {0x89BA, 0x89BA}, {0x89BB, 0x89BB}, {0x89BC, 0x89BC}, {0x89BD, 0x89BD}, {0x89BE, 0x89BE}, + {0x89BF, 0x89BF}, {0x89C0, 0x89C0}, {0x89C1, 0x89C1}, {0x89C2, 0x89C2}, {0x89C3, 0x89C3}, {0x89C4, 0x89C4}, {0x89C5, 0x89C5}, + {0x89C6, 0x89C6}, {0x89C7, 0x89C7}, {0x89C8, 0x89C8}, {0x89C9, 0x89C9}, {0x89CA, 0x89CA}, {0x89CB, 0x89CB}, {0x89CC, 0x89CC}, + {0x89CD, 0x89CD}, {0x89CE, 0x89CE}, {0x89CF, 0x89CF}, {0x89D0, 0x89D0}, {0x89D1, 0x89D1}, {0x89D2, 0x89D2}, {0x89D3, 0x89D3}, + {0x89D4, 0x89D4}, {0x89D5, 0x89D5}, {0x89D6, 0x89D6}, {0x89D7, 0x89D7}, {0x89D8, 0x89D8}, {0x89D9, 0x89D9}, {0x89DA, 0x89DA}, + {0x89DB, 0x89DB}, {0x89DC, 0x89DC}, {0x89DD, 0x89DD}, {0x89DE, 0x89DE}, {0x89DF, 0x89DF}, {0x89E0, 0x89E0}, {0x89E1, 0x89E1}, + {0x89E2, 0x89E2}, {0x89E3, 0x89E3}, {0x89E4, 0x89E4}, {0x89E5, 0x89E5}, {0x89E6, 0x89E6}, {0x89E7, 0x89E7}, {0x89E8, 0x89E8}, + {0x89E9, 0x89E9}, {0x89EA, 0x89EA}, {0x89EB, 0x89EB}, {0x89EC, 0x89EC}, {0x89ED, 0x89ED}, {0x89EE, 0x89EE}, {0x89EF, 0x89EF}, + {0x89F0, 0x89F0}, {0x89F1, 0x89F1}, {0x89F2, 0x89F2}, {0x89F3, 0x89F3}, {0x89F4, 0x89F4}, {0x89F5, 0x89F5}, {0x89F6, 0x89F6}, + {0x89F7, 0x89F7}, {0x89F8, 0x89F8}, {0x89F9, 0x89F9}, {0x89FA, 0x89FA}, {0x89FB, 0x89FB}, {0x89FC, 0x89FC}, {0x89FD, 0x89FD}, + {0x89FE, 0x89FE}, {0x89FF, 0x89FF}, {0x8A00, 0x8A00}, {0x8A01, 0x8A01}, {0x8A02, 0x8A02}, {0x8A03, 0x8A03}, {0x8A04, 0x8A04}, + {0x8A05, 0x8A05}, {0x8A06, 0x8A06}, {0x8A07, 0x8A07}, {0x8A08, 0x8A08}, {0x8A09, 0x8A09}, {0x8A0A, 0x8A0A}, {0x8A0B, 0x8A0B}, + {0x8A0C, 0x8A0C}, {0x8A0D, 0x8A0D}, {0x8A0E, 0x8A0E}, {0x8A0F, 0x8A0F}, {0x8A10, 0x8A10}, {0x8A11, 0x8A11}, {0x8A12, 0x8A12}, + {0x8A13, 0x8A13}, {0x8A14, 0x8A14}, {0x8A15, 0x8A15}, {0x8A16, 0x8A16}, {0x8A17, 0x8A17}, {0x8A18, 0x8A18}, {0x8A19, 0x8A19}, + {0x8A1A, 0x8A1A}, {0x8A1B, 0x8A1B}, {0x8A1C, 0x8A1C}, {0x8A1D, 0x8A1D}, {0x8A1E, 0x8A1E}, {0x8A1F, 0x8A1F}, {0x8A20, 0x8A20}, + {0x8A21, 0x8A21}, {0x8A22, 0x8A22}, {0x8A23, 0x8A23}, {0x8A24, 0x8A24}, {0x8A25, 0x8A25}, {0x8A26, 0x8A26}, {0x8A27, 0x8A27}, + {0x8A28, 0x8A28}, {0x8A29, 0x8A29}, {0x8A2A, 0x8A2A}, {0x8A2B, 0x8A2B}, {0x8A2C, 0x8A2C}, {0x8A2D, 0x8A2D}, {0x8A2E, 0x8A2E}, + {0x8A2F, 0x8A2F}, {0x8A30, 0x8A30}, {0x8A31, 0x8A31}, {0x8A32, 0x8A32}, {0x8A33, 0x8A33}, {0x8A34, 0x8A34}, {0x8A35, 0x8A35}, + {0x8A36, 0x8A36}, {0x8A37, 0x8A37}, {0x8A38, 0x8A38}, {0x8A39, 0x8A39}, {0x8A3A, 0x8A3A}, {0x8A3B, 0x8A3B}, {0x8A3C, 0x8A3C}, + {0x8A3D, 0x8A3D}, {0x8A3E, 0x8A3E}, {0x8A3F, 0x8A3F}, {0x8A40, 0x8A40}, {0x8A41, 0x8A41}, {0x8A42, 0x8A42}, {0x8A43, 0x8A43}, + {0x8A44, 0x8A44}, {0x8A45, 0x8A45}, {0x8A46, 0x8A46}, {0x8A47, 0x8A47}, {0x8A48, 0x8A48}, {0x8A49, 0x8A49}, {0x8A4A, 0x8A4A}, + {0x8A4B, 0x8A4B}, {0x8A4C, 0x8A4C}, {0x8A4D, 0x8A4D}, {0x8A4E, 0x8A4E}, {0x8A4F, 0x8A4F}, {0x8A50, 0x8A50}, {0x8A51, 0x8A51}, + {0x8A52, 0x8A52}, {0x8A53, 0x8A53}, {0x8A54, 0x8A54}, {0x8A55, 0x8A55}, {0x8A56, 0x8A56}, {0x8A57, 0x8A57}, {0x8A58, 0x8A58}, + {0x8A59, 0x8A59}, {0x8A5A, 0x8A5A}, {0x8A5B, 0x8A5B}, {0x8A5C, 0x8A5C}, {0x8A5D, 0x8A5D}, {0x8A5E, 0x8A5E}, {0x8A5F, 0x8A5F}, + {0x8A60, 0x8A60}, {0x8A61, 0x8A61}, {0x8A62, 0x8A62}, {0x8A63, 0x8A63}, {0x8A64, 0x8A64}, {0x8A65, 0x8A65}, {0x8A66, 0x8A66}, + {0x8A67, 0x8A67}, {0x8A68, 0x8A68}, {0x8A69, 0x8A69}, {0x8A6A, 0x8A6A}, {0x8A6B, 0x8A6B}, {0x8A6C, 0x8A6C}, {0x8A6D, 0x8A6D}, + {0x8A6E, 0x8A6E}, {0x8A6F, 0x8A6F}, {0x8A70, 0x8A70}, {0x8A71, 0x8A71}, {0x8A72, 0x8A72}, {0x8A73, 0x8A73}, {0x8A74, 0x8A74}, + {0x8A75, 0x8A75}, {0x8A76, 0x8A76}, {0x8A77, 0x8A77}, {0x8A78, 0x8A78}, {0x8A79, 0x8A79}, {0x8A7A, 0x8A7A}, {0x8A7B, 0x8A7B}, + {0x8A7C, 0x8A7C}, {0x8A7D, 0x8A7D}, {0x8A7E, 0x8A7E}, {0x8A7F, 0x8A7F}, {0x8A80, 0x8A80}, {0x8A81, 0x8A81}, {0x8A82, 0x8A82}, + {0x8A83, 0x8A83}, {0x8A84, 0x8A84}, {0x8A85, 0x8A85}, {0x8A86, 0x8A86}, {0x8A87, 0x8A87}, {0x8A88, 0x8A88}, {0x8A89, 0x8A89}, + {0x8A8A, 0x8A8A}, {0x8A8B, 0x8A8B}, {0x8A8C, 0x8A8C}, {0x8A8D, 0x8A8D}, {0x8A8E, 0x8A8E}, {0x8A8F, 0x8A8F}, {0x8A90, 0x8A90}, + {0x8A91, 0x8A91}, {0x8A92, 0x8A92}, {0x8A93, 0x8A93}, {0x8A94, 0x8A94}, {0x8A95, 0x8A95}, {0x8A96, 0x8A96}, {0x8A97, 0x8A97}, + {0x8A98, 0x8A98}, {0x8A99, 0x8A99}, {0x8A9A, 0x8A9A}, {0x8A9B, 0x8A9B}, {0x8A9C, 0x8A9C}, {0x8A9D, 0x8A9D}, {0x8A9E, 0x8A9E}, + {0x8A9F, 0x8A9F}, {0x8AA0, 0x8AA0}, {0x8AA1, 0x8AA1}, {0x8AA2, 0x8AA2}, {0x8AA3, 0x8AA3}, {0x8AA4, 0x8AA4}, {0x8AA5, 0x8AA5}, + {0x8AA6, 0x8AA6}, {0x8AA7, 0x8AA7}, {0x8AA8, 0x8AA8}, {0x8AA9, 0x8AA9}, {0x8AAA, 0x8AAA}, {0x8AAB, 0x8AAB}, {0x8AAC, 0x8AAC}, + {0x8AAD, 0x8AAD}, {0x8AAE, 0x8AAE}, {0x8AAF, 0x8AAF}, {0x8AB0, 0x8AB0}, {0x8AB1, 0x8AB1}, {0x8AB2, 0x8AB2}, {0x8AB3, 0x8AB3}, + {0x8AB4, 0x8AB4}, {0x8AB5, 0x8AB5}, {0x8AB6, 0x8AB6}, {0x8AB7, 0x8AB7}, {0x8AB8, 0x8AB8}, {0x8AB9, 0x8AB9}, {0x8ABA, 0x8ABA}, + {0x8ABB, 0x8ABB}, {0x8ABC, 0x8ABC}, {0x8ABD, 0x8ABD}, {0x8ABE, 0x8ABE}, {0x8ABF, 0x8ABF}, {0x8AC0, 0x8AC0}, {0x8AC1, 0x8AC1}, + {0x8AC2, 0x8AC2}, {0x8AC3, 0x8AC3}, {0x8AC4, 0x8AC4}, {0x8AC5, 0x8AC5}, {0x8AC6, 0x8AC6}, {0x8AC7, 0x8AC7}, {0x8AC8, 0x8AC8}, + {0x8AC9, 0x8AC9}, {0x8ACA, 0x8ACA}, {0x8ACB, 0x8ACB}, {0x8ACC, 0x8ACC}, {0x8ACD, 0x8ACD}, {0x8ACE, 0x8ACE}, {0x8ACF, 0x8ACF}, + {0x8AD0, 0x8AD0}, {0x8AD1, 0x8AD1}, {0x8AD2, 0x8AD2}, {0x8AD3, 0x8AD3}, {0x8AD4, 0x8AD4}, {0x8AD5, 0x8AD5}, {0x8AD6, 0x8AD6}, + {0x8AD7, 0x8AD7}, {0x8AD8, 0x8AD8}, {0x8AD9, 0x8AD9}, {0x8ADA, 0x8ADA}, {0x8ADB, 0x8ADB}, {0x8ADC, 0x8ADC}, {0x8ADD, 0x8ADD}, + {0x8ADE, 0x8ADE}, {0x8ADF, 0x8ADF}, {0x8AE0, 0x8AE0}, {0x8AE1, 0x8AE1}, {0x8AE2, 0x8AE2}, {0x8AE3, 0x8AE3}, {0x8AE4, 0x8AE4}, + {0x8AE5, 0x8AE5}, {0x8AE6, 0x8AE6}, {0x8AE7, 0x8AE7}, {0x8AE8, 0x8AE8}, {0x8AE9, 0x8AE9}, {0x8AEA, 0x8AEA}, {0x8AEB, 0x8AEB}, + {0x8AEC, 0x8AEC}, {0x8AED, 0x8AED}, {0x8AEE, 0x8AEE}, {0x8AEF, 0x8AEF}, {0x8AF0, 0x8AF0}, {0x8AF1, 0x8AF1}, {0x8AF2, 0x8AF2}, + {0x8AF3, 0x8AF3}, {0x8AF4, 0x8AF4}, {0x8AF5, 0x8AF5}, {0x8AF6, 0x8AF6}, {0x8AF7, 0x8AF7}, {0x8AF8, 0x8AF8}, {0x8AF9, 0x8AF9}, + {0x8AFA, 0x8AFA}, {0x8AFB, 0x8AFB}, {0x8AFC, 0x8AFC}, {0x8AFD, 0x8AFD}, {0x8AFE, 0x8AFE}, {0x8AFF, 0x8AFF}, {0x8B00, 0x8B00}, + {0x8B01, 0x8B01}, {0x8B02, 0x8B02}, {0x8B03, 0x8B03}, {0x8B04, 0x8B04}, {0x8B05, 0x8B05}, {0x8B06, 0x8B06}, {0x8B07, 0x8B07}, + {0x8B08, 0x8B08}, {0x8B09, 0x8B09}, {0x8B0A, 0x8B0A}, {0x8B0B, 0x8B0B}, {0x8B0C, 0x8B0C}, {0x8B0D, 0x8B0D}, {0x8B0E, 0x8B0E}, + {0x8B0F, 0x8B0F}, {0x8B10, 0x8B10}, {0x8B11, 0x8B11}, {0x8B12, 0x8B12}, {0x8B13, 0x8B13}, {0x8B14, 0x8B14}, {0x8B15, 0x8B15}, + {0x8B16, 0x8B16}, {0x8B17, 0x8B17}, {0x8B18, 0x8B18}, {0x8B19, 0x8B19}, {0x8B1A, 0x8B1A}, {0x8B1B, 0x8B1B}, {0x8B1C, 0x8B1C}, + {0x8B1D, 0x8B1D}, {0x8B1E, 0x8B1E}, {0x8B1F, 0x8B1F}, {0x8B20, 0x8B20}, {0x8B21, 0x8B21}, {0x8B22, 0x8B22}, {0x8B23, 0x8B23}, + {0x8B24, 0x8B24}, {0x8B25, 0x8B25}, {0x8B26, 0x8B26}, {0x8B27, 0x8B27}, {0x8B28, 0x8B28}, {0x8B29, 0x8B29}, {0x8B2A, 0x8B2A}, + {0x8B2B, 0x8B2B}, {0x8B2C, 0x8B2C}, {0x8B2D, 0x8B2D}, {0x8B2E, 0x8B2E}, {0x8B2F, 0x8B2F}, {0x8B30, 0x8B30}, {0x8B31, 0x8B31}, + {0x8B32, 0x8B32}, {0x8B33, 0x8B33}, {0x8B34, 0x8B34}, {0x8B35, 0x8B35}, {0x8B36, 0x8B36}, {0x8B37, 0x8B37}, {0x8B38, 0x8B38}, + {0x8B39, 0x8B39}, {0x8B3A, 0x8B3A}, {0x8B3B, 0x8B3B}, {0x8B3C, 0x8B3C}, {0x8B3D, 0x8B3D}, {0x8B3E, 0x8B3E}, {0x8B3F, 0x8B3F}, + {0x8B40, 0x8B40}, {0x8B41, 0x8B41}, {0x8B42, 0x8B42}, {0x8B43, 0x8B43}, {0x8B44, 0x8B44}, {0x8B45, 0x8B45}, {0x8B46, 0x8B46}, + {0x8B47, 0x8B47}, {0x8B48, 0x8B48}, {0x8B49, 0x8B49}, {0x8B4A, 0x8B4A}, {0x8B4B, 0x8B4B}, {0x8B4C, 0x8B4C}, {0x8B4D, 0x8B4D}, + {0x8B4E, 0x8B4E}, {0x8B4F, 0x8B4F}, {0x8B50, 0x8B50}, {0x8B51, 0x8B51}, {0x8B52, 0x8B52}, {0x8B53, 0x8B53}, {0x8B54, 0x8B54}, + {0x8B55, 0x8B55}, {0x8B56, 0x8B56}, {0x8B57, 0x8B57}, {0x8B58, 0x8B58}, {0x8B59, 0x8B59}, {0x8B5A, 0x8B5A}, {0x8B5B, 0x8B5B}, + {0x8B5C, 0x8B5C}, {0x8B5D, 0x8B5D}, {0x8B5E, 0x8B5E}, {0x8B5F, 0x8B5F}, {0x8B60, 0x8B60}, {0x8B61, 0x8B61}, {0x8B62, 0x8B62}, + {0x8B63, 0x8B63}, {0x8B64, 0x8B64}, {0x8B65, 0x8B65}, {0x8B66, 0x8B66}, {0x8B67, 0x8B67}, {0x8B68, 0x8B68}, {0x8B69, 0x8B69}, + {0x8B6A, 0x8B6A}, {0x8B6B, 0x8B6B}, {0x8B6C, 0x8B6C}, {0x8B6D, 0x8B6D}, {0x8B6E, 0x8B6E}, {0x8B6F, 0x8B6F}, {0x8B70, 0x8B70}, + {0x8B71, 0x8B71}, {0x8B72, 0x8B72}, {0x8B73, 0x8B73}, {0x8B74, 0x8B74}, {0x8B75, 0x8B75}, {0x8B76, 0x8B76}, {0x8B77, 0x8B77}, + {0x8B78, 0x8B78}, {0x8B79, 0x8B79}, {0x8B7A, 0x8B7A}, {0x8B7B, 0x8B7B}, {0x8B7C, 0x8B7C}, {0x8B7D, 0x8B7D}, {0x8B7E, 0x8B7E}, + {0x8B7F, 0x8B7F}, {0x8B80, 0x8B80}, {0x8B81, 0x8B81}, {0x8B82, 0x8B82}, {0x8B83, 0x8B83}, {0x8B84, 0x8B84}, {0x8B85, 0x8B85}, + {0x8B86, 0x8B86}, {0x8B87, 0x8B87}, {0x8B88, 0x8B88}, {0x8B89, 0x8B89}, {0x8B8A, 0x8B8A}, {0x8B8B, 0x8B8B}, {0x8B8C, 0x8B8C}, + {0x8B8D, 0x8B8D}, {0x8B8E, 0x8B8E}, {0x8B8F, 0x8B8F}, {0x8B90, 0x8B90}, {0x8B91, 0x8B91}, {0x8B92, 0x8B92}, {0x8B93, 0x8B93}, + {0x8B94, 0x8B94}, {0x8B95, 0x8B95}, {0x8B96, 0x8B96}, {0x8B97, 0x8B97}, {0x8B98, 0x8B98}, {0x8B99, 0x8B99}, {0x8B9A, 0x8B9A}, + {0x8B9B, 0x8B9B}, {0x8B9C, 0x8B9C}, {0x8B9D, 0x8B9D}, {0x8B9E, 0x8B9E}, {0x8B9F, 0x8B9F}, {0x8BA0, 0x8BA0}, {0x8BA1, 0x8BA1}, + {0x8BA2, 0x8BA2}, {0x8BA3, 0x8BA3}, {0x8BA4, 0x8BA4}, {0x8BA5, 0x8BA5}, {0x8BA6, 0x8BA6}, {0x8BA7, 0x8BA7}, {0x8BA8, 0x8BA8}, + {0x8BA9, 0x8BA9}, {0x8BAA, 0x8BAA}, {0x8BAB, 0x8BAB}, {0x8BAC, 0x8BAC}, {0x8BAD, 0x8BAD}, {0x8BAE, 0x8BAE}, {0x8BAF, 0x8BAF}, + {0x8BB0, 0x8BB0}, {0x8BB1, 0x8BB1}, {0x8BB2, 0x8BB2}, {0x8BB3, 0x8BB3}, {0x8BB4, 0x8BB4}, {0x8BB5, 0x8BB5}, {0x8BB6, 0x8BB6}, + {0x8BB7, 0x8BB7}, {0x8BB8, 0x8BB8}, {0x8BB9, 0x8BB9}, {0x8BBA, 0x8BBA}, {0x8BBB, 0x8BBB}, {0x8BBC, 0x8BBC}, {0x8BBD, 0x8BBD}, + {0x8BBE, 0x8BBE}, {0x8BBF, 0x8BBF}, {0x8BC0, 0x8BC0}, {0x8BC1, 0x8BC1}, {0x8BC2, 0x8BC2}, {0x8BC3, 0x8BC3}, {0x8BC4, 0x8BC4}, + {0x8BC5, 0x8BC5}, {0x8BC6, 0x8BC6}, {0x8BC7, 0x8BC7}, {0x8BC8, 0x8BC8}, {0x8BC9, 0x8BC9}, {0x8BCA, 0x8BCA}, {0x8BCB, 0x8BCB}, + {0x8BCC, 0x8BCC}, {0x8BCD, 0x8BCD}, {0x8BCE, 0x8BCE}, {0x8BCF, 0x8BCF}, {0x8BD0, 0x8BD0}, {0x8BD1, 0x8BD1}, {0x8BD2, 0x8BD2}, + {0x8BD3, 0x8BD3}, {0x8BD4, 0x8BD4}, {0x8BD5, 0x8BD5}, {0x8BD6, 0x8BD6}, {0x8BD7, 0x8BD7}, {0x8BD8, 0x8BD8}, {0x8BD9, 0x8BD9}, + {0x8BDA, 0x8BDA}, {0x8BDB, 0x8BDB}, {0x8BDC, 0x8BDC}, {0x8BDD, 0x8BDD}, {0x8BDE, 0x8BDE}, {0x8BDF, 0x8BDF}, {0x8BE0, 0x8BE0}, + {0x8BE1, 0x8BE1}, {0x8BE2, 0x8BE2}, {0x8BE3, 0x8BE3}, {0x8BE4, 0x8BE4}, {0x8BE5, 0x8BE5}, {0x8BE6, 0x8BE6}, {0x8BE7, 0x8BE7}, + {0x8BE8, 0x8BE8}, {0x8BE9, 0x8BE9}, {0x8BEA, 0x8BEA}, {0x8BEB, 0x8BEB}, {0x8BEC, 0x8BEC}, {0x8BED, 0x8BED}, {0x8BEE, 0x8BEE}, + {0x8BEF, 0x8BEF}, {0x8BF0, 0x8BF0}, {0x8BF1, 0x8BF1}, {0x8BF2, 0x8BF2}, {0x8BF3, 0x8BF3}, {0x8BF4, 0x8BF4}, {0x8BF5, 0x8BF5}, + {0x8BF6, 0x8BF6}, {0x8BF7, 0x8BF7}, {0x8BF8, 0x8BF8}, {0x8BF9, 0x8BF9}, {0x8BFA, 0x8BFA}, {0x8BFB, 0x8BFB}, {0x8BFC, 0x8BFC}, + {0x8BFD, 0x8BFD}, {0x8BFE, 0x8BFE}, {0x8BFF, 0x8BFF}, {0x8C00, 0x8C00}, {0x8C01, 0x8C01}, {0x8C02, 0x8C02}, {0x8C03, 0x8C03}, + {0x8C04, 0x8C04}, {0x8C05, 0x8C05}, {0x8C06, 0x8C06}, {0x8C07, 0x8C07}, {0x8C08, 0x8C08}, {0x8C09, 0x8C09}, {0x8C0A, 0x8C0A}, + {0x8C0B, 0x8C0B}, {0x8C0C, 0x8C0C}, {0x8C0D, 0x8C0D}, {0x8C0E, 0x8C0E}, {0x8C0F, 0x8C0F}, {0x8C10, 0x8C10}, {0x8C11, 0x8C11}, + {0x8C12, 0x8C12}, {0x8C13, 0x8C13}, {0x8C14, 0x8C14}, {0x8C15, 0x8C15}, {0x8C16, 0x8C16}, {0x8C17, 0x8C17}, {0x8C18, 0x8C18}, + {0x8C19, 0x8C19}, {0x8C1A, 0x8C1A}, {0x8C1B, 0x8C1B}, {0x8C1C, 0x8C1C}, {0x8C1D, 0x8C1D}, {0x8C1E, 0x8C1E}, {0x8C1F, 0x8C1F}, + {0x8C20, 0x8C20}, {0x8C21, 0x8C21}, {0x8C22, 0x8C22}, {0x8C23, 0x8C23}, {0x8C24, 0x8C24}, {0x8C25, 0x8C25}, {0x8C26, 0x8C26}, + {0x8C27, 0x8C27}, {0x8C28, 0x8C28}, {0x8C29, 0x8C29}, {0x8C2A, 0x8C2A}, {0x8C2B, 0x8C2B}, {0x8C2C, 0x8C2C}, {0x8C2D, 0x8C2D}, + {0x8C2E, 0x8C2E}, {0x8C2F, 0x8C2F}, {0x8C30, 0x8C30}, {0x8C31, 0x8C31}, {0x8C32, 0x8C32}, {0x8C33, 0x8C33}, {0x8C34, 0x8C34}, + {0x8C35, 0x8C35}, {0x8C36, 0x8C36}, {0x8C37, 0x8C37}, {0x8C38, 0x8C38}, {0x8C39, 0x8C39}, {0x8C3A, 0x8C3A}, {0x8C3B, 0x8C3B}, + {0x8C3C, 0x8C3C}, {0x8C3D, 0x8C3D}, {0x8C3E, 0x8C3E}, {0x8C3F, 0x8C3F}, {0x8C40, 0x8C40}, {0x8C41, 0x8C41}, {0x8C42, 0x8C42}, + {0x8C43, 0x8C43}, {0x8C44, 0x8C44}, {0x8C45, 0x8C45}, {0x8C46, 0x8C46}, {0x8C47, 0x8C47}, {0x8C48, 0x8C48}, {0x8C49, 0x8C49}, + {0x8C4A, 0x8C4A}, {0x8C4B, 0x8C4B}, {0x8C4C, 0x8C4C}, {0x8C4D, 0x8C4D}, {0x8C4E, 0x8C4E}, {0x8C4F, 0x8C4F}, {0x8C50, 0x8C50}, + {0x8C51, 0x8C51}, {0x8C52, 0x8C52}, {0x8C53, 0x8C53}, {0x8C54, 0x8C54}, {0x8C55, 0x8C55}, {0x8C56, 0x8C56}, {0x8C57, 0x8C57}, + {0x8C58, 0x8C58}, {0x8C59, 0x8C59}, {0x8C5A, 0x8C5A}, {0x8C5B, 0x8C5B}, {0x8C5C, 0x8C5C}, {0x8C5D, 0x8C5D}, {0x8C5E, 0x8C5E}, + {0x8C5F, 0x8C5F}, {0x8C60, 0x8C60}, {0x8C61, 0x8C61}, {0x8C62, 0x8C62}, {0x8C63, 0x8C63}, {0x8C64, 0x8C64}, {0x8C65, 0x8C65}, + {0x8C66, 0x8C66}, {0x8C67, 0x8C67}, {0x8C68, 0x8C68}, {0x8C69, 0x8C69}, {0x8C6A, 0x8C6A}, {0x8C6B, 0x8C6B}, {0x8C6C, 0x8C6C}, + {0x8C6D, 0x8C6D}, {0x8C6E, 0x8C6E}, {0x8C6F, 0x8C6F}, {0x8C70, 0x8C70}, {0x8C71, 0x8C71}, {0x8C72, 0x8C72}, {0x8C73, 0x8C73}, + {0x8C74, 0x8C74}, {0x8C75, 0x8C75}, {0x8C76, 0x8C76}, {0x8C77, 0x8C77}, {0x8C78, 0x8C78}, {0x8C79, 0x8C79}, {0x8C7A, 0x8C7A}, + {0x8C7B, 0x8C7B}, {0x8C7C, 0x8C7C}, {0x8C7D, 0x8C7D}, {0x8C7E, 0x8C7E}, {0x8C7F, 0x8C7F}, {0x8C80, 0x8C80}, {0x8C81, 0x8C81}, + {0x8C82, 0x8C82}, {0x8C83, 0x8C83}, {0x8C84, 0x8C84}, {0x8C85, 0x8C85}, {0x8C86, 0x8C86}, {0x8C87, 0x8C87}, {0x8C88, 0x8C88}, + {0x8C89, 0x8C89}, {0x8C8A, 0x8C8A}, {0x8C8B, 0x8C8B}, {0x8C8C, 0x8C8C}, {0x8C8D, 0x8C8D}, {0x8C8E, 0x8C8E}, {0x8C8F, 0x8C8F}, + {0x8C90, 0x8C90}, {0x8C91, 0x8C91}, {0x8C92, 0x8C92}, {0x8C93, 0x8C93}, {0x8C94, 0x8C94}, {0x8C95, 0x8C95}, {0x8C96, 0x8C96}, + {0x8C97, 0x8C97}, {0x8C98, 0x8C98}, {0x8C99, 0x8C99}, {0x8C9A, 0x8C9A}, {0x8C9B, 0x8C9B}, {0x8C9C, 0x8C9C}, {0x8C9D, 0x8C9D}, + {0x8C9E, 0x8C9E}, {0x8C9F, 0x8C9F}, {0x8CA0, 0x8CA0}, {0x8CA1, 0x8CA1}, {0x8CA2, 0x8CA2}, {0x8CA3, 0x8CA3}, {0x8CA4, 0x8CA4}, + {0x8CA5, 0x8CA5}, {0x8CA6, 0x8CA6}, {0x8CA7, 0x8CA7}, {0x8CA8, 0x8CA8}, {0x8CA9, 0x8CA9}, {0x8CAA, 0x8CAA}, {0x8CAB, 0x8CAB}, + {0x8CAC, 0x8CAC}, {0x8CAD, 0x8CAD}, {0x8CAE, 0x8CAE}, {0x8CAF, 0x8CAF}, {0x8CB0, 0x8CB0}, {0x8CB1, 0x8CB1}, {0x8CB2, 0x8CB2}, + {0x8CB3, 0x8CB3}, {0x8CB4, 0x8CB4}, {0x8CB5, 0x8CB5}, {0x8CB6, 0x8CB6}, {0x8CB7, 0x8CB7}, {0x8CB8, 0x8CB8}, {0x8CB9, 0x8CB9}, + {0x8CBA, 0x8CBA}, {0x8CBB, 0x8CBB}, {0x8CBC, 0x8CBC}, {0x8CBD, 0x8CBD}, {0x8CBE, 0x8CBE}, {0x8CBF, 0x8CBF}, {0x8CC0, 0x8CC0}, + {0x8CC1, 0x8CC1}, {0x8CC2, 0x8CC2}, {0x8CC3, 0x8CC3}, {0x8CC4, 0x8CC4}, {0x8CC5, 0x8CC5}, {0x8CC6, 0x8CC6}, {0x8CC7, 0x8CC7}, + {0x8CC8, 0x8CC8}, {0x8CC9, 0x8CC9}, {0x8CCA, 0x8CCA}, {0x8CCB, 0x8CCB}, {0x8CCC, 0x8CCC}, {0x8CCD, 0x8CCD}, {0x8CCE, 0x8CCE}, + {0x8CCF, 0x8CCF}, {0x8CD0, 0x8CD0}, {0x8CD1, 0x8CD1}, {0x8CD2, 0x8CD2}, {0x8CD3, 0x8CD3}, {0x8CD4, 0x8CD4}, {0x8CD5, 0x8CD5}, + {0x8CD6, 0x8CD6}, {0x8CD7, 0x8CD7}, {0x8CD8, 0x8CD8}, {0x8CD9, 0x8CD9}, {0x8CDA, 0x8CDA}, {0x8CDB, 0x8CDB}, {0x8CDC, 0x8CDC}, + {0x8CDD, 0x8CDD}, {0x8CDE, 0x8CDE}, {0x8CDF, 0x8CDF}, {0x8CE0, 0x8CE0}, {0x8CE1, 0x8CE1}, {0x8CE2, 0x8CE2}, {0x8CE3, 0x8CE3}, + {0x8CE4, 0x8CE4}, {0x8CE5, 0x8CE5}, {0x8CE6, 0x8CE6}, {0x8CE7, 0x8CE7}, {0x8CE8, 0x8CE8}, {0x8CE9, 0x8CE9}, {0x8CEA, 0x8CEA}, + {0x8CEB, 0x8CEB}, {0x8CEC, 0x8CEC}, {0x8CED, 0x8CED}, {0x8CEE, 0x8CEE}, {0x8CEF, 0x8CEF}, {0x8CF0, 0x8CF0}, {0x8CF1, 0x8CF1}, + {0x8CF2, 0x8CF2}, {0x8CF3, 0x8CF3}, {0x8CF4, 0x8CF4}, {0x8CF5, 0x8CF5}, {0x8CF6, 0x8CF6}, {0x8CF7, 0x8CF7}, {0x8CF8, 0x8CF8}, + {0x8CF9, 0x8CF9}, {0x8CFA, 0x8CFA}, {0x8CFB, 0x8CFB}, {0x8CFC, 0x8CFC}, {0x8CFD, 0x8CFD}, {0x8CFE, 0x8CFE}, {0x8CFF, 0x8CFF}, + {0x8D00, 0x8D00}, {0x8D01, 0x8D01}, {0x8D02, 0x8D02}, {0x8D03, 0x8D03}, {0x8D04, 0x8D04}, {0x8D05, 0x8D05}, {0x8D06, 0x8D06}, + {0x8D07, 0x8D07}, {0x8D08, 0x8D08}, {0x8D09, 0x8D09}, {0x8D0A, 0x8D0A}, {0x8D0B, 0x8D0B}, {0x8D0C, 0x8D0C}, {0x8D0D, 0x8D0D}, + {0x8D0E, 0x8D0E}, {0x8D0F, 0x8D0F}, {0x8D10, 0x8D10}, {0x8D11, 0x8D11}, {0x8D12, 0x8D12}, {0x8D13, 0x8D13}, {0x8D14, 0x8D14}, + {0x8D15, 0x8D15}, {0x8D16, 0x8D16}, {0x8D17, 0x8D17}, {0x8D18, 0x8D18}, {0x8D19, 0x8D19}, {0x8D1A, 0x8D1A}, {0x8D1B, 0x8D1B}, + {0x8D1C, 0x8D1C}, {0x8D1D, 0x8D1D}, {0x8D1E, 0x8D1E}, {0x8D1F, 0x8D1F}, {0x8D20, 0x8D20}, {0x8D21, 0x8D21}, {0x8D22, 0x8D22}, + {0x8D23, 0x8D23}, {0x8D24, 0x8D24}, {0x8D25, 0x8D25}, {0x8D26, 0x8D26}, {0x8D27, 0x8D27}, {0x8D28, 0x8D28}, {0x8D29, 0x8D29}, + {0x8D2A, 0x8D2A}, {0x8D2B, 0x8D2B}, {0x8D2C, 0x8D2C}, {0x8D2D, 0x8D2D}, {0x8D2E, 0x8D2E}, {0x8D2F, 0x8D2F}, {0x8D30, 0x8D30}, + {0x8D31, 0x8D31}, {0x8D32, 0x8D32}, {0x8D33, 0x8D33}, {0x8D34, 0x8D34}, {0x8D35, 0x8D35}, {0x8D36, 0x8D36}, {0x8D37, 0x8D37}, + {0x8D38, 0x8D38}, {0x8D39, 0x8D39}, {0x8D3A, 0x8D3A}, {0x8D3B, 0x8D3B}, {0x8D3C, 0x8D3C}, {0x8D3D, 0x8D3D}, {0x8D3E, 0x8D3E}, + {0x8D3F, 0x8D3F}, {0x8D40, 0x8D40}, {0x8D41, 0x8D41}, {0x8D42, 0x8D42}, {0x8D43, 0x8D43}, {0x8D44, 0x8D44}, {0x8D45, 0x8D45}, + {0x8D46, 0x8D46}, {0x8D47, 0x8D47}, {0x8D48, 0x8D48}, {0x8D49, 0x8D49}, {0x8D4A, 0x8D4A}, {0x8D4B, 0x8D4B}, {0x8D4C, 0x8D4C}, + {0x8D4D, 0x8D4D}, {0x8D4E, 0x8D4E}, {0x8D4F, 0x8D4F}, {0x8D50, 0x8D50}, {0x8D51, 0x8D51}, {0x8D52, 0x8D52}, {0x8D53, 0x8D53}, + {0x8D54, 0x8D54}, {0x8D55, 0x8D55}, {0x8D56, 0x8D56}, {0x8D57, 0x8D57}, {0x8D58, 0x8D58}, {0x8D59, 0x8D59}, {0x8D5A, 0x8D5A}, + {0x8D5B, 0x8D5B}, {0x8D5C, 0x8D5C}, {0x8D5D, 0x8D5D}, {0x8D5E, 0x8D5E}, {0x8D5F, 0x8D5F}, {0x8D60, 0x8D60}, {0x8D61, 0x8D61}, + {0x8D62, 0x8D62}, {0x8D63, 0x8D63}, {0x8D64, 0x8D64}, {0x8D65, 0x8D65}, {0x8D66, 0x8D66}, {0x8D67, 0x8D67}, {0x8D68, 0x8D68}, + {0x8D69, 0x8D69}, {0x8D6A, 0x8D6A}, {0x8D6B, 0x8D6B}, {0x8D6C, 0x8D6C}, {0x8D6D, 0x8D6D}, {0x8D6E, 0x8D6E}, {0x8D6F, 0x8D6F}, + {0x8D70, 0x8D70}, {0x8D71, 0x8D71}, {0x8D72, 0x8D72}, {0x8D73, 0x8D73}, {0x8D74, 0x8D74}, {0x8D75, 0x8D75}, {0x8D76, 0x8D76}, + {0x8D77, 0x8D77}, {0x8D78, 0x8D78}, {0x8D79, 0x8D79}, {0x8D7A, 0x8D7A}, {0x8D7B, 0x8D7B}, {0x8D7C, 0x8D7C}, {0x8D7D, 0x8D7D}, + {0x8D7E, 0x8D7E}, {0x8D7F, 0x8D7F}, {0x8D80, 0x8D80}, {0x8D81, 0x8D81}, {0x8D82, 0x8D82}, {0x8D83, 0x8D83}, {0x8D84, 0x8D84}, + {0x8D85, 0x8D85}, {0x8D86, 0x8D86}, {0x8D87, 0x8D87}, {0x8D88, 0x8D88}, {0x8D89, 0x8D89}, {0x8D8A, 0x8D8A}, {0x8D8B, 0x8D8B}, + {0x8D8C, 0x8D8C}, {0x8D8D, 0x8D8D}, {0x8D8E, 0x8D8E}, {0x8D8F, 0x8D8F}, {0x8D90, 0x8D90}, {0x8D91, 0x8D91}, {0x8D92, 0x8D92}, + {0x8D93, 0x8D93}, {0x8D94, 0x8D94}, {0x8D95, 0x8D95}, {0x8D96, 0x8D96}, {0x8D97, 0x8D97}, {0x8D98, 0x8D98}, {0x8D99, 0x8D99}, + {0x8D9A, 0x8D9A}, {0x8D9B, 0x8D9B}, {0x8D9C, 0x8D9C}, {0x8D9D, 0x8D9D}, {0x8D9E, 0x8D9E}, {0x8D9F, 0x8D9F}, {0x8DA0, 0x8DA0}, + {0x8DA1, 0x8DA1}, {0x8DA2, 0x8DA2}, {0x8DA3, 0x8DA3}, {0x8DA4, 0x8DA4}, {0x8DA5, 0x8DA5}, {0x8DA6, 0x8DA6}, {0x8DA7, 0x8DA7}, + {0x8DA8, 0x8DA8}, {0x8DA9, 0x8DA9}, {0x8DAA, 0x8DAA}, {0x8DAB, 0x8DAB}, {0x8DAC, 0x8DAC}, {0x8DAD, 0x8DAD}, {0x8DAE, 0x8DAE}, + {0x8DAF, 0x8DAF}, {0x8DB0, 0x8DB0}, {0x8DB1, 0x8DB1}, {0x8DB2, 0x8DB2}, {0x8DB3, 0x8DB3}, {0x8DB4, 0x8DB4}, {0x8DB5, 0x8DB5}, + {0x8DB6, 0x8DB6}, {0x8DB7, 0x8DB7}, {0x8DB8, 0x8DB8}, {0x8DB9, 0x8DB9}, {0x8DBA, 0x8DBA}, {0x8DBB, 0x8DBB}, {0x8DBC, 0x8DBC}, + {0x8DBD, 0x8DBD}, {0x8DBE, 0x8DBE}, {0x8DBF, 0x8DBF}, {0x8DC0, 0x8DC0}, {0x8DC1, 0x8DC1}, {0x8DC2, 0x8DC2}, {0x8DC3, 0x8DC3}, + {0x8DC4, 0x8DC4}, {0x8DC5, 0x8DC5}, {0x8DC6, 0x8DC6}, {0x8DC7, 0x8DC7}, {0x8DC8, 0x8DC8}, {0x8DC9, 0x8DC9}, {0x8DCA, 0x8DCA}, + {0x8DCB, 0x8DCB}, {0x8DCC, 0x8DCC}, {0x8DCD, 0x8DCD}, {0x8DCE, 0x8DCE}, {0x8DCF, 0x8DCF}, {0x8DD0, 0x8DD0}, {0x8DD1, 0x8DD1}, + {0x8DD2, 0x8DD2}, {0x8DD3, 0x8DD3}, {0x8DD4, 0x8DD4}, {0x8DD5, 0x8DD5}, {0x8DD6, 0x8DD6}, {0x8DD7, 0x8DD7}, {0x8DD8, 0x8DD8}, + {0x8DD9, 0x8DD9}, {0x8DDA, 0x8DDA}, {0x8DDB, 0x8DDB}, {0x8DDC, 0x8DDC}, {0x8DDD, 0x8DDD}, {0x8DDE, 0x8DDE}, {0x8DDF, 0x8DDF}, + {0x8DE0, 0x8DE0}, {0x8DE1, 0x8DE1}, {0x8DE2, 0x8DE2}, {0x8DE3, 0x8DE3}, {0x8DE4, 0x8DE4}, {0x8DE5, 0x8DE5}, {0x8DE6, 0x8DE6}, + {0x8DE7, 0x8DE7}, {0x8DE8, 0x8DE8}, {0x8DE9, 0x8DE9}, {0x8DEA, 0x8DEA}, {0x8DEB, 0x8DEB}, {0x8DEC, 0x8DEC}, {0x8DED, 0x8DED}, + {0x8DEE, 0x8DEE}, {0x8DEF, 0x8DEF}, {0x8DF0, 0x8DF0}, {0x8DF1, 0x8DF1}, {0x8DF2, 0x8DF2}, {0x8DF3, 0x8DF3}, {0x8DF4, 0x8DF4}, + {0x8DF5, 0x8DF5}, {0x8DF6, 0x8DF6}, {0x8DF7, 0x8DF7}, {0x8DF8, 0x8DF8}, {0x8DF9, 0x8DF9}, {0x8DFA, 0x8DFA}, {0x8DFB, 0x8DFB}, + {0x8DFC, 0x8DFC}, {0x8DFD, 0x8DFD}, {0x8DFE, 0x8DFE}, {0x8DFF, 0x8DFF}, {0x8E00, 0x8E00}, {0x8E01, 0x8E01}, {0x8E02, 0x8E02}, + {0x8E03, 0x8E03}, {0x8E04, 0x8E04}, {0x8E05, 0x8E05}, {0x8E06, 0x8E06}, {0x8E07, 0x8E07}, {0x8E08, 0x8E08}, {0x8E09, 0x8E09}, + {0x8E0A, 0x8E0A}, {0x8E0B, 0x8E0B}, {0x8E0C, 0x8E0C}, {0x8E0D, 0x8E0D}, {0x8E0E, 0x8E0E}, {0x8E0F, 0x8E0F}, {0x8E10, 0x8E10}, + {0x8E11, 0x8E11}, {0x8E12, 0x8E12}, {0x8E13, 0x8E13}, {0x8E14, 0x8E14}, {0x8E15, 0x8E15}, {0x8E16, 0x8E16}, {0x8E17, 0x8E17}, + {0x8E18, 0x8E18}, {0x8E19, 0x8E19}, {0x8E1A, 0x8E1A}, {0x8E1B, 0x8E1B}, {0x8E1C, 0x8E1C}, {0x8E1D, 0x8E1D}, {0x8E1E, 0x8E1E}, + {0x8E1F, 0x8E1F}, {0x8E20, 0x8E20}, {0x8E21, 0x8E21}, {0x8E22, 0x8E22}, {0x8E23, 0x8E23}, {0x8E24, 0x8E24}, {0x8E25, 0x8E25}, + {0x8E26, 0x8E26}, {0x8E27, 0x8E27}, {0x8E28, 0x8E28}, {0x8E29, 0x8E29}, {0x8E2A, 0x8E2A}, {0x8E2B, 0x8E2B}, {0x8E2C, 0x8E2C}, + {0x8E2D, 0x8E2D}, {0x8E2E, 0x8E2E}, {0x8E2F, 0x8E2F}, {0x8E30, 0x8E30}, {0x8E31, 0x8E31}, {0x8E32, 0x8E32}, {0x8E33, 0x8E33}, + {0x8E34, 0x8E34}, {0x8E35, 0x8E35}, {0x8E36, 0x8E36}, {0x8E37, 0x8E37}, {0x8E38, 0x8E38}, {0x8E39, 0x8E39}, {0x8E3A, 0x8E3A}, + {0x8E3B, 0x8E3B}, {0x8E3C, 0x8E3C}, {0x8E3D, 0x8E3D}, {0x8E3E, 0x8E3E}, {0x8E3F, 0x8E3F}, {0x8E40, 0x8E40}, {0x8E41, 0x8E41}, + {0x8E42, 0x8E42}, {0x8E43, 0x8E43}, {0x8E44, 0x8E44}, {0x8E45, 0x8E45}, {0x8E46, 0x8E46}, {0x8E47, 0x8E47}, {0x8E48, 0x8E48}, + {0x8E49, 0x8E49}, {0x8E4A, 0x8E4A}, {0x8E4B, 0x8E4B}, {0x8E4C, 0x8E4C}, {0x8E4D, 0x8E4D}, {0x8E4E, 0x8E4E}, {0x8E4F, 0x8E4F}, + {0x8E50, 0x8E50}, {0x8E51, 0x8E51}, {0x8E52, 0x8E52}, {0x8E53, 0x8E53}, {0x8E54, 0x8E54}, {0x8E55, 0x8E55}, {0x8E56, 0x8E56}, + {0x8E57, 0x8E57}, {0x8E58, 0x8E58}, {0x8E59, 0x8E59}, {0x8E5A, 0x8E5A}, {0x8E5B, 0x8E5B}, {0x8E5C, 0x8E5C}, {0x8E5D, 0x8E5D}, + {0x8E5E, 0x8E5E}, {0x8E5F, 0x8E5F}, {0x8E60, 0x8E60}, {0x8E61, 0x8E61}, {0x8E62, 0x8E62}, {0x8E63, 0x8E63}, {0x8E64, 0x8E64}, + {0x8E65, 0x8E65}, {0x8E66, 0x8E66}, {0x8E67, 0x8E67}, {0x8E68, 0x8E68}, {0x8E69, 0x8E69}, {0x8E6A, 0x8E6A}, {0x8E6B, 0x8E6B}, + {0x8E6C, 0x8E6C}, {0x8E6D, 0x8E6D}, {0x8E6E, 0x8E6E}, {0x8E6F, 0x8E6F}, {0x8E70, 0x8E70}, {0x8E71, 0x8E71}, {0x8E72, 0x8E72}, + {0x8E73, 0x8E73}, {0x8E74, 0x8E74}, {0x8E75, 0x8E75}, {0x8E76, 0x8E76}, {0x8E77, 0x8E77}, {0x8E78, 0x8E78}, {0x8E79, 0x8E79}, + {0x8E7A, 0x8E7A}, {0x8E7B, 0x8E7B}, {0x8E7C, 0x8E7C}, {0x8E7D, 0x8E7D}, {0x8E7E, 0x8E7E}, {0x8E7F, 0x8E7F}, {0x8E80, 0x8E80}, + {0x8E81, 0x8E81}, {0x8E82, 0x8E82}, {0x8E83, 0x8E83}, {0x8E84, 0x8E84}, {0x8E85, 0x8E85}, {0x8E86, 0x8E86}, {0x8E87, 0x8E87}, + {0x8E88, 0x8E88}, {0x8E89, 0x8E89}, {0x8E8A, 0x8E8A}, {0x8E8B, 0x8E8B}, {0x8E8C, 0x8E8C}, {0x8E8D, 0x8E8D}, {0x8E8E, 0x8E8E}, + {0x8E8F, 0x8E8F}, {0x8E90, 0x8E90}, {0x8E91, 0x8E91}, {0x8E92, 0x8E92}, {0x8E93, 0x8E93}, {0x8E94, 0x8E94}, {0x8E95, 0x8E95}, + {0x8E96, 0x8E96}, {0x8E97, 0x8E97}, {0x8E98, 0x8E98}, {0x8E99, 0x8E99}, {0x8E9A, 0x8E9A}, {0x8E9B, 0x8E9B}, {0x8E9C, 0x8E9C}, + {0x8E9D, 0x8E9D}, {0x8E9E, 0x8E9E}, {0x8E9F, 0x8E9F}, {0x8EA0, 0x8EA0}, {0x8EA1, 0x8EA1}, {0x8EA2, 0x8EA2}, {0x8EA3, 0x8EA3}, + {0x8EA4, 0x8EA4}, {0x8EA5, 0x8EA5}, {0x8EA6, 0x8EA6}, {0x8EA7, 0x8EA7}, {0x8EA8, 0x8EA8}, {0x8EA9, 0x8EA9}, {0x8EAA, 0x8EAA}, + {0x8EAB, 0x8EAB}, {0x8EAC, 0x8EAC}, {0x8EAD, 0x8EAD}, {0x8EAE, 0x8EAE}, {0x8EAF, 0x8EAF}, {0x8EB0, 0x8EB0}, {0x8EB1, 0x8EB1}, + {0x8EB2, 0x8EB2}, {0x8EB3, 0x8EB3}, {0x8EB4, 0x8EB4}, {0x8EB5, 0x8EB5}, {0x8EB6, 0x8EB6}, {0x8EB7, 0x8EB7}, {0x8EB8, 0x8EB8}, + {0x8EB9, 0x8EB9}, {0x8EBA, 0x8EBA}, {0x8EBB, 0x8EBB}, {0x8EBC, 0x8EBC}, {0x8EBD, 0x8EBD}, {0x8EBE, 0x8EBE}, {0x8EBF, 0x8EBF}, + {0x8EC0, 0x8EC0}, {0x8EC1, 0x8EC1}, {0x8EC2, 0x8EC2}, {0x8EC3, 0x8EC3}, {0x8EC4, 0x8EC4}, {0x8EC5, 0x8EC5}, {0x8EC6, 0x8EC6}, + {0x8EC7, 0x8EC7}, {0x8EC8, 0x8EC8}, {0x8EC9, 0x8EC9}, {0x8ECA, 0x8ECA}, {0x8ECB, 0x8ECB}, {0x8ECC, 0x8ECC}, {0x8ECD, 0x8ECD}, + {0x8ECE, 0x8ECE}, {0x8ECF, 0x8ECF}, {0x8ED0, 0x8ED0}, {0x8ED1, 0x8ED1}, {0x8ED2, 0x8ED2}, {0x8ED3, 0x8ED3}, {0x8ED4, 0x8ED4}, + {0x8ED5, 0x8ED5}, {0x8ED6, 0x8ED6}, {0x8ED7, 0x8ED7}, {0x8ED8, 0x8ED8}, {0x8ED9, 0x8ED9}, {0x8EDA, 0x8EDA}, {0x8EDB, 0x8EDB}, + {0x8EDC, 0x8EDC}, {0x8EDD, 0x8EDD}, {0x8EDE, 0x8EDE}, {0x8EDF, 0x8EDF}, {0x8EE0, 0x8EE0}, {0x8EE1, 0x8EE1}, {0x8EE2, 0x8EE2}, + {0x8EE3, 0x8EE3}, {0x8EE4, 0x8EE4}, {0x8EE5, 0x8EE5}, {0x8EE6, 0x8EE6}, {0x8EE7, 0x8EE7}, {0x8EE8, 0x8EE8}, {0x8EE9, 0x8EE9}, + {0x8EEA, 0x8EEA}, {0x8EEB, 0x8EEB}, {0x8EEC, 0x8EEC}, {0x8EED, 0x8EED}, {0x8EEE, 0x8EEE}, {0x8EEF, 0x8EEF}, {0x8EF0, 0x8EF0}, + {0x8EF1, 0x8EF1}, {0x8EF2, 0x8EF2}, {0x8EF3, 0x8EF3}, {0x8EF4, 0x8EF4}, {0x8EF5, 0x8EF5}, {0x8EF6, 0x8EF6}, {0x8EF7, 0x8EF7}, + {0x8EF8, 0x8EF8}, {0x8EF9, 0x8EF9}, {0x8EFA, 0x8EFA}, {0x8EFB, 0x8EFB}, {0x8EFC, 0x8EFC}, {0x8EFD, 0x8EFD}, {0x8EFE, 0x8EFE}, + {0x8EFF, 0x8EFF}, {0x8F00, 0x8F00}, {0x8F01, 0x8F01}, {0x8F02, 0x8F02}, {0x8F03, 0x8F03}, {0x8F04, 0x8F04}, {0x8F05, 0x8F05}, + {0x8F06, 0x8F06}, {0x8F07, 0x8F07}, {0x8F08, 0x8F08}, {0x8F09, 0x8F09}, {0x8F0A, 0x8F0A}, {0x8F0B, 0x8F0B}, {0x8F0C, 0x8F0C}, + {0x8F0D, 0x8F0D}, {0x8F0E, 0x8F0E}, {0x8F0F, 0x8F0F}, {0x8F10, 0x8F10}, {0x8F11, 0x8F11}, {0x8F12, 0x8F12}, {0x8F13, 0x8F13}, + {0x8F14, 0x8F14}, {0x8F15, 0x8F15}, {0x8F16, 0x8F16}, {0x8F17, 0x8F17}, {0x8F18, 0x8F18}, {0x8F19, 0x8F19}, {0x8F1A, 0x8F1A}, + {0x8F1B, 0x8F1B}, {0x8F1C, 0x8F1C}, {0x8F1D, 0x8F1D}, {0x8F1E, 0x8F1E}, {0x8F1F, 0x8F1F}, {0x8F20, 0x8F20}, {0x8F21, 0x8F21}, + {0x8F22, 0x8F22}, {0x8F23, 0x8F23}, {0x8F24, 0x8F24}, {0x8F25, 0x8F25}, {0x8F26, 0x8F26}, {0x8F27, 0x8F27}, {0x8F28, 0x8F28}, + {0x8F29, 0x8F29}, {0x8F2A, 0x8F2A}, {0x8F2B, 0x8F2B}, {0x8F2C, 0x8F2C}, {0x8F2D, 0x8F2D}, {0x8F2E, 0x8F2E}, {0x8F2F, 0x8F2F}, + {0x8F30, 0x8F30}, {0x8F31, 0x8F31}, {0x8F32, 0x8F32}, {0x8F33, 0x8F33}, {0x8F34, 0x8F34}, {0x8F35, 0x8F35}, {0x8F36, 0x8F36}, + {0x8F37, 0x8F37}, {0x8F38, 0x8F38}, {0x8F39, 0x8F39}, {0x8F3A, 0x8F3A}, {0x8F3B, 0x8F3B}, {0x8F3C, 0x8F3C}, {0x8F3D, 0x8F3D}, + {0x8F3E, 0x8F3E}, {0x8F3F, 0x8F3F}, {0x8F40, 0x8F40}, {0x8F41, 0x8F41}, {0x8F42, 0x8F42}, {0x8F43, 0x8F43}, {0x8F44, 0x8F44}, + {0x8F45, 0x8F45}, {0x8F46, 0x8F46}, {0x8F47, 0x8F47}, {0x8F48, 0x8F48}, {0x8F49, 0x8F49}, {0x8F4A, 0x8F4A}, {0x8F4B, 0x8F4B}, + {0x8F4C, 0x8F4C}, {0x8F4D, 0x8F4D}, {0x8F4E, 0x8F4E}, {0x8F4F, 0x8F4F}, {0x8F50, 0x8F50}, {0x8F51, 0x8F51}, {0x8F52, 0x8F52}, + {0x8F53, 0x8F53}, {0x8F54, 0x8F54}, {0x8F55, 0x8F55}, {0x8F56, 0x8F56}, {0x8F57, 0x8F57}, {0x8F58, 0x8F58}, {0x8F59, 0x8F59}, + {0x8F5A, 0x8F5A}, {0x8F5B, 0x8F5B}, {0x8F5C, 0x8F5C}, {0x8F5D, 0x8F5D}, {0x8F5E, 0x8F5E}, {0x8F5F, 0x8F5F}, {0x8F60, 0x8F60}, + {0x8F61, 0x8F61}, {0x8F62, 0x8F62}, {0x8F63, 0x8F63}, {0x8F64, 0x8F64}, {0x8F65, 0x8F65}, {0x8F66, 0x8F66}, {0x8F67, 0x8F67}, + {0x8F68, 0x8F68}, {0x8F69, 0x8F69}, {0x8F6A, 0x8F6A}, {0x8F6B, 0x8F6B}, {0x8F6C, 0x8F6C}, {0x8F6D, 0x8F6D}, {0x8F6E, 0x8F6E}, + {0x8F6F, 0x8F6F}, {0x8F70, 0x8F70}, {0x8F71, 0x8F71}, {0x8F72, 0x8F72}, {0x8F73, 0x8F73}, {0x8F74, 0x8F74}, {0x8F75, 0x8F75}, + {0x8F76, 0x8F76}, {0x8F77, 0x8F77}, {0x8F78, 0x8F78}, {0x8F79, 0x8F79}, {0x8F7A, 0x8F7A}, {0x8F7B, 0x8F7B}, {0x8F7C, 0x8F7C}, + {0x8F7D, 0x8F7D}, {0x8F7E, 0x8F7E}, {0x8F7F, 0x8F7F}, {0x8F80, 0x8F80}, {0x8F81, 0x8F81}, {0x8F82, 0x8F82}, {0x8F83, 0x8F83}, + {0x8F84, 0x8F84}, {0x8F85, 0x8F85}, {0x8F86, 0x8F86}, {0x8F87, 0x8F87}, {0x8F88, 0x8F88}, {0x8F89, 0x8F89}, {0x8F8A, 0x8F8A}, + {0x8F8B, 0x8F8B}, {0x8F8C, 0x8F8C}, {0x8F8D, 0x8F8D}, {0x8F8E, 0x8F8E}, {0x8F8F, 0x8F8F}, {0x8F90, 0x8F90}, {0x8F91, 0x8F91}, + {0x8F92, 0x8F92}, {0x8F93, 0x8F93}, {0x8F94, 0x8F94}, {0x8F95, 0x8F95}, {0x8F96, 0x8F96}, {0x8F97, 0x8F97}, {0x8F98, 0x8F98}, + {0x8F99, 0x8F99}, {0x8F9A, 0x8F9A}, {0x8F9B, 0x8F9B}, {0x8F9C, 0x8F9C}, {0x8F9D, 0x8F9D}, {0x8F9E, 0x8F9E}, {0x8F9F, 0x8F9F}, + {0x8FA0, 0x8FA0}, {0x8FA1, 0x8FA1}, {0x8FA2, 0x8FA2}, {0x8FA3, 0x8FA3}, {0x8FA4, 0x8FA4}, {0x8FA5, 0x8FA5}, {0x8FA6, 0x8FA6}, + {0x8FA7, 0x8FA7}, {0x8FA8, 0x8FA8}, {0x8FA9, 0x8FA9}, {0x8FAA, 0x8FAA}, {0x8FAB, 0x8FAB}, {0x8FAC, 0x8FAC}, {0x8FAD, 0x8FAD}, + {0x8FAE, 0x8FAE}, {0x8FAF, 0x8FAF}, {0x8FB0, 0x8FB0}, {0x8FB1, 0x8FB1}, {0x8FB2, 0x8FB2}, {0x8FB3, 0x8FB3}, {0x8FB4, 0x8FB4}, + {0x8FB5, 0x8FB5}, {0x8FB6, 0x8FB6}, {0x8FB7, 0x8FB7}, {0x8FB8, 0x8FB8}, {0x8FB9, 0x8FB9}, {0x8FBA, 0x8FBA}, {0x8FBB, 0x8FBB}, + {0x8FBC, 0x8FBC}, {0x8FBD, 0x8FBD}, {0x8FBE, 0x8FBE}, {0x8FBF, 0x8FBF}, {0x8FC0, 0x8FC0}, {0x8FC1, 0x8FC1}, {0x8FC2, 0x8FC2}, + {0x8FC3, 0x8FC3}, {0x8FC4, 0x8FC4}, {0x8FC5, 0x8FC5}, {0x8FC6, 0x8FC6}, {0x8FC7, 0x8FC7}, {0x8FC8, 0x8FC8}, {0x8FC9, 0x8FC9}, + {0x8FCA, 0x8FCA}, {0x8FCB, 0x8FCB}, {0x8FCC, 0x8FCC}, {0x8FCD, 0x8FCD}, {0x8FCE, 0x8FCE}, {0x8FCF, 0x8FCF}, {0x8FD0, 0x8FD0}, + {0x8FD1, 0x8FD1}, {0x8FD2, 0x8FD2}, {0x8FD3, 0x8FD3}, {0x8FD4, 0x8FD4}, {0x8FD5, 0x8FD5}, {0x8FD6, 0x8FD6}, {0x8FD7, 0x8FD7}, + {0x8FD8, 0x8FD8}, {0x8FD9, 0x8FD9}, {0x8FDA, 0x8FDA}, {0x8FDB, 0x8FDB}, {0x8FDC, 0x8FDC}, {0x8FDD, 0x8FDD}, {0x8FDE, 0x8FDE}, + {0x8FDF, 0x8FDF}, {0x8FE0, 0x8FE0}, {0x8FE1, 0x8FE1}, {0x8FE2, 0x8FE2}, {0x8FE3, 0x8FE3}, {0x8FE4, 0x8FE4}, {0x8FE5, 0x8FE5}, + {0x8FE6, 0x8FE6}, {0x8FE7, 0x8FE7}, {0x8FE8, 0x8FE8}, {0x8FE9, 0x8FE9}, {0x8FEA, 0x8FEA}, {0x8FEB, 0x8FEB}, {0x8FEC, 0x8FEC}, + {0x8FED, 0x8FED}, {0x8FEE, 0x8FEE}, {0x8FEF, 0x8FEF}, {0x8FF0, 0x8FF0}, {0x8FF1, 0x8FF1}, {0x8FF2, 0x8FF2}, {0x8FF3, 0x8FF3}, + {0x8FF4, 0x8FF4}, {0x8FF5, 0x8FF5}, {0x8FF6, 0x8FF6}, {0x8FF7, 0x8FF7}, {0x8FF8, 0x8FF8}, {0x8FF9, 0x8FF9}, {0x8FFA, 0x8FFA}, + {0x8FFB, 0x8FFB}, {0x8FFC, 0x8FFC}, {0x8FFD, 0x8FFD}, {0x8FFE, 0x8FFE}, {0x8FFF, 0x8FFF}, {0x9000, 0x9000}, {0x9001, 0x9001}, + {0x9002, 0x9002}, {0x9003, 0x9003}, {0x9004, 0x9004}, {0x9005, 0x9005}, {0x9006, 0x9006}, {0x9007, 0x9007}, {0x9008, 0x9008}, + {0x9009, 0x9009}, {0x900A, 0x900A}, {0x900B, 0x900B}, {0x900C, 0x900C}, {0x900D, 0x900D}, {0x900E, 0x900E}, {0x900F, 0x900F}, + {0x9010, 0x9010}, {0x9011, 0x9011}, {0x9012, 0x9012}, {0x9013, 0x9013}, {0x9014, 0x9014}, {0x9015, 0x9015}, {0x9016, 0x9016}, + {0x9017, 0x9017}, {0x9018, 0x9018}, {0x9019, 0x9019}, {0x901A, 0x901A}, {0x901B, 0x901B}, {0x901C, 0x901C}, {0x901D, 0x901D}, + {0x901E, 0x901E}, {0x901F, 0x901F}, {0x9020, 0x9020}, {0x9021, 0x9021}, {0x9022, 0x9022}, {0x9023, 0x9023}, {0x9024, 0x9024}, + {0x9025, 0x9025}, {0x9026, 0x9026}, {0x9027, 0x9027}, {0x9028, 0x9028}, {0x9029, 0x9029}, {0x902A, 0x902A}, {0x902B, 0x902B}, + {0x902C, 0x902C}, {0x902D, 0x902D}, {0x902E, 0x902E}, {0x902F, 0x902F}, {0x9030, 0x9030}, {0x9031, 0x9031}, {0x9032, 0x9032}, + {0x9033, 0x9033}, {0x9034, 0x9034}, {0x9035, 0x9035}, {0x9036, 0x9036}, {0x9037, 0x9037}, {0x9038, 0x9038}, {0x9039, 0x9039}, + {0x903A, 0x903A}, {0x903B, 0x903B}, {0x903C, 0x903C}, {0x903D, 0x903D}, {0x903E, 0x903E}, {0x903F, 0x903F}, {0x9040, 0x9040}, + {0x9041, 0x9041}, {0x9042, 0x9042}, {0x9043, 0x9043}, {0x9044, 0x9044}, {0x9045, 0x9045}, {0x9046, 0x9046}, {0x9047, 0x9047}, + {0x9048, 0x9048}, {0x9049, 0x9049}, {0x904A, 0x904A}, {0x904B, 0x904B}, {0x904C, 0x904C}, {0x904D, 0x904D}, {0x904E, 0x904E}, + {0x904F, 0x904F}, {0x9050, 0x9050}, {0x9051, 0x9051}, {0x9052, 0x9052}, {0x9053, 0x9053}, {0x9054, 0x9054}, {0x9055, 0x9055}, + {0x9056, 0x9056}, {0x9057, 0x9057}, {0x9058, 0x9058}, {0x9059, 0x9059}, {0x905A, 0x905A}, {0x905B, 0x905B}, {0x905C, 0x905C}, + {0x905D, 0x905D}, {0x905E, 0x905E}, {0x905F, 0x905F}, {0x9060, 0x9060}, {0x9061, 0x9061}, {0x9062, 0x9062}, {0x9063, 0x9063}, + {0x9064, 0x9064}, {0x9065, 0x9065}, {0x9066, 0x9066}, {0x9067, 0x9067}, {0x9068, 0x9068}, {0x9069, 0x9069}, {0x906A, 0x906A}, + {0x906B, 0x906B}, {0x906C, 0x906C}, {0x906D, 0x906D}, {0x906E, 0x906E}, {0x906F, 0x906F}, {0x9070, 0x9070}, {0x9071, 0x9071}, + {0x9072, 0x9072}, {0x9073, 0x9073}, {0x9074, 0x9074}, {0x9075, 0x9075}, {0x9076, 0x9076}, {0x9077, 0x9077}, {0x9078, 0x9078}, + {0x9079, 0x9079}, {0x907A, 0x907A}, {0x907B, 0x907B}, {0x907C, 0x907C}, {0x907D, 0x907D}, {0x907E, 0x907E}, {0x907F, 0x907F}, + {0x9080, 0x9080}, {0x9081, 0x9081}, {0x9082, 0x9082}, {0x9083, 0x9083}, {0x9084, 0x9084}, {0x9085, 0x9085}, {0x9086, 0x9086}, + {0x9087, 0x9087}, {0x9088, 0x9088}, {0x9089, 0x9089}, {0x908A, 0x908A}, {0x908B, 0x908B}, {0x908C, 0x908C}, {0x908D, 0x908D}, + {0x908E, 0x908E}, {0x908F, 0x908F}, {0x9090, 0x9090}, {0x9091, 0x9091}, {0x9092, 0x9092}, {0x9093, 0x9093}, {0x9094, 0x9094}, + {0x9095, 0x9095}, {0x9096, 0x9096}, {0x9097, 0x9097}, {0x9098, 0x9098}, {0x9099, 0x9099}, {0x909A, 0x909A}, {0x909B, 0x909B}, + {0x909C, 0x909C}, {0x909D, 0x909D}, {0x909E, 0x909E}, {0x909F, 0x909F}, {0x90A0, 0x90A0}, {0x90A1, 0x90A1}, {0x90A2, 0x90A2}, + {0x90A3, 0x90A3}, {0x90A4, 0x90A4}, {0x90A5, 0x90A5}, {0x90A6, 0x90A6}, {0x90A7, 0x90A7}, {0x90A8, 0x90A8}, {0x90A9, 0x90A9}, + {0x90AA, 0x90AA}, {0x90AB, 0x90AB}, {0x90AC, 0x90AC}, {0x90AD, 0x90AD}, {0x90AE, 0x90AE}, {0x90AF, 0x90AF}, {0x90B0, 0x90B0}, + {0x90B1, 0x90B1}, {0x90B2, 0x90B2}, {0x90B3, 0x90B3}, {0x90B4, 0x90B4}, {0x90B5, 0x90B5}, {0x90B6, 0x90B6}, {0x90B7, 0x90B7}, + {0x90B8, 0x90B8}, {0x90B9, 0x90B9}, {0x90BA, 0x90BA}, {0x90BB, 0x90BB}, {0x90BC, 0x90BC}, {0x90BD, 0x90BD}, {0x90BE, 0x90BE}, + {0x90BF, 0x90BF}, {0x90C0, 0x90C0}, {0x90C1, 0x90C1}, {0x90C2, 0x90C2}, {0x90C3, 0x90C3}, {0x90C4, 0x90C4}, {0x90C5, 0x90C5}, + {0x90C6, 0x90C6}, {0x90C7, 0x90C7}, {0x90C8, 0x90C8}, {0x90C9, 0x90C9}, {0x90CA, 0x90CA}, {0x90CB, 0x90CB}, {0x90CC, 0x90CC}, + {0x90CD, 0x90CD}, {0x90CE, 0x90CE}, {0x90CF, 0x90CF}, {0x90D0, 0x90D0}, {0x90D1, 0x90D1}, {0x90D2, 0x90D2}, {0x90D3, 0x90D3}, + {0x90D4, 0x90D4}, {0x90D5, 0x90D5}, {0x90D6, 0x90D6}, {0x90D7, 0x90D7}, {0x90D8, 0x90D8}, {0x90D9, 0x90D9}, {0x90DA, 0x90DA}, + {0x90DB, 0x90DB}, {0x90DC, 0x90DC}, {0x90DD, 0x90DD}, {0x90DE, 0x90DE}, {0x90DF, 0x90DF}, {0x90E0, 0x90E0}, {0x90E1, 0x90E1}, + {0x90E2, 0x90E2}, {0x90E3, 0x90E3}, {0x90E4, 0x90E4}, {0x90E5, 0x90E5}, {0x90E6, 0x90E6}, {0x90E7, 0x90E7}, {0x90E8, 0x90E8}, + {0x90E9, 0x90E9}, {0x90EA, 0x90EA}, {0x90EB, 0x90EB}, {0x90EC, 0x90EC}, {0x90ED, 0x90ED}, {0x90EE, 0x90EE}, {0x90EF, 0x90EF}, + {0x90F0, 0x90F0}, {0x90F1, 0x90F1}, {0x90F2, 0x90F2}, {0x90F3, 0x90F3}, {0x90F4, 0x90F4}, {0x90F5, 0x90F5}, {0x90F6, 0x90F6}, + {0x90F7, 0x90F7}, {0x90F8, 0x90F8}, {0x90F9, 0x90F9}, {0x90FA, 0x90FA}, {0x90FB, 0x90FB}, {0x90FC, 0x90FC}, {0x90FD, 0x90FD}, + {0x90FE, 0x90FE}, {0x90FF, 0x90FF}, {0x9100, 0x9100}, {0x9101, 0x9101}, {0x9102, 0x9102}, {0x9103, 0x9103}, {0x9104, 0x9104}, + {0x9105, 0x9105}, {0x9106, 0x9106}, {0x9107, 0x9107}, {0x9108, 0x9108}, {0x9109, 0x9109}, {0x910A, 0x910A}, {0x910B, 0x910B}, + {0x910C, 0x910C}, {0x910D, 0x910D}, {0x910E, 0x910E}, {0x910F, 0x910F}, {0x9110, 0x9110}, {0x9111, 0x9111}, {0x9112, 0x9112}, + {0x9113, 0x9113}, {0x9114, 0x9114}, {0x9115, 0x9115}, {0x9116, 0x9116}, {0x9117, 0x9117}, {0x9118, 0x9118}, {0x9119, 0x9119}, + {0x911A, 0x911A}, {0x911B, 0x911B}, {0x911C, 0x911C}, {0x911D, 0x911D}, {0x911E, 0x911E}, {0x911F, 0x911F}, {0x9120, 0x9120}, + {0x9121, 0x9121}, {0x9122, 0x9122}, {0x9123, 0x9123}, {0x9124, 0x9124}, {0x9125, 0x9125}, {0x9126, 0x9126}, {0x9127, 0x9127}, + {0x9128, 0x9128}, {0x9129, 0x9129}, {0x912A, 0x912A}, {0x912B, 0x912B}, {0x912C, 0x912C}, {0x912D, 0x912D}, {0x912E, 0x912E}, + {0x912F, 0x912F}, {0x9130, 0x9130}, {0x9131, 0x9131}, {0x9132, 0x9132}, {0x9133, 0x9133}, {0x9134, 0x9134}, {0x9135, 0x9135}, + {0x9136, 0x9136}, {0x9137, 0x9137}, {0x9138, 0x9138}, {0x9139, 0x9139}, {0x913A, 0x913A}, {0x913B, 0x913B}, {0x913C, 0x913C}, + {0x913D, 0x913D}, {0x913E, 0x913E}, {0x913F, 0x913F}, {0x9140, 0x9140}, {0x9141, 0x9141}, {0x9142, 0x9142}, {0x9143, 0x9143}, + {0x9144, 0x9144}, {0x9145, 0x9145}, {0x9146, 0x9146}, {0x9147, 0x9147}, {0x9148, 0x9148}, {0x9149, 0x9149}, {0x914A, 0x914A}, + {0x914B, 0x914B}, {0x914C, 0x914C}, {0x914D, 0x914D}, {0x914E, 0x914E}, {0x914F, 0x914F}, {0x9150, 0x9150}, {0x9151, 0x9151}, + {0x9152, 0x9152}, {0x9153, 0x9153}, {0x9154, 0x9154}, {0x9155, 0x9155}, {0x9156, 0x9156}, {0x9157, 0x9157}, {0x9158, 0x9158}, + {0x9159, 0x9159}, {0x915A, 0x915A}, {0x915B, 0x915B}, {0x915C, 0x915C}, {0x915D, 0x915D}, {0x915E, 0x915E}, {0x915F, 0x915F}, + {0x9160, 0x9160}, {0x9161, 0x9161}, {0x9162, 0x9162}, {0x9163, 0x9163}, {0x9164, 0x9164}, {0x9165, 0x9165}, {0x9166, 0x9166}, + {0x9167, 0x9167}, {0x9168, 0x9168}, {0x9169, 0x9169}, {0x916A, 0x916A}, {0x916B, 0x916B}, {0x916C, 0x916C}, {0x916D, 0x916D}, + {0x916E, 0x916E}, {0x916F, 0x916F}, {0x9170, 0x9170}, {0x9171, 0x9171}, {0x9172, 0x9172}, {0x9173, 0x9173}, {0x9174, 0x9174}, + {0x9175, 0x9175}, {0x9176, 0x9176}, {0x9177, 0x9177}, {0x9178, 0x9178}, {0x9179, 0x9179}, {0x917A, 0x917A}, {0x917B, 0x917B}, + {0x917C, 0x917C}, {0x917D, 0x917D}, {0x917E, 0x917E}, {0x917F, 0x917F}, {0x9180, 0x9180}, {0x9181, 0x9181}, {0x9182, 0x9182}, + {0x9183, 0x9183}, {0x9184, 0x9184}, {0x9185, 0x9185}, {0x9186, 0x9186}, {0x9187, 0x9187}, {0x9188, 0x9188}, {0x9189, 0x9189}, + {0x918A, 0x918A}, {0x918B, 0x918B}, {0x918C, 0x918C}, {0x918D, 0x918D}, {0x918E, 0x918E}, {0x918F, 0x918F}, {0x9190, 0x9190}, + {0x9191, 0x9191}, {0x9192, 0x9192}, {0x9193, 0x9193}, {0x9194, 0x9194}, {0x9195, 0x9195}, {0x9196, 0x9196}, {0x9197, 0x9197}, + {0x9198, 0x9198}, {0x9199, 0x9199}, {0x919A, 0x919A}, {0x919B, 0x919B}, {0x919C, 0x919C}, {0x919D, 0x919D}, {0x919E, 0x919E}, + {0x919F, 0x919F}, {0x91A0, 0x91A0}, {0x91A1, 0x91A1}, {0x91A2, 0x91A2}, {0x91A3, 0x91A3}, {0x91A4, 0x91A4}, {0x91A5, 0x91A5}, + {0x91A6, 0x91A6}, {0x91A7, 0x91A7}, {0x91A8, 0x91A8}, {0x91A9, 0x91A9}, {0x91AA, 0x91AA}, {0x91AB, 0x91AB}, {0x91AC, 0x91AC}, + {0x91AD, 0x91AD}, {0x91AE, 0x91AE}, {0x91AF, 0x91AF}, {0x91B0, 0x91B0}, {0x91B1, 0x91B1}, {0x91B2, 0x91B2}, {0x91B3, 0x91B3}, + {0x91B4, 0x91B4}, {0x91B5, 0x91B5}, {0x91B6, 0x91B6}, {0x91B7, 0x91B7}, {0x91B8, 0x91B8}, {0x91B9, 0x91B9}, {0x91BA, 0x91BA}, + {0x91BB, 0x91BB}, {0x91BC, 0x91BC}, {0x91BD, 0x91BD}, {0x91BE, 0x91BE}, {0x91BF, 0x91BF}, {0x91C0, 0x91C0}, {0x91C1, 0x91C1}, + {0x91C2, 0x91C2}, {0x91C3, 0x91C3}, {0x91C4, 0x91C4}, {0x91C5, 0x91C5}, {0x91C6, 0x91C6}, {0x91C7, 0x91C7}, {0x91C8, 0x91C8}, + {0x91C9, 0x91C9}, {0x91CA, 0x91CA}, {0x91CB, 0x91CB}, {0x91CC, 0x91CC}, {0x91CD, 0x91CD}, {0x91CE, 0x91CE}, {0x91CF, 0x91CF}, + {0x91D0, 0x91D0}, {0x91D1, 0x91D1}, {0x91D2, 0x91D2}, {0x91D3, 0x91D3}, {0x91D4, 0x91D4}, {0x91D5, 0x91D5}, {0x91D6, 0x91D6}, + {0x91D7, 0x91D7}, {0x91D8, 0x91D8}, {0x91D9, 0x91D9}, {0x91DA, 0x91DA}, {0x91DB, 0x91DB}, {0x91DC, 0x91DC}, {0x91DD, 0x91DD}, + {0x91DE, 0x91DE}, {0x91DF, 0x91DF}, {0x91E0, 0x91E0}, {0x91E1, 0x91E1}, {0x91E2, 0x91E2}, {0x91E3, 0x91E3}, {0x91E4, 0x91E4}, + {0x91E5, 0x91E5}, {0x91E6, 0x91E6}, {0x91E7, 0x91E7}, {0x91E8, 0x91E8}, {0x91E9, 0x91E9}, {0x91EA, 0x91EA}, {0x91EB, 0x91EB}, + {0x91EC, 0x91EC}, {0x91ED, 0x91ED}, {0x91EE, 0x91EE}, {0x91EF, 0x91EF}, {0x91F0, 0x91F0}, {0x91F1, 0x91F1}, {0x91F2, 0x91F2}, + {0x91F3, 0x91F3}, {0x91F4, 0x91F4}, {0x91F5, 0x91F5}, {0x91F6, 0x91F6}, {0x91F7, 0x91F7}, {0x91F8, 0x91F8}, {0x91F9, 0x91F9}, + {0x91FA, 0x91FA}, {0x91FB, 0x91FB}, {0x91FC, 0x91FC}, {0x91FD, 0x91FD}, {0x91FE, 0x91FE}, {0x91FF, 0x91FF}, {0x9200, 0x9200}, + {0x9201, 0x9201}, {0x9202, 0x9202}, {0x9203, 0x9203}, {0x9204, 0x9204}, {0x9205, 0x9205}, {0x9206, 0x9206}, {0x9207, 0x9207}, + {0x9208, 0x9208}, {0x9209, 0x9209}, {0x920A, 0x920A}, {0x920B, 0x920B}, {0x920C, 0x920C}, {0x920D, 0x920D}, {0x920E, 0x920E}, + {0x920F, 0x920F}, {0x9210, 0x9210}, {0x9211, 0x9211}, {0x9212, 0x9212}, {0x9213, 0x9213}, {0x9214, 0x9214}, {0x9215, 0x9215}, + {0x9216, 0x9216}, {0x9217, 0x9217}, {0x9218, 0x9218}, {0x9219, 0x9219}, {0x921A, 0x921A}, {0x921B, 0x921B}, {0x921C, 0x921C}, + {0x921D, 0x921D}, {0x921E, 0x921E}, {0x921F, 0x921F}, {0x9220, 0x9220}, {0x9221, 0x9221}, {0x9222, 0x9222}, {0x9223, 0x9223}, + {0x9224, 0x9224}, {0x9225, 0x9225}, {0x9226, 0x9226}, {0x9227, 0x9227}, {0x9228, 0x9228}, {0x9229, 0x9229}, {0x922A, 0x922A}, + {0x922B, 0x922B}, {0x922C, 0x922C}, {0x922D, 0x922D}, {0x922E, 0x922E}, {0x922F, 0x922F}, {0x9230, 0x9230}, {0x9231, 0x9231}, + {0x9232, 0x9232}, {0x9233, 0x9233}, {0x9234, 0x9234}, {0x9235, 0x9235}, {0x9236, 0x9236}, {0x9237, 0x9237}, {0x9238, 0x9238}, + {0x9239, 0x9239}, {0x923A, 0x923A}, {0x923B, 0x923B}, {0x923C, 0x923C}, {0x923D, 0x923D}, {0x923E, 0x923E}, {0x923F, 0x923F}, + {0x9240, 0x9240}, {0x9241, 0x9241}, {0x9242, 0x9242}, {0x9243, 0x9243}, {0x9244, 0x9244}, {0x9245, 0x9245}, {0x9246, 0x9246}, + {0x9247, 0x9247}, {0x9248, 0x9248}, {0x9249, 0x9249}, {0x924A, 0x924A}, {0x924B, 0x924B}, {0x924C, 0x924C}, {0x924D, 0x924D}, + {0x924E, 0x924E}, {0x924F, 0x924F}, {0x9250, 0x9250}, {0x9251, 0x9251}, {0x9252, 0x9252}, {0x9253, 0x9253}, {0x9254, 0x9254}, + {0x9255, 0x9255}, {0x9256, 0x9256}, {0x9257, 0x9257}, {0x9258, 0x9258}, {0x9259, 0x9259}, {0x925A, 0x925A}, {0x925B, 0x925B}, + {0x925C, 0x925C}, {0x925D, 0x925D}, {0x925E, 0x925E}, {0x925F, 0x925F}, {0x9260, 0x9260}, {0x9261, 0x9261}, {0x9262, 0x9262}, + {0x9263, 0x9263}, {0x9264, 0x9264}, {0x9265, 0x9265}, {0x9266, 0x9266}, {0x9267, 0x9267}, {0x9268, 0x9268}, {0x9269, 0x9269}, + {0x926A, 0x926A}, {0x926B, 0x926B}, {0x926C, 0x926C}, {0x926D, 0x926D}, {0x926E, 0x926E}, {0x926F, 0x926F}, {0x9270, 0x9270}, + {0x9271, 0x9271}, {0x9272, 0x9272}, {0x9273, 0x9273}, {0x9274, 0x9274}, {0x9275, 0x9275}, {0x9276, 0x9276}, {0x9277, 0x9277}, + {0x9278, 0x9278}, {0x9279, 0x9279}, {0x927A, 0x927A}, {0x927B, 0x927B}, {0x927C, 0x927C}, {0x927D, 0x927D}, {0x927E, 0x927E}, + {0x927F, 0x927F}, {0x9280, 0x9280}, {0x9281, 0x9281}, {0x9282, 0x9282}, {0x9283, 0x9283}, {0x9284, 0x9284}, {0x9285, 0x9285}, + {0x9286, 0x9286}, {0x9287, 0x9287}, {0x9288, 0x9288}, {0x9289, 0x9289}, {0x928A, 0x928A}, {0x928B, 0x928B}, {0x928C, 0x928C}, + {0x928D, 0x928D}, {0x928E, 0x928E}, {0x928F, 0x928F}, {0x9290, 0x9290}, {0x9291, 0x9291}, {0x9292, 0x9292}, {0x9293, 0x9293}, + {0x9294, 0x9294}, {0x9295, 0x9295}, {0x9296, 0x9296}, {0x9297, 0x9297}, {0x9298, 0x9298}, {0x9299, 0x9299}, {0x929A, 0x929A}, + {0x929B, 0x929B}, {0x929C, 0x929C}, {0x929D, 0x929D}, {0x929E, 0x929E}, {0x929F, 0x929F}, {0x92A0, 0x92A0}, {0x92A1, 0x92A1}, + {0x92A2, 0x92A2}, {0x92A3, 0x92A3}, {0x92A4, 0x92A4}, {0x92A5, 0x92A5}, {0x92A6, 0x92A6}, {0x92A7, 0x92A7}, {0x92A8, 0x92A8}, + {0x92A9, 0x92A9}, {0x92AA, 0x92AA}, {0x92AB, 0x92AB}, {0x92AC, 0x92AC}, {0x92AD, 0x92AD}, {0x92AE, 0x92AE}, {0x92AF, 0x92AF}, + {0x92B0, 0x92B0}, {0x92B1, 0x92B1}, {0x92B2, 0x92B2}, {0x92B3, 0x92B3}, {0x92B4, 0x92B4}, {0x92B5, 0x92B5}, {0x92B6, 0x92B6}, + {0x92B7, 0x92B7}, {0x92B8, 0x92B8}, {0x92B9, 0x92B9}, {0x92BA, 0x92BA}, {0x92BB, 0x92BB}, {0x92BC, 0x92BC}, {0x92BD, 0x92BD}, + {0x92BE, 0x92BE}, {0x92BF, 0x92BF}, {0x92C0, 0x92C0}, {0x92C1, 0x92C1}, {0x92C2, 0x92C2}, {0x92C3, 0x92C3}, {0x92C4, 0x92C4}, + {0x92C5, 0x92C5}, {0x92C6, 0x92C6}, {0x92C7, 0x92C7}, {0x92C8, 0x92C8}, {0x92C9, 0x92C9}, {0x92CA, 0x92CA}, {0x92CB, 0x92CB}, + {0x92CC, 0x92CC}, {0x92CD, 0x92CD}, {0x92CE, 0x92CE}, {0x92CF, 0x92CF}, {0x92D0, 0x92D0}, {0x92D1, 0x92D1}, {0x92D2, 0x92D2}, + {0x92D3, 0x92D3}, {0x92D4, 0x92D4}, {0x92D5, 0x92D5}, {0x92D6, 0x92D6}, {0x92D7, 0x92D7}, {0x92D8, 0x92D8}, {0x92D9, 0x92D9}, + {0x92DA, 0x92DA}, {0x92DB, 0x92DB}, {0x92DC, 0x92DC}, {0x92DD, 0x92DD}, {0x92DE, 0x92DE}, {0x92DF, 0x92DF}, {0x92E0, 0x92E0}, + {0x92E1, 0x92E1}, {0x92E2, 0x92E2}, {0x92E3, 0x92E3}, {0x92E4, 0x92E4}, {0x92E5, 0x92E5}, {0x92E6, 0x92E6}, {0x92E7, 0x92E7}, + {0x92E8, 0x92E8}, {0x92E9, 0x92E9}, {0x92EA, 0x92EA}, {0x92EB, 0x92EB}, {0x92EC, 0x92EC}, {0x92ED, 0x92ED}, {0x92EE, 0x92EE}, + {0x92EF, 0x92EF}, {0x92F0, 0x92F0}, {0x92F1, 0x92F1}, {0x92F2, 0x92F2}, {0x92F3, 0x92F3}, {0x92F4, 0x92F4}, {0x92F5, 0x92F5}, + {0x92F6, 0x92F6}, {0x92F7, 0x92F7}, {0x92F8, 0x92F8}, {0x92F9, 0x92F9}, {0x92FA, 0x92FA}, {0x92FB, 0x92FB}, {0x92FC, 0x92FC}, + {0x92FD, 0x92FD}, {0x92FE, 0x92FE}, {0x92FF, 0x92FF}, {0x9300, 0x9300}, {0x9301, 0x9301}, {0x9302, 0x9302}, {0x9303, 0x9303}, + {0x9304, 0x9304}, {0x9305, 0x9305}, {0x9306, 0x9306}, {0x9307, 0x9307}, {0x9308, 0x9308}, {0x9309, 0x9309}, {0x930A, 0x930A}, + {0x930B, 0x930B}, {0x930C, 0x930C}, {0x930D, 0x930D}, {0x930E, 0x930E}, {0x930F, 0x930F}, {0x9310, 0x9310}, {0x9311, 0x9311}, + {0x9312, 0x9312}, {0x9313, 0x9313}, {0x9314, 0x9314}, {0x9315, 0x9315}, {0x9316, 0x9316}, {0x9317, 0x9317}, {0x9318, 0x9318}, + {0x9319, 0x9319}, {0x931A, 0x931A}, {0x931B, 0x931B}, {0x931C, 0x931C}, {0x931D, 0x931D}, {0x931E, 0x931E}, {0x931F, 0x931F}, + {0x9320, 0x9320}, {0x9321, 0x9321}, {0x9322, 0x9322}, {0x9323, 0x9323}, {0x9324, 0x9324}, {0x9325, 0x9325}, {0x9326, 0x9326}, + {0x9327, 0x9327}, {0x9328, 0x9328}, {0x9329, 0x9329}, {0x932A, 0x932A}, {0x932B, 0x932B}, {0x932C, 0x932C}, {0x932D, 0x932D}, + {0x932E, 0x932E}, {0x932F, 0x932F}, {0x9330, 0x9330}, {0x9331, 0x9331}, {0x9332, 0x9332}, {0x9333, 0x9333}, {0x9334, 0x9334}, + {0x9335, 0x9335}, {0x9336, 0x9336}, {0x9337, 0x9337}, {0x9338, 0x9338}, {0x9339, 0x9339}, {0x933A, 0x933A}, {0x933B, 0x933B}, + {0x933C, 0x933C}, {0x933D, 0x933D}, {0x933E, 0x933E}, {0x933F, 0x933F}, {0x9340, 0x9340}, {0x9341, 0x9341}, {0x9342, 0x9342}, + {0x9343, 0x9343}, {0x9344, 0x9344}, {0x9345, 0x9345}, {0x9346, 0x9346}, {0x9347, 0x9347}, {0x9348, 0x9348}, {0x9349, 0x9349}, + {0x934A, 0x934A}, {0x934B, 0x934B}, {0x934C, 0x934C}, {0x934D, 0x934D}, {0x934E, 0x934E}, {0x934F, 0x934F}, {0x9350, 0x9350}, + {0x9351, 0x9351}, {0x9352, 0x9352}, {0x9353, 0x9353}, {0x9354, 0x9354}, {0x9355, 0x9355}, {0x9356, 0x9356}, {0x9357, 0x9357}, + {0x9358, 0x9358}, {0x9359, 0x9359}, {0x935A, 0x935A}, {0x935B, 0x935B}, {0x935C, 0x935C}, {0x935D, 0x935D}, {0x935E, 0x935E}, + {0x935F, 0x935F}, {0x9360, 0x9360}, {0x9361, 0x9361}, {0x9362, 0x9362}, {0x9363, 0x9363}, {0x9364, 0x9364}, {0x9365, 0x9365}, + {0x9366, 0x9366}, {0x9367, 0x9367}, {0x9368, 0x9368}, {0x9369, 0x9369}, {0x936A, 0x936A}, {0x936B, 0x936B}, {0x936C, 0x936C}, + {0x936D, 0x936D}, {0x936E, 0x936E}, {0x936F, 0x936F}, {0x9370, 0x9370}, {0x9371, 0x9371}, {0x9372, 0x9372}, {0x9373, 0x9373}, + {0x9374, 0x9374}, {0x9375, 0x9375}, {0x9376, 0x9376}, {0x9377, 0x9377}, {0x9378, 0x9378}, {0x9379, 0x9379}, {0x937A, 0x937A}, + {0x937B, 0x937B}, {0x937C, 0x937C}, {0x937D, 0x937D}, {0x937E, 0x937E}, {0x937F, 0x937F}, {0x9380, 0x9380}, {0x9381, 0x9381}, + {0x9382, 0x9382}, {0x9383, 0x9383}, {0x9384, 0x9384}, {0x9385, 0x9385}, {0x9386, 0x9386}, {0x9387, 0x9387}, {0x9388, 0x9388}, + {0x9389, 0x9389}, {0x938A, 0x938A}, {0x938B, 0x938B}, {0x938C, 0x938C}, {0x938D, 0x938D}, {0x938E, 0x938E}, {0x938F, 0x938F}, + {0x9390, 0x9390}, {0x9391, 0x9391}, {0x9392, 0x9392}, {0x9393, 0x9393}, {0x9394, 0x9394}, {0x9395, 0x9395}, {0x9396, 0x9396}, + {0x9397, 0x9397}, {0x9398, 0x9398}, {0x9399, 0x9399}, {0x939A, 0x939A}, {0x939B, 0x939B}, {0x939C, 0x939C}, {0x939D, 0x939D}, + {0x939E, 0x939E}, {0x939F, 0x939F}, {0x93A0, 0x93A0}, {0x93A1, 0x93A1}, {0x93A2, 0x93A2}, {0x93A3, 0x93A3}, {0x93A4, 0x93A4}, + {0x93A5, 0x93A5}, {0x93A6, 0x93A6}, {0x93A7, 0x93A7}, {0x93A8, 0x93A8}, {0x93A9, 0x93A9}, {0x93AA, 0x93AA}, {0x93AB, 0x93AB}, + {0x93AC, 0x93AC}, {0x93AD, 0x93AD}, {0x93AE, 0x93AE}, {0x93AF, 0x93AF}, {0x93B0, 0x93B0}, {0x93B1, 0x93B1}, {0x93B2, 0x93B2}, + {0x93B3, 0x93B3}, {0x93B4, 0x93B4}, {0x93B5, 0x93B5}, {0x93B6, 0x93B6}, {0x93B7, 0x93B7}, {0x93B8, 0x93B8}, {0x93B9, 0x93B9}, + {0x93BA, 0x93BA}, {0x93BB, 0x93BB}, {0x93BC, 0x93BC}, {0x93BD, 0x93BD}, {0x93BE, 0x93BE}, {0x93BF, 0x93BF}, {0x93C0, 0x93C0}, + {0x93C1, 0x93C1}, {0x93C2, 0x93C2}, {0x93C3, 0x93C3}, {0x93C4, 0x93C4}, {0x93C5, 0x93C5}, {0x93C6, 0x93C6}, {0x93C7, 0x93C7}, + {0x93C8, 0x93C8}, {0x93C9, 0x93C9}, {0x93CA, 0x93CA}, {0x93CB, 0x93CB}, {0x93CC, 0x93CC}, {0x93CD, 0x93CD}, {0x93CE, 0x93CE}, + {0x93CF, 0x93CF}, {0x93D0, 0x93D0}, {0x93D1, 0x93D1}, {0x93D2, 0x93D2}, {0x93D3, 0x93D3}, {0x93D4, 0x93D4}, {0x93D5, 0x93D5}, + {0x93D6, 0x93D6}, {0x93D7, 0x93D7}, {0x93D8, 0x93D8}, {0x93D9, 0x93D9}, {0x93DA, 0x93DA}, {0x93DB, 0x93DB}, {0x93DC, 0x93DC}, + {0x93DD, 0x93DD}, {0x93DE, 0x93DE}, {0x93DF, 0x93DF}, {0x93E0, 0x93E0}, {0x93E1, 0x93E1}, {0x93E2, 0x93E2}, {0x93E3, 0x93E3}, + {0x93E4, 0x93E4}, {0x93E5, 0x93E5}, {0x93E6, 0x93E6}, {0x93E7, 0x93E7}, {0x93E8, 0x93E8}, {0x93E9, 0x93E9}, {0x93EA, 0x93EA}, + {0x93EB, 0x93EB}, {0x93EC, 0x93EC}, {0x93ED, 0x93ED}, {0x93EE, 0x93EE}, {0x93EF, 0x93EF}, {0x93F0, 0x93F0}, {0x93F1, 0x93F1}, + {0x93F2, 0x93F2}, {0x93F3, 0x93F3}, {0x93F4, 0x93F4}, {0x93F5, 0x93F5}, {0x93F6, 0x93F6}, {0x93F7, 0x93F7}, {0x93F8, 0x93F8}, + {0x93F9, 0x93F9}, {0x93FA, 0x93FA}, {0x93FB, 0x93FB}, {0x93FC, 0x93FC}, {0x93FD, 0x93FD}, {0x93FE, 0x93FE}, {0x93FF, 0x93FF}, + {0x9400, 0x9400}, {0x9401, 0x9401}, {0x9402, 0x9402}, {0x9403, 0x9403}, {0x9404, 0x9404}, {0x9405, 0x9405}, {0x9406, 0x9406}, + {0x9407, 0x9407}, {0x9408, 0x9408}, {0x9409, 0x9409}, {0x940A, 0x940A}, {0x940B, 0x940B}, {0x940C, 0x940C}, {0x940D, 0x940D}, + {0x940E, 0x940E}, {0x940F, 0x940F}, {0x9410, 0x9410}, {0x9411, 0x9411}, {0x9412, 0x9412}, {0x9413, 0x9413}, {0x9414, 0x9414}, + {0x9415, 0x9415}, {0x9416, 0x9416}, {0x9417, 0x9417}, {0x9418, 0x9418}, {0x9419, 0x9419}, {0x941A, 0x941A}, {0x941B, 0x941B}, + {0x941C, 0x941C}, {0x941D, 0x941D}, {0x941E, 0x941E}, {0x941F, 0x941F}, {0x9420, 0x9420}, {0x9421, 0x9421}, {0x9422, 0x9422}, + {0x9423, 0x9423}, {0x9424, 0x9424}, {0x9425, 0x9425}, {0x9426, 0x9426}, {0x9427, 0x9427}, {0x9428, 0x9428}, {0x9429, 0x9429}, + {0x942A, 0x942A}, {0x942B, 0x942B}, {0x942C, 0x942C}, {0x942D, 0x942D}, {0x942E, 0x942E}, {0x942F, 0x942F}, {0x9430, 0x9430}, + {0x9431, 0x9431}, {0x9432, 0x9432}, {0x9433, 0x9433}, {0x9434, 0x9434}, {0x9435, 0x9435}, {0x9436, 0x9436}, {0x9437, 0x9437}, + {0x9438, 0x9438}, {0x9439, 0x9439}, {0x943A, 0x943A}, {0x943B, 0x943B}, {0x943C, 0x943C}, {0x943D, 0x943D}, {0x943E, 0x943E}, + {0x943F, 0x943F}, {0x9440, 0x9440}, {0x9441, 0x9441}, {0x9442, 0x9442}, {0x9443, 0x9443}, {0x9444, 0x9444}, {0x9445, 0x9445}, + {0x9446, 0x9446}, {0x9447, 0x9447}, {0x9448, 0x9448}, {0x9449, 0x9449}, {0x944A, 0x944A}, {0x944B, 0x944B}, {0x944C, 0x944C}, + {0x944D, 0x944D}, {0x944E, 0x944E}, {0x944F, 0x944F}, {0x9450, 0x9450}, {0x9451, 0x9451}, {0x9452, 0x9452}, {0x9453, 0x9453}, + {0x9454, 0x9454}, {0x9455, 0x9455}, {0x9456, 0x9456}, {0x9457, 0x9457}, {0x9458, 0x9458}, {0x9459, 0x9459}, {0x945A, 0x945A}, + {0x945B, 0x945B}, {0x945C, 0x945C}, {0x945D, 0x945D}, {0x945E, 0x945E}, {0x945F, 0x945F}, {0x9460, 0x9460}, {0x9461, 0x9461}, + {0x9462, 0x9462}, {0x9463, 0x9463}, {0x9464, 0x9464}, {0x9465, 0x9465}, {0x9466, 0x9466}, {0x9467, 0x9467}, {0x9468, 0x9468}, + {0x9469, 0x9469}, {0x946A, 0x946A}, {0x946B, 0x946B}, {0x946C, 0x946C}, {0x946D, 0x946D}, {0x946E, 0x946E}, {0x946F, 0x946F}, + {0x9470, 0x9470}, {0x9471, 0x9471}, {0x9472, 0x9472}, {0x9473, 0x9473}, {0x9474, 0x9474}, {0x9475, 0x9475}, {0x9476, 0x9476}, + {0x9477, 0x9477}, {0x9478, 0x9478}, {0x9479, 0x9479}, {0x947A, 0x947A}, {0x947B, 0x947B}, {0x947C, 0x947C}, {0x947D, 0x947D}, + {0x947E, 0x947E}, {0x947F, 0x947F}, {0x9480, 0x9480}, {0x9481, 0x9481}, {0x9482, 0x9482}, {0x9483, 0x9483}, {0x9484, 0x9484}, + {0x9485, 0x9485}, {0x9486, 0x9486}, {0x9487, 0x9487}, {0x9488, 0x9488}, {0x9489, 0x9489}, {0x948A, 0x948A}, {0x948B, 0x948B}, + {0x948C, 0x948C}, {0x948D, 0x948D}, {0x948E, 0x948E}, {0x948F, 0x948F}, {0x9490, 0x9490}, {0x9491, 0x9491}, {0x9492, 0x9492}, + {0x9493, 0x9493}, {0x9494, 0x9494}, {0x9495, 0x9495}, {0x9496, 0x9496}, {0x9497, 0x9497}, {0x9498, 0x9498}, {0x9499, 0x9499}, + {0x949A, 0x949A}, {0x949B, 0x949B}, {0x949C, 0x949C}, {0x949D, 0x949D}, {0x949E, 0x949E}, {0x949F, 0x949F}, {0x94A0, 0x94A0}, + {0x94A1, 0x94A1}, {0x94A2, 0x94A2}, {0x94A3, 0x94A3}, {0x94A4, 0x94A4}, {0x94A5, 0x94A5}, {0x94A6, 0x94A6}, {0x94A7, 0x94A7}, + {0x94A8, 0x94A8}, {0x94A9, 0x94A9}, {0x94AA, 0x94AA}, {0x94AB, 0x94AB}, {0x94AC, 0x94AC}, {0x94AD, 0x94AD}, {0x94AE, 0x94AE}, + {0x94AF, 0x94AF}, {0x94B0, 0x94B0}, {0x94B1, 0x94B1}, {0x94B2, 0x94B2}, {0x94B3, 0x94B3}, {0x94B4, 0x94B4}, {0x94B5, 0x94B5}, + {0x94B6, 0x94B6}, {0x94B7, 0x94B7}, {0x94B8, 0x94B8}, {0x94B9, 0x94B9}, {0x94BA, 0x94BA}, {0x94BB, 0x94BB}, {0x94BC, 0x94BC}, + {0x94BD, 0x94BD}, {0x94BE, 0x94BE}, {0x94BF, 0x94BF}, {0x94C0, 0x94C0}, {0x94C1, 0x94C1}, {0x94C2, 0x94C2}, {0x94C3, 0x94C3}, + {0x94C4, 0x94C4}, {0x94C5, 0x94C5}, {0x94C6, 0x94C6}, {0x94C7, 0x94C7}, {0x94C8, 0x94C8}, {0x94C9, 0x94C9}, {0x94CA, 0x94CA}, + {0x94CB, 0x94CB}, {0x94CC, 0x94CC}, {0x94CD, 0x94CD}, {0x94CE, 0x94CE}, {0x94CF, 0x94CF}, {0x94D0, 0x94D0}, {0x94D1, 0x94D1}, + {0x94D2, 0x94D2}, {0x94D3, 0x94D3}, {0x94D4, 0x94D4}, {0x94D5, 0x94D5}, {0x94D6, 0x94D6}, {0x94D7, 0x94D7}, {0x94D8, 0x94D8}, + {0x94D9, 0x94D9}, {0x94DA, 0x94DA}, {0x94DB, 0x94DB}, {0x94DC, 0x94DC}, {0x94DD, 0x94DD}, {0x94DE, 0x94DE}, {0x94DF, 0x94DF}, + {0x94E0, 0x94E0}, {0x94E1, 0x94E1}, {0x94E2, 0x94E2}, {0x94E3, 0x94E3}, {0x94E4, 0x94E4}, {0x94E5, 0x94E5}, {0x94E6, 0x94E6}, + {0x94E7, 0x94E7}, {0x94E8, 0x94E8}, {0x94E9, 0x94E9}, {0x94EA, 0x94EA}, {0x94EB, 0x94EB}, {0x94EC, 0x94EC}, {0x94ED, 0x94ED}, + {0x94EE, 0x94EE}, {0x94EF, 0x94EF}, {0x94F0, 0x94F0}, {0x94F1, 0x94F1}, {0x94F2, 0x94F2}, {0x94F3, 0x94F3}, {0x94F4, 0x94F4}, + {0x94F5, 0x94F5}, {0x94F6, 0x94F6}, {0x94F7, 0x94F7}, {0x94F8, 0x94F8}, {0x94F9, 0x94F9}, {0x94FA, 0x94FA}, {0x94FB, 0x94FB}, + {0x94FC, 0x94FC}, {0x94FD, 0x94FD}, {0x94FE, 0x94FE}, {0x94FF, 0x94FF}, {0x9500, 0x9500}, {0x9501, 0x9501}, {0x9502, 0x9502}, + {0x9503, 0x9503}, {0x9504, 0x9504}, {0x9505, 0x9505}, {0x9506, 0x9506}, {0x9507, 0x9507}, {0x9508, 0x9508}, {0x9509, 0x9509}, + {0x950A, 0x950A}, {0x950B, 0x950B}, {0x950C, 0x950C}, {0x950D, 0x950D}, {0x950E, 0x950E}, {0x950F, 0x950F}, {0x9510, 0x9510}, + {0x9511, 0x9511}, {0x9512, 0x9512}, {0x9513, 0x9513}, {0x9514, 0x9514}, {0x9515, 0x9515}, {0x9516, 0x9516}, {0x9517, 0x9517}, + {0x9518, 0x9518}, {0x9519, 0x9519}, {0x951A, 0x951A}, {0x951B, 0x951B}, {0x951C, 0x951C}, {0x951D, 0x951D}, {0x951E, 0x951E}, + {0x951F, 0x951F}, {0x9520, 0x9520}, {0x9521, 0x9521}, {0x9522, 0x9522}, {0x9523, 0x9523}, {0x9524, 0x9524}, {0x9525, 0x9525}, + {0x9526, 0x9526}, {0x9527, 0x9527}, {0x9528, 0x9528}, {0x9529, 0x9529}, {0x952A, 0x952A}, {0x952B, 0x952B}, {0x952C, 0x952C}, + {0x952D, 0x952D}, {0x952E, 0x952E}, {0x952F, 0x952F}, {0x9530, 0x9530}, {0x9531, 0x9531}, {0x9532, 0x9532}, {0x9533, 0x9533}, + {0x9534, 0x9534}, {0x9535, 0x9535}, {0x9536, 0x9536}, {0x9537, 0x9537}, {0x9538, 0x9538}, {0x9539, 0x9539}, {0x953A, 0x953A}, + {0x953B, 0x953B}, {0x953C, 0x953C}, {0x953D, 0x953D}, {0x953E, 0x953E}, {0x953F, 0x953F}, {0x9540, 0x9540}, {0x9541, 0x9541}, + {0x9542, 0x9542}, {0x9543, 0x9543}, {0x9544, 0x9544}, {0x9545, 0x9545}, {0x9546, 0x9546}, {0x9547, 0x9547}, {0x9548, 0x9548}, + {0x9549, 0x9549}, {0x954A, 0x954A}, {0x954B, 0x954B}, {0x954C, 0x954C}, {0x954D, 0x954D}, {0x954E, 0x954E}, {0x954F, 0x954F}, + {0x9550, 0x9550}, {0x9551, 0x9551}, {0x9552, 0x9552}, {0x9553, 0x9553}, {0x9554, 0x9554}, {0x9555, 0x9555}, {0x9556, 0x9556}, + {0x9557, 0x9557}, {0x9558, 0x9558}, {0x9559, 0x9559}, {0x955A, 0x955A}, {0x955B, 0x955B}, {0x955C, 0x955C}, {0x955D, 0x955D}, + {0x955E, 0x955E}, {0x955F, 0x955F}, {0x9560, 0x9560}, {0x9561, 0x9561}, {0x9562, 0x9562}, {0x9563, 0x9563}, {0x9564, 0x9564}, + {0x9565, 0x9565}, {0x9566, 0x9566}, {0x9567, 0x9567}, {0x9568, 0x9568}, {0x9569, 0x9569}, {0x956A, 0x956A}, {0x956B, 0x956B}, + {0x956C, 0x956C}, {0x956D, 0x956D}, {0x956E, 0x956E}, {0x956F, 0x956F}, {0x9570, 0x9570}, {0x9571, 0x9571}, {0x9572, 0x9572}, + {0x9573, 0x9573}, {0x9574, 0x9574}, {0x9575, 0x9575}, {0x9576, 0x9576}, {0x9577, 0x9577}, {0x9578, 0x9578}, {0x9579, 0x9579}, + {0x957A, 0x957A}, {0x957B, 0x957B}, {0x957C, 0x957C}, {0x957D, 0x957D}, {0x957E, 0x957E}, {0x957F, 0x957F}, {0x9580, 0x9580}, + {0x9581, 0x9581}, {0x9582, 0x9582}, {0x9583, 0x9583}, {0x9584, 0x9584}, {0x9585, 0x9585}, {0x9586, 0x9586}, {0x9587, 0x9587}, + {0x9588, 0x9588}, {0x9589, 0x9589}, {0x958A, 0x958A}, {0x958B, 0x958B}, {0x958C, 0x958C}, {0x958D, 0x958D}, {0x958E, 0x958E}, + {0x958F, 0x958F}, {0x9590, 0x9590}, {0x9591, 0x9591}, {0x9592, 0x9592}, {0x9593, 0x9593}, {0x9594, 0x9594}, {0x9595, 0x9595}, + {0x9596, 0x9596}, {0x9597, 0x9597}, {0x9598, 0x9598}, {0x9599, 0x9599}, {0x959A, 0x959A}, {0x959B, 0x959B}, {0x959C, 0x959C}, + {0x959D, 0x959D}, {0x959E, 0x959E}, {0x959F, 0x959F}, {0x95A0, 0x95A0}, {0x95A1, 0x95A1}, {0x95A2, 0x95A2}, {0x95A3, 0x95A3}, + {0x95A4, 0x95A4}, {0x95A5, 0x95A5}, {0x95A6, 0x95A6}, {0x95A7, 0x95A7}, {0x95A8, 0x95A8}, {0x95A9, 0x95A9}, {0x95AA, 0x95AA}, + {0x95AB, 0x95AB}, {0x95AC, 0x95AC}, {0x95AD, 0x95AD}, {0x95AE, 0x95AE}, {0x95AF, 0x95AF}, {0x95B0, 0x95B0}, {0x95B1, 0x95B1}, + {0x95B2, 0x95B2}, {0x95B3, 0x95B3}, {0x95B4, 0x95B4}, {0x95B5, 0x95B5}, {0x95B6, 0x95B6}, {0x95B7, 0x95B7}, {0x95B8, 0x95B8}, + {0x95B9, 0x95B9}, {0x95BA, 0x95BA}, {0x95BB, 0x95BB}, {0x95BC, 0x95BC}, {0x95BD, 0x95BD}, {0x95BE, 0x95BE}, {0x95BF, 0x95BF}, + {0x95C0, 0x95C0}, {0x95C1, 0x95C1}, {0x95C2, 0x95C2}, {0x95C3, 0x95C3}, {0x95C4, 0x95C4}, {0x95C5, 0x95C5}, {0x95C6, 0x95C6}, + {0x95C7, 0x95C7}, {0x95C8, 0x95C8}, {0x95C9, 0x95C9}, {0x95CA, 0x95CA}, {0x95CB, 0x95CB}, {0x95CC, 0x95CC}, {0x95CD, 0x95CD}, + {0x95CE, 0x95CE}, {0x95CF, 0x95CF}, {0x95D0, 0x95D0}, {0x95D1, 0x95D1}, {0x95D2, 0x95D2}, {0x95D3, 0x95D3}, {0x95D4, 0x95D4}, + {0x95D5, 0x95D5}, {0x95D6, 0x95D6}, {0x95D7, 0x95D7}, {0x95D8, 0x95D8}, {0x95D9, 0x95D9}, {0x95DA, 0x95DA}, {0x95DB, 0x95DB}, + {0x95DC, 0x95DC}, {0x95DD, 0x95DD}, {0x95DE, 0x95DE}, {0x95DF, 0x95DF}, {0x95E0, 0x95E0}, {0x95E1, 0x95E1}, {0x95E2, 0x95E2}, + {0x95E3, 0x95E3}, {0x95E4, 0x95E4}, {0x95E5, 0x95E5}, {0x95E6, 0x95E6}, {0x95E7, 0x95E7}, {0x95E8, 0x95E8}, {0x95E9, 0x95E9}, + {0x95EA, 0x95EA}, {0x95EB, 0x95EB}, {0x95EC, 0x95EC}, {0x95ED, 0x95ED}, {0x95EE, 0x95EE}, {0x95EF, 0x95EF}, {0x95F0, 0x95F0}, + {0x95F1, 0x95F1}, {0x95F2, 0x95F2}, {0x95F3, 0x95F3}, {0x95F4, 0x95F4}, {0x95F5, 0x95F5}, {0x95F6, 0x95F6}, {0x95F7, 0x95F7}, + {0x95F8, 0x95F8}, {0x95F9, 0x95F9}, {0x95FA, 0x95FA}, {0x95FB, 0x95FB}, {0x95FC, 0x95FC}, {0x95FD, 0x95FD}, {0x95FE, 0x95FE}, + {0x95FF, 0x95FF}, {0x9600, 0x9600}, {0x9601, 0x9601}, {0x9602, 0x9602}, {0x9603, 0x9603}, {0x9604, 0x9604}, {0x9605, 0x9605}, + {0x9606, 0x9606}, {0x9607, 0x9607}, {0x9608, 0x9608}, {0x9609, 0x9609}, {0x960A, 0x960A}, {0x960B, 0x960B}, {0x960C, 0x960C}, + {0x960D, 0x960D}, {0x960E, 0x960E}, {0x960F, 0x960F}, {0x9610, 0x9610}, {0x9611, 0x9611}, {0x9612, 0x9612}, {0x9613, 0x9613}, + {0x9614, 0x9614}, {0x9615, 0x9615}, {0x9616, 0x9616}, {0x9617, 0x9617}, {0x9618, 0x9618}, {0x9619, 0x9619}, {0x961A, 0x961A}, + {0x961B, 0x961B}, {0x961C, 0x961C}, {0x961D, 0x961D}, {0x961E, 0x961E}, {0x961F, 0x961F}, {0x9620, 0x9620}, {0x9621, 0x9621}, + {0x9622, 0x9622}, {0x9623, 0x9623}, {0x9624, 0x9624}, {0x9625, 0x9625}, {0x9626, 0x9626}, {0x9627, 0x9627}, {0x9628, 0x9628}, + {0x9629, 0x9629}, {0x962A, 0x962A}, {0x962B, 0x962B}, {0x962C, 0x962C}, {0x962D, 0x962D}, {0x962E, 0x962E}, {0x962F, 0x962F}, + {0x9630, 0x9630}, {0x9631, 0x9631}, {0x9632, 0x9632}, {0x9633, 0x9633}, {0x9634, 0x9634}, {0x9635, 0x9635}, {0x9636, 0x9636}, + {0x9637, 0x9637}, {0x9638, 0x9638}, {0x9639, 0x9639}, {0x963A, 0x963A}, {0x963B, 0x963B}, {0x963C, 0x963C}, {0x963D, 0x963D}, + {0x963E, 0x963E}, {0x963F, 0x963F}, {0x9640, 0x9640}, {0x9641, 0x9641}, {0x9642, 0x9642}, {0x9643, 0x9643}, {0x9644, 0x9644}, + {0x9645, 0x9645}, {0x9646, 0x9646}, {0x9647, 0x9647}, {0x9648, 0x9648}, {0x9649, 0x9649}, {0x964A, 0x964A}, {0x964B, 0x964B}, + {0x964C, 0x964C}, {0x964D, 0x964D}, {0x964E, 0x964E}, {0x964F, 0x964F}, {0x9650, 0x9650}, {0x9651, 0x9651}, {0x9652, 0x9652}, + {0x9653, 0x9653}, {0x9654, 0x9654}, {0x9655, 0x9655}, {0x9656, 0x9656}, {0x9657, 0x9657}, {0x9658, 0x9658}, {0x9659, 0x9659}, + {0x965A, 0x965A}, {0x965B, 0x965B}, {0x965C, 0x965C}, {0x965D, 0x965D}, {0x965E, 0x965E}, {0x965F, 0x965F}, {0x9660, 0x9660}, + {0x9661, 0x9661}, {0x9662, 0x9662}, {0x9663, 0x9663}, {0x9664, 0x9664}, {0x9665, 0x9665}, {0x9666, 0x9666}, {0x9667, 0x9667}, + {0x9668, 0x9668}, {0x9669, 0x9669}, {0x966A, 0x966A}, {0x966B, 0x966B}, {0x966C, 0x966C}, {0x966D, 0x966D}, {0x966E, 0x966E}, + {0x966F, 0x966F}, {0x9670, 0x9670}, {0x9671, 0x9671}, {0x9672, 0x9672}, {0x9673, 0x9673}, {0x9674, 0x9674}, {0x9675, 0x9675}, + {0x9676, 0x9676}, {0x9677, 0x9677}, {0x9678, 0x9678}, {0x9679, 0x9679}, {0x967A, 0x967A}, {0x967B, 0x967B}, {0x967C, 0x967C}, + {0x967D, 0x967D}, {0x967E, 0x967E}, {0x967F, 0x967F}, {0x9680, 0x9680}, {0x9681, 0x9681}, {0x9682, 0x9682}, {0x9683, 0x9683}, + {0x9684, 0x9684}, {0x9685, 0x9685}, {0x9686, 0x9686}, {0x9687, 0x9687}, {0x9688, 0x9688}, {0x9689, 0x9689}, {0x968A, 0x968A}, + {0x968B, 0x968B}, {0x968C, 0x968C}, {0x968D, 0x968D}, {0x968E, 0x968E}, {0x968F, 0x968F}, {0x9690, 0x9690}, {0x9691, 0x9691}, + {0x9692, 0x9692}, {0x9693, 0x9693}, {0x9694, 0x9694}, {0x9695, 0x9695}, {0x9696, 0x9696}, {0x9697, 0x9697}, {0x9698, 0x9698}, + {0x9699, 0x9699}, {0x969A, 0x969A}, {0x969B, 0x969B}, {0x969C, 0x969C}, {0x969D, 0x969D}, {0x969E, 0x969E}, {0x969F, 0x969F}, + {0x96A0, 0x96A0}, {0x96A1, 0x96A1}, {0x96A2, 0x96A2}, {0x96A3, 0x96A3}, {0x96A4, 0x96A4}, {0x96A5, 0x96A5}, {0x96A6, 0x96A6}, + {0x96A7, 0x96A7}, {0x96A8, 0x96A8}, {0x96A9, 0x96A9}, {0x96AA, 0x96AA}, {0x96AB, 0x96AB}, {0x96AC, 0x96AC}, {0x96AD, 0x96AD}, + {0x96AE, 0x96AE}, {0x96AF, 0x96AF}, {0x96B0, 0x96B0}, {0x96B1, 0x96B1}, {0x96B2, 0x96B2}, {0x96B3, 0x96B3}, {0x96B4, 0x96B4}, + {0x96B5, 0x96B5}, {0x96B6, 0x96B6}, {0x96B7, 0x96B7}, {0x96B8, 0x96B8}, {0x96B9, 0x96B9}, {0x96BA, 0x96BA}, {0x96BB, 0x96BB}, + {0x96BC, 0x96BC}, {0x96BD, 0x96BD}, {0x96BE, 0x96BE}, {0x96BF, 0x96BF}, {0x96C0, 0x96C0}, {0x96C1, 0x96C1}, {0x96C2, 0x96C2}, + {0x96C3, 0x96C3}, {0x96C4, 0x96C4}, {0x96C5, 0x96C5}, {0x96C6, 0x96C6}, {0x96C7, 0x96C7}, {0x96C8, 0x96C8}, {0x96C9, 0x96C9}, + {0x96CA, 0x96CA}, {0x96CB, 0x96CB}, {0x96CC, 0x96CC}, {0x96CD, 0x96CD}, {0x96CE, 0x96CE}, {0x96CF, 0x96CF}, {0x96D0, 0x96D0}, + {0x96D1, 0x96D1}, {0x96D2, 0x96D2}, {0x96D3, 0x96D3}, {0x96D4, 0x96D4}, {0x96D5, 0x96D5}, {0x96D6, 0x96D6}, {0x96D7, 0x96D7}, + {0x96D8, 0x96D8}, {0x96D9, 0x96D9}, {0x96DA, 0x96DA}, {0x96DB, 0x96DB}, {0x96DC, 0x96DC}, {0x96DD, 0x96DD}, {0x96DE, 0x96DE}, + {0x96DF, 0x96DF}, {0x96E0, 0x96E0}, {0x96E1, 0x96E1}, {0x96E2, 0x96E2}, {0x96E3, 0x96E3}, {0x96E4, 0x96E4}, {0x96E5, 0x96E5}, + {0x96E6, 0x96E6}, {0x96E7, 0x96E7}, {0x96E8, 0x96E8}, {0x96E9, 0x96E9}, {0x96EA, 0x96EA}, {0x96EB, 0x96EB}, {0x96EC, 0x96EC}, + {0x96ED, 0x96ED}, {0x96EE, 0x96EE}, {0x96EF, 0x96EF}, {0x96F0, 0x96F0}, {0x96F1, 0x96F1}, {0x96F2, 0x96F2}, {0x96F3, 0x96F3}, + {0x96F4, 0x96F4}, {0x96F5, 0x96F5}, {0x96F6, 0x96F6}, {0x96F7, 0x96F7}, {0x96F8, 0x96F8}, {0x96F9, 0x96F9}, {0x96FA, 0x96FA}, + {0x96FB, 0x96FB}, {0x96FC, 0x96FC}, {0x96FD, 0x96FD}, {0x96FE, 0x96FE}, {0x96FF, 0x96FF}, {0x9700, 0x9700}, {0x9701, 0x9701}, + {0x9702, 0x9702}, {0x9703, 0x9703}, {0x9704, 0x9704}, {0x9705, 0x9705}, {0x9706, 0x9706}, {0x9707, 0x9707}, {0x9708, 0x9708}, + {0x9709, 0x9709}, {0x970A, 0x970A}, {0x970B, 0x970B}, {0x970C, 0x970C}, {0x970D, 0x970D}, {0x970E, 0x970E}, {0x970F, 0x970F}, + {0x9710, 0x9710}, {0x9711, 0x9711}, {0x9712, 0x9712}, {0x9713, 0x9713}, {0x9714, 0x9714}, {0x9715, 0x9715}, {0x9716, 0x9716}, + {0x9717, 0x9717}, {0x9718, 0x9718}, {0x9719, 0x9719}, {0x971A, 0x971A}, {0x971B, 0x971B}, {0x971C, 0x971C}, {0x971D, 0x971D}, + {0x971E, 0x971E}, {0x971F, 0x971F}, {0x9720, 0x9720}, {0x9721, 0x9721}, {0x9722, 0x9722}, {0x9723, 0x9723}, {0x9724, 0x9724}, + {0x9725, 0x9725}, {0x9726, 0x9726}, {0x9727, 0x9727}, {0x9728, 0x9728}, {0x9729, 0x9729}, {0x972A, 0x972A}, {0x972B, 0x972B}, + {0x972C, 0x972C}, {0x972D, 0x972D}, {0x972E, 0x972E}, {0x972F, 0x972F}, {0x9730, 0x9730}, {0x9731, 0x9731}, {0x9732, 0x9732}, + {0x9733, 0x9733}, {0x9734, 0x9734}, {0x9735, 0x9735}, {0x9736, 0x9736}, {0x9737, 0x9737}, {0x9738, 0x9738}, {0x9739, 0x9739}, + {0x973A, 0x973A}, {0x973B, 0x973B}, {0x973C, 0x973C}, {0x973D, 0x973D}, {0x973E, 0x973E}, {0x973F, 0x973F}, {0x9740, 0x9740}, + {0x9741, 0x9741}, {0x9742, 0x9742}, {0x9743, 0x9743}, {0x9744, 0x9744}, {0x9745, 0x9745}, {0x9746, 0x9746}, {0x9747, 0x9747}, + {0x9748, 0x9748}, {0x9749, 0x9749}, {0x974A, 0x974A}, {0x974B, 0x974B}, {0x974C, 0x974C}, {0x974D, 0x974D}, {0x974E, 0x974E}, + {0x974F, 0x974F}, {0x9750, 0x9750}, {0x9751, 0x9751}, {0x9752, 0x9752}, {0x9753, 0x9753}, {0x9754, 0x9754}, {0x9755, 0x9755}, + {0x9756, 0x9756}, {0x9757, 0x9757}, {0x9758, 0x9758}, {0x9759, 0x9759}, {0x975A, 0x975A}, {0x975B, 0x975B}, {0x975C, 0x975C}, + {0x975D, 0x975D}, {0x975E, 0x975E}, {0x975F, 0x975F}, {0x9760, 0x9760}, {0x9761, 0x9761}, {0x9762, 0x9762}, {0x9763, 0x9763}, + {0x9764, 0x9764}, {0x9765, 0x9765}, {0x9766, 0x9766}, {0x9767, 0x9767}, {0x9768, 0x9768}, {0x9769, 0x9769}, {0x976A, 0x976A}, + {0x976B, 0x976B}, {0x976C, 0x976C}, {0x976D, 0x976D}, {0x976E, 0x976E}, {0x976F, 0x976F}, {0x9770, 0x9770}, {0x9771, 0x9771}, + {0x9772, 0x9772}, {0x9773, 0x9773}, {0x9774, 0x9774}, {0x9775, 0x9775}, {0x9776, 0x9776}, {0x9777, 0x9777}, {0x9778, 0x9778}, + {0x9779, 0x9779}, {0x977A, 0x977A}, {0x977B, 0x977B}, {0x977C, 0x977C}, {0x977D, 0x977D}, {0x977E, 0x977E}, {0x977F, 0x977F}, + {0x9780, 0x9780}, {0x9781, 0x9781}, {0x9782, 0x9782}, {0x9783, 0x9783}, {0x9784, 0x9784}, {0x9785, 0x9785}, {0x9786, 0x9786}, + {0x9787, 0x9787}, {0x9788, 0x9788}, {0x9789, 0x9789}, {0x978A, 0x978A}, {0x978B, 0x978B}, {0x978C, 0x978C}, {0x978D, 0x978D}, + {0x978E, 0x978E}, {0x978F, 0x978F}, {0x9790, 0x9790}, {0x9791, 0x9791}, {0x9792, 0x9792}, {0x9793, 0x9793}, {0x9794, 0x9794}, + {0x9795, 0x9795}, {0x9796, 0x9796}, {0x9797, 0x9797}, {0x9798, 0x9798}, {0x9799, 0x9799}, {0x979A, 0x979A}, {0x979B, 0x979B}, + {0x979C, 0x979C}, {0x979D, 0x979D}, {0x979E, 0x979E}, {0x979F, 0x979F}, {0x97A0, 0x97A0}, {0x97A1, 0x97A1}, {0x97A2, 0x97A2}, + {0x97A3, 0x97A3}, {0x97A4, 0x97A4}, {0x97A5, 0x97A5}, {0x97A6, 0x97A6}, {0x97A7, 0x97A7}, {0x97A8, 0x97A8}, {0x97A9, 0x97A9}, + {0x97AA, 0x97AA}, {0x97AB, 0x97AB}, {0x97AC, 0x97AC}, {0x97AD, 0x97AD}, {0x97AE, 0x97AE}, {0x97AF, 0x97AF}, {0x97B0, 0x97B0}, + {0x97B1, 0x97B1}, {0x97B2, 0x97B2}, {0x97B3, 0x97B3}, {0x97B4, 0x97B4}, {0x97B5, 0x97B5}, {0x97B6, 0x97B6}, {0x97B7, 0x97B7}, + {0x97B8, 0x97B8}, {0x97B9, 0x97B9}, {0x97BA, 0x97BA}, {0x97BB, 0x97BB}, {0x97BC, 0x97BC}, {0x97BD, 0x97BD}, {0x97BE, 0x97BE}, + {0x97BF, 0x97BF}, {0x97C0, 0x97C0}, {0x97C1, 0x97C1}, {0x97C2, 0x97C2}, {0x97C3, 0x97C3}, {0x97C4, 0x97C4}, {0x97C5, 0x97C5}, + {0x97C6, 0x97C6}, {0x97C7, 0x97C7}, {0x97C8, 0x97C8}, {0x97C9, 0x97C9}, {0x97CA, 0x97CA}, {0x97CB, 0x97CB}, {0x97CC, 0x97CC}, + {0x97CD, 0x97CD}, {0x97CE, 0x97CE}, {0x97CF, 0x97CF}, {0x97D0, 0x97D0}, {0x97D1, 0x97D1}, {0x97D2, 0x97D2}, {0x97D3, 0x97D3}, + {0x97D4, 0x97D4}, {0x97D5, 0x97D5}, {0x97D6, 0x97D6}, {0x97D7, 0x97D7}, {0x97D8, 0x97D8}, {0x97D9, 0x97D9}, {0x97DA, 0x97DA}, + {0x97DB, 0x97DB}, {0x97DC, 0x97DC}, {0x97DD, 0x97DD}, {0x97DE, 0x97DE}, {0x97DF, 0x97DF}, {0x97E0, 0x97E0}, {0x97E1, 0x97E1}, + {0x97E2, 0x97E2}, {0x97E3, 0x97E3}, {0x97E4, 0x97E4}, {0x97E5, 0x97E5}, {0x97E6, 0x97E6}, {0x97E7, 0x97E7}, {0x97E8, 0x97E8}, + {0x97E9, 0x97E9}, {0x97EA, 0x97EA}, {0x97EB, 0x97EB}, {0x97EC, 0x97EC}, {0x97ED, 0x97ED}, {0x97EE, 0x97EE}, {0x97EF, 0x97EF}, + {0x97F0, 0x97F0}, {0x97F1, 0x97F1}, {0x97F2, 0x97F2}, {0x97F3, 0x97F3}, {0x97F4, 0x97F4}, {0x97F5, 0x97F5}, {0x97F6, 0x97F6}, + {0x97F7, 0x97F7}, {0x97F8, 0x97F8}, {0x97F9, 0x97F9}, {0x97FA, 0x97FA}, {0x97FB, 0x97FB}, {0x97FC, 0x97FC}, {0x97FD, 0x97FD}, + {0x97FE, 0x97FE}, {0x97FF, 0x97FF}, {0x9800, 0x9800}, {0x9801, 0x9801}, {0x9802, 0x9802}, {0x9803, 0x9803}, {0x9804, 0x9804}, + {0x9805, 0x9805}, {0x9806, 0x9806}, {0x9807, 0x9807}, {0x9808, 0x9808}, {0x9809, 0x9809}, {0x980A, 0x980A}, {0x980B, 0x980B}, + {0x980C, 0x980C}, {0x980D, 0x980D}, {0x980E, 0x980E}, {0x980F, 0x980F}, {0x9810, 0x9810}, {0x9811, 0x9811}, {0x9812, 0x9812}, + {0x9813, 0x9813}, {0x9814, 0x9814}, {0x9815, 0x9815}, {0x9816, 0x9816}, {0x9817, 0x9817}, {0x9818, 0x9818}, {0x9819, 0x9819}, + {0x981A, 0x981A}, {0x981B, 0x981B}, {0x981C, 0x981C}, {0x981D, 0x981D}, {0x981E, 0x981E}, {0x981F, 0x981F}, {0x9820, 0x9820}, + {0x9821, 0x9821}, {0x9822, 0x9822}, {0x9823, 0x9823}, {0x9824, 0x9824}, {0x9825, 0x9825}, {0x9826, 0x9826}, {0x9827, 0x9827}, + {0x9828, 0x9828}, {0x9829, 0x9829}, {0x982A, 0x982A}, {0x982B, 0x982B}, {0x982C, 0x982C}, {0x982D, 0x982D}, {0x982E, 0x982E}, + {0x982F, 0x982F}, {0x9830, 0x9830}, {0x9831, 0x9831}, {0x9832, 0x9832}, {0x9833, 0x9833}, {0x9834, 0x9834}, {0x9835, 0x9835}, + {0x9836, 0x9836}, {0x9837, 0x9837}, {0x9838, 0x9838}, {0x9839, 0x9839}, {0x983A, 0x983A}, {0x983B, 0x983B}, {0x983C, 0x983C}, + {0x983D, 0x983D}, {0x983E, 0x983E}, {0x983F, 0x983F}, {0x9840, 0x9840}, {0x9841, 0x9841}, {0x9842, 0x9842}, {0x9843, 0x9843}, + {0x9844, 0x9844}, {0x9845, 0x9845}, {0x9846, 0x9846}, {0x9847, 0x9847}, {0x9848, 0x9848}, {0x9849, 0x9849}, {0x984A, 0x984A}, + {0x984B, 0x984B}, {0x984C, 0x984C}, {0x984D, 0x984D}, {0x984E, 0x984E}, {0x984F, 0x984F}, {0x9850, 0x9850}, {0x9851, 0x9851}, + {0x9852, 0x9852}, {0x9853, 0x9853}, {0x9854, 0x9854}, {0x9855, 0x9855}, {0x9856, 0x9856}, {0x9857, 0x9857}, {0x9858, 0x9858}, + {0x9859, 0x9859}, {0x985A, 0x985A}, {0x985B, 0x985B}, {0x985C, 0x985C}, {0x985D, 0x985D}, {0x985E, 0x985E}, {0x985F, 0x985F}, + {0x9860, 0x9860}, {0x9861, 0x9861}, {0x9862, 0x9862}, {0x9863, 0x9863}, {0x9864, 0x9864}, {0x9865, 0x9865}, {0x9866, 0x9866}, + {0x9867, 0x9867}, {0x9868, 0x9868}, {0x9869, 0x9869}, {0x986A, 0x986A}, {0x986B, 0x986B}, {0x986C, 0x986C}, {0x986D, 0x986D}, + {0x986E, 0x986E}, {0x986F, 0x986F}, {0x9870, 0x9870}, {0x9871, 0x9871}, {0x9872, 0x9872}, {0x9873, 0x9873}, {0x9874, 0x9874}, + {0x9875, 0x9875}, {0x9876, 0x9876}, {0x9877, 0x9877}, {0x9878, 0x9878}, {0x9879, 0x9879}, {0x987A, 0x987A}, {0x987B, 0x987B}, + {0x987C, 0x987C}, {0x987D, 0x987D}, {0x987E, 0x987E}, {0x987F, 0x987F}, {0x9880, 0x9880}, {0x9881, 0x9881}, {0x9882, 0x9882}, + {0x9883, 0x9883}, {0x9884, 0x9884}, {0x9885, 0x9885}, {0x9886, 0x9886}, {0x9887, 0x9887}, {0x9888, 0x9888}, {0x9889, 0x9889}, + {0x988A, 0x988A}, {0x988B, 0x988B}, {0x988C, 0x988C}, {0x988D, 0x988D}, {0x988E, 0x988E}, {0x988F, 0x988F}, {0x9890, 0x9890}, + {0x9891, 0x9891}, {0x9892, 0x9892}, {0x9893, 0x9893}, {0x9894, 0x9894}, {0x9895, 0x9895}, {0x9896, 0x9896}, {0x9897, 0x9897}, + {0x9898, 0x9898}, {0x9899, 0x9899}, {0x989A, 0x989A}, {0x989B, 0x989B}, {0x989C, 0x989C}, {0x989D, 0x989D}, {0x989E, 0x989E}, + {0x989F, 0x989F}, {0x98A0, 0x98A0}, {0x98A1, 0x98A1}, {0x98A2, 0x98A2}, {0x98A3, 0x98A3}, {0x98A4, 0x98A4}, {0x98A5, 0x98A5}, + {0x98A6, 0x98A6}, {0x98A7, 0x98A7}, {0x98A8, 0x98A8}, {0x98A9, 0x98A9}, {0x98AA, 0x98AA}, {0x98AB, 0x98AB}, {0x98AC, 0x98AC}, + {0x98AD, 0x98AD}, {0x98AE, 0x98AE}, {0x98AF, 0x98AF}, {0x98B0, 0x98B0}, {0x98B1, 0x98B1}, {0x98B2, 0x98B2}, {0x98B3, 0x98B3}, + {0x98B4, 0x98B4}, {0x98B5, 0x98B5}, {0x98B6, 0x98B6}, {0x98B7, 0x98B7}, {0x98B8, 0x98B8}, {0x98B9, 0x98B9}, {0x98BA, 0x98BA}, + {0x98BB, 0x98BB}, {0x98BC, 0x98BC}, {0x98BD, 0x98BD}, {0x98BE, 0x98BE}, {0x98BF, 0x98BF}, {0x98C0, 0x98C0}, {0x98C1, 0x98C1}, + {0x98C2, 0x98C2}, {0x98C3, 0x98C3}, {0x98C4, 0x98C4}, {0x98C5, 0x98C5}, {0x98C6, 0x98C6}, {0x98C7, 0x98C7}, {0x98C8, 0x98C8}, + {0x98C9, 0x98C9}, {0x98CA, 0x98CA}, {0x98CB, 0x98CB}, {0x98CC, 0x98CC}, {0x98CD, 0x98CD}, {0x98CE, 0x98CE}, {0x98CF, 0x98CF}, + {0x98D0, 0x98D0}, {0x98D1, 0x98D1}, {0x98D2, 0x98D2}, {0x98D3, 0x98D3}, {0x98D4, 0x98D4}, {0x98D5, 0x98D5}, {0x98D6, 0x98D6}, + {0x98D7, 0x98D7}, {0x98D8, 0x98D8}, {0x98D9, 0x98D9}, {0x98DA, 0x98DA}, {0x98DB, 0x98DB}, {0x98DC, 0x98DC}, {0x98DD, 0x98DD}, + {0x98DE, 0x98DE}, {0x98DF, 0x98DF}, {0x98E0, 0x98E0}, {0x98E1, 0x98E1}, {0x98E2, 0x98E2}, {0x98E3, 0x98E3}, {0x98E4, 0x98E4}, + {0x98E5, 0x98E5}, {0x98E6, 0x98E6}, {0x98E7, 0x98E7}, {0x98E8, 0x98E8}, {0x98E9, 0x98E9}, {0x98EA, 0x98EA}, {0x98EB, 0x98EB}, + {0x98EC, 0x98EC}, {0x98ED, 0x98ED}, {0x98EE, 0x98EE}, {0x98EF, 0x98EF}, {0x98F0, 0x98F0}, {0x98F1, 0x98F1}, {0x98F2, 0x98F2}, + {0x98F3, 0x98F3}, {0x98F4, 0x98F4}, {0x98F5, 0x98F5}, {0x98F6, 0x98F6}, {0x98F7, 0x98F7}, {0x98F8, 0x98F8}, {0x98F9, 0x98F9}, + {0x98FA, 0x98FA}, {0x98FB, 0x98FB}, {0x98FC, 0x98FC}, {0x98FD, 0x98FD}, {0x98FE, 0x98FE}, {0x98FF, 0x98FF}, {0x9900, 0x9900}, + {0x9901, 0x9901}, {0x9902, 0x9902}, {0x9903, 0x9903}, {0x9904, 0x9904}, {0x9905, 0x9905}, {0x9906, 0x9906}, {0x9907, 0x9907}, + {0x9908, 0x9908}, {0x9909, 0x9909}, {0x990A, 0x990A}, {0x990B, 0x990B}, {0x990C, 0x990C}, {0x990D, 0x990D}, {0x990E, 0x990E}, + {0x990F, 0x990F}, {0x9910, 0x9910}, {0x9911, 0x9911}, {0x9912, 0x9912}, {0x9913, 0x9913}, {0x9914, 0x9914}, {0x9915, 0x9915}, + {0x9916, 0x9916}, {0x9917, 0x9917}, {0x9918, 0x9918}, {0x9919, 0x9919}, {0x991A, 0x991A}, {0x991B, 0x991B}, {0x991C, 0x991C}, + {0x991D, 0x991D}, {0x991E, 0x991E}, {0x991F, 0x991F}, {0x9920, 0x9920}, {0x9921, 0x9921}, {0x9922, 0x9922}, {0x9923, 0x9923}, + {0x9924, 0x9924}, {0x9925, 0x9925}, {0x9926, 0x9926}, {0x9927, 0x9927}, {0x9928, 0x9928}, {0x9929, 0x9929}, {0x992A, 0x992A}, + {0x992B, 0x992B}, {0x992C, 0x992C}, {0x992D, 0x992D}, {0x992E, 0x992E}, {0x992F, 0x992F}, {0x9930, 0x9930}, {0x9931, 0x9931}, + {0x9932, 0x9932}, {0x9933, 0x9933}, {0x9934, 0x9934}, {0x9935, 0x9935}, {0x9936, 0x9936}, {0x9937, 0x9937}, {0x9938, 0x9938}, + {0x9939, 0x9939}, {0x993A, 0x993A}, {0x993B, 0x993B}, {0x993C, 0x993C}, {0x993D, 0x993D}, {0x993E, 0x993E}, {0x993F, 0x993F}, + {0x9940, 0x9940}, {0x9941, 0x9941}, {0x9942, 0x9942}, {0x9943, 0x9943}, {0x9944, 0x9944}, {0x9945, 0x9945}, {0x9946, 0x9946}, + {0x9947, 0x9947}, {0x9948, 0x9948}, {0x9949, 0x9949}, {0x994A, 0x994A}, {0x994B, 0x994B}, {0x994C, 0x994C}, {0x994D, 0x994D}, + {0x994E, 0x994E}, {0x994F, 0x994F}, {0x9950, 0x9950}, {0x9951, 0x9951}, {0x9952, 0x9952}, {0x9953, 0x9953}, {0x9954, 0x9954}, + {0x9955, 0x9955}, {0x9956, 0x9956}, {0x9957, 0x9957}, {0x9958, 0x9958}, {0x9959, 0x9959}, {0x995A, 0x995A}, {0x995B, 0x995B}, + {0x995C, 0x995C}, {0x995D, 0x995D}, {0x995E, 0x995E}, {0x995F, 0x995F}, {0x9960, 0x9960}, {0x9961, 0x9961}, {0x9962, 0x9962}, + {0x9963, 0x9963}, {0x9964, 0x9964}, {0x9965, 0x9965}, {0x9966, 0x9966}, {0x9967, 0x9967}, {0x9968, 0x9968}, {0x9969, 0x9969}, + {0x996A, 0x996A}, {0x996B, 0x996B}, {0x996C, 0x996C}, {0x996D, 0x996D}, {0x996E, 0x996E}, {0x996F, 0x996F}, {0x9970, 0x9970}, + {0x9971, 0x9971}, {0x9972, 0x9972}, {0x9973, 0x9973}, {0x9974, 0x9974}, {0x9975, 0x9975}, {0x9976, 0x9976}, {0x9977, 0x9977}, + {0x9978, 0x9978}, {0x9979, 0x9979}, {0x997A, 0x997A}, {0x997B, 0x997B}, {0x997C, 0x997C}, {0x997D, 0x997D}, {0x997E, 0x997E}, + {0x997F, 0x997F}, {0x9980, 0x9980}, {0x9981, 0x9981}, {0x9982, 0x9982}, {0x9983, 0x9983}, {0x9984, 0x9984}, {0x9985, 0x9985}, + {0x9986, 0x9986}, {0x9987, 0x9987}, {0x9988, 0x9988}, {0x9989, 0x9989}, {0x998A, 0x998A}, {0x998B, 0x998B}, {0x998C, 0x998C}, + {0x998D, 0x998D}, {0x998E, 0x998E}, {0x998F, 0x998F}, {0x9990, 0x9990}, {0x9991, 0x9991}, {0x9992, 0x9992}, {0x9993, 0x9993}, + {0x9994, 0x9994}, {0x9995, 0x9995}, {0x9996, 0x9996}, {0x9997, 0x9997}, {0x9998, 0x9998}, {0x9999, 0x9999}, {0x999A, 0x999A}, + {0x999B, 0x999B}, {0x999C, 0x999C}, {0x999D, 0x999D}, {0x999E, 0x999E}, {0x999F, 0x999F}, {0x99A0, 0x99A0}, {0x99A1, 0x99A1}, + {0x99A2, 0x99A2}, {0x99A3, 0x99A3}, {0x99A4, 0x99A4}, {0x99A5, 0x99A5}, {0x99A6, 0x99A6}, {0x99A7, 0x99A7}, {0x99A8, 0x99A8}, + {0x99A9, 0x99A9}, {0x99AA, 0x99AA}, {0x99AB, 0x99AB}, {0x99AC, 0x99AC}, {0x99AD, 0x99AD}, {0x99AE, 0x99AE}, {0x99AF, 0x99AF}, + {0x99B0, 0x99B0}, {0x99B1, 0x99B1}, {0x99B2, 0x99B2}, {0x99B3, 0x99B3}, {0x99B4, 0x99B4}, {0x99B5, 0x99B5}, {0x99B6, 0x99B6}, + {0x99B7, 0x99B7}, {0x99B8, 0x99B8}, {0x99B9, 0x99B9}, {0x99BA, 0x99BA}, {0x99BB, 0x99BB}, {0x99BC, 0x99BC}, {0x99BD, 0x99BD}, + {0x99BE, 0x99BE}, {0x99BF, 0x99BF}, {0x99C0, 0x99C0}, {0x99C1, 0x99C1}, {0x99C2, 0x99C2}, {0x99C3, 0x99C3}, {0x99C4, 0x99C4}, + {0x99C5, 0x99C5}, {0x99C6, 0x99C6}, {0x99C7, 0x99C7}, {0x99C8, 0x99C8}, {0x99C9, 0x99C9}, {0x99CA, 0x99CA}, {0x99CB, 0x99CB}, + {0x99CC, 0x99CC}, {0x99CD, 0x99CD}, {0x99CE, 0x99CE}, {0x99CF, 0x99CF}, {0x99D0, 0x99D0}, {0x99D1, 0x99D1}, {0x99D2, 0x99D2}, + {0x99D3, 0x99D3}, {0x99D4, 0x99D4}, {0x99D5, 0x99D5}, {0x99D6, 0x99D6}, {0x99D7, 0x99D7}, {0x99D8, 0x99D8}, {0x99D9, 0x99D9}, + {0x99DA, 0x99DA}, {0x99DB, 0x99DB}, {0x99DC, 0x99DC}, {0x99DD, 0x99DD}, {0x99DE, 0x99DE}, {0x99DF, 0x99DF}, {0x99E0, 0x99E0}, + {0x99E1, 0x99E1}, {0x99E2, 0x99E2}, {0x99E3, 0x99E3}, {0x99E4, 0x99E4}, {0x99E5, 0x99E5}, {0x99E6, 0x99E6}, {0x99E7, 0x99E7}, + {0x99E8, 0x99E8}, {0x99E9, 0x99E9}, {0x99EA, 0x99EA}, {0x99EB, 0x99EB}, {0x99EC, 0x99EC}, {0x99ED, 0x99ED}, {0x99EE, 0x99EE}, + {0x99EF, 0x99EF}, {0x99F0, 0x99F0}, {0x99F1, 0x99F1}, {0x99F2, 0x99F2}, {0x99F3, 0x99F3}, {0x99F4, 0x99F4}, {0x99F5, 0x99F5}, + {0x99F6, 0x99F6}, {0x99F7, 0x99F7}, {0x99F8, 0x99F8}, {0x99F9, 0x99F9}, {0x99FA, 0x99FA}, {0x99FB, 0x99FB}, {0x99FC, 0x99FC}, + {0x99FD, 0x99FD}, {0x99FE, 0x99FE}, {0x99FF, 0x99FF}, {0x9A00, 0x9A00}, {0x9A01, 0x9A01}, {0x9A02, 0x9A02}, {0x9A03, 0x9A03}, + {0x9A04, 0x9A04}, {0x9A05, 0x9A05}, {0x9A06, 0x9A06}, {0x9A07, 0x9A07}, {0x9A08, 0x9A08}, {0x9A09, 0x9A09}, {0x9A0A, 0x9A0A}, + {0x9A0B, 0x9A0B}, {0x9A0C, 0x9A0C}, {0x9A0D, 0x9A0D}, {0x9A0E, 0x9A0E}, {0x9A0F, 0x9A0F}, {0x9A10, 0x9A10}, {0x9A11, 0x9A11}, + {0x9A12, 0x9A12}, {0x9A13, 0x9A13}, {0x9A14, 0x9A14}, {0x9A15, 0x9A15}, {0x9A16, 0x9A16}, {0x9A17, 0x9A17}, {0x9A18, 0x9A18}, + {0x9A19, 0x9A19}, {0x9A1A, 0x9A1A}, {0x9A1B, 0x9A1B}, {0x9A1C, 0x9A1C}, {0x9A1D, 0x9A1D}, {0x9A1E, 0x9A1E}, {0x9A1F, 0x9A1F}, + {0x9A20, 0x9A20}, {0x9A21, 0x9A21}, {0x9A22, 0x9A22}, {0x9A23, 0x9A23}, {0x9A24, 0x9A24}, {0x9A25, 0x9A25}, {0x9A26, 0x9A26}, + {0x9A27, 0x9A27}, {0x9A28, 0x9A28}, {0x9A29, 0x9A29}, {0x9A2A, 0x9A2A}, {0x9A2B, 0x9A2B}, {0x9A2C, 0x9A2C}, {0x9A2D, 0x9A2D}, + {0x9A2E, 0x9A2E}, {0x9A2F, 0x9A2F}, {0x9A30, 0x9A30}, {0x9A31, 0x9A31}, {0x9A32, 0x9A32}, {0x9A33, 0x9A33}, {0x9A34, 0x9A34}, + {0x9A35, 0x9A35}, {0x9A36, 0x9A36}, {0x9A37, 0x9A37}, {0x9A38, 0x9A38}, {0x9A39, 0x9A39}, {0x9A3A, 0x9A3A}, {0x9A3B, 0x9A3B}, + {0x9A3C, 0x9A3C}, {0x9A3D, 0x9A3D}, {0x9A3E, 0x9A3E}, {0x9A3F, 0x9A3F}, {0x9A40, 0x9A40}, {0x9A41, 0x9A41}, {0x9A42, 0x9A42}, + {0x9A43, 0x9A43}, {0x9A44, 0x9A44}, {0x9A45, 0x9A45}, {0x9A46, 0x9A46}, {0x9A47, 0x9A47}, {0x9A48, 0x9A48}, {0x9A49, 0x9A49}, + {0x9A4A, 0x9A4A}, {0x9A4B, 0x9A4B}, {0x9A4C, 0x9A4C}, {0x9A4D, 0x9A4D}, {0x9A4E, 0x9A4E}, {0x9A4F, 0x9A4F}, {0x9A50, 0x9A50}, + {0x9A51, 0x9A51}, {0x9A52, 0x9A52}, {0x9A53, 0x9A53}, {0x9A54, 0x9A54}, {0x9A55, 0x9A55}, {0x9A56, 0x9A56}, {0x9A57, 0x9A57}, + {0x9A58, 0x9A58}, {0x9A59, 0x9A59}, {0x9A5A, 0x9A5A}, {0x9A5B, 0x9A5B}, {0x9A5C, 0x9A5C}, {0x9A5D, 0x9A5D}, {0x9A5E, 0x9A5E}, + {0x9A5F, 0x9A5F}, {0x9A60, 0x9A60}, {0x9A61, 0x9A61}, {0x9A62, 0x9A62}, {0x9A63, 0x9A63}, {0x9A64, 0x9A64}, {0x9A65, 0x9A65}, + {0x9A66, 0x9A66}, {0x9A67, 0x9A67}, {0x9A68, 0x9A68}, {0x9A69, 0x9A69}, {0x9A6A, 0x9A6A}, {0x9A6B, 0x9A6B}, {0x9A6C, 0x9A6C}, + {0x9A6D, 0x9A6D}, {0x9A6E, 0x9A6E}, {0x9A6F, 0x9A6F}, {0x9A70, 0x9A70}, {0x9A71, 0x9A71}, {0x9A72, 0x9A72}, {0x9A73, 0x9A73}, + {0x9A74, 0x9A74}, {0x9A75, 0x9A75}, {0x9A76, 0x9A76}, {0x9A77, 0x9A77}, {0x9A78, 0x9A78}, {0x9A79, 0x9A79}, {0x9A7A, 0x9A7A}, + {0x9A7B, 0x9A7B}, {0x9A7C, 0x9A7C}, {0x9A7D, 0x9A7D}, {0x9A7E, 0x9A7E}, {0x9A7F, 0x9A7F}, {0x9A80, 0x9A80}, {0x9A81, 0x9A81}, + {0x9A82, 0x9A82}, {0x9A83, 0x9A83}, {0x9A84, 0x9A84}, {0x9A85, 0x9A85}, {0x9A86, 0x9A86}, {0x9A87, 0x9A87}, {0x9A88, 0x9A88}, + {0x9A89, 0x9A89}, {0x9A8A, 0x9A8A}, {0x9A8B, 0x9A8B}, {0x9A8C, 0x9A8C}, {0x9A8D, 0x9A8D}, {0x9A8E, 0x9A8E}, {0x9A8F, 0x9A8F}, + {0x9A90, 0x9A90}, {0x9A91, 0x9A91}, {0x9A92, 0x9A92}, {0x9A93, 0x9A93}, {0x9A94, 0x9A94}, {0x9A95, 0x9A95}, {0x9A96, 0x9A96}, + {0x9A97, 0x9A97}, {0x9A98, 0x9A98}, {0x9A99, 0x9A99}, {0x9A9A, 0x9A9A}, {0x9A9B, 0x9A9B}, {0x9A9C, 0x9A9C}, {0x9A9D, 0x9A9D}, + {0x9A9E, 0x9A9E}, {0x9A9F, 0x9A9F}, {0x9AA0, 0x9AA0}, {0x9AA1, 0x9AA1}, {0x9AA2, 0x9AA2}, {0x9AA3, 0x9AA3}, {0x9AA4, 0x9AA4}, + {0x9AA5, 0x9AA5}, {0x9AA6, 0x9AA6}, {0x9AA7, 0x9AA7}, {0x9AA8, 0x9AA8}, {0x9AA9, 0x9AA9}, {0x9AAA, 0x9AAA}, {0x9AAB, 0x9AAB}, + {0x9AAC, 0x9AAC}, {0x9AAD, 0x9AAD}, {0x9AAE, 0x9AAE}, {0x9AAF, 0x9AAF}, {0x9AB0, 0x9AB0}, {0x9AB1, 0x9AB1}, {0x9AB2, 0x9AB2}, + {0x9AB3, 0x9AB3}, {0x9AB4, 0x9AB4}, {0x9AB5, 0x9AB5}, {0x9AB6, 0x9AB6}, {0x9AB7, 0x9AB7}, {0x9AB8, 0x9AB8}, {0x9AB9, 0x9AB9}, + {0x9ABA, 0x9ABA}, {0x9ABB, 0x9ABB}, {0x9ABC, 0x9ABC}, {0x9ABD, 0x9ABD}, {0x9ABE, 0x9ABE}, {0x9ABF, 0x9ABF}, {0x9AC0, 0x9AC0}, + {0x9AC1, 0x9AC1}, {0x9AC2, 0x9AC2}, {0x9AC3, 0x9AC3}, {0x9AC4, 0x9AC4}, {0x9AC5, 0x9AC5}, {0x9AC6, 0x9AC6}, {0x9AC7, 0x9AC7}, + {0x9AC8, 0x9AC8}, {0x9AC9, 0x9AC9}, {0x9ACA, 0x9ACA}, {0x9ACB, 0x9ACB}, {0x9ACC, 0x9ACC}, {0x9ACD, 0x9ACD}, {0x9ACE, 0x9ACE}, + {0x9ACF, 0x9ACF}, {0x9AD0, 0x9AD0}, {0x9AD1, 0x9AD1}, {0x9AD2, 0x9AD2}, {0x9AD3, 0x9AD3}, {0x9AD4, 0x9AD4}, {0x9AD5, 0x9AD5}, + {0x9AD6, 0x9AD6}, {0x9AD7, 0x9AD7}, {0x9AD8, 0x9AD8}, {0x9AD9, 0x9AD9}, {0x9ADA, 0x9ADA}, {0x9ADB, 0x9ADB}, {0x9ADC, 0x9ADC}, + {0x9ADD, 0x9ADD}, {0x9ADE, 0x9ADE}, {0x9ADF, 0x9ADF}, {0x9AE0, 0x9AE0}, {0x9AE1, 0x9AE1}, {0x9AE2, 0x9AE2}, {0x9AE3, 0x9AE3}, + {0x9AE4, 0x9AE4}, {0x9AE5, 0x9AE5}, {0x9AE6, 0x9AE6}, {0x9AE7, 0x9AE7}, {0x9AE8, 0x9AE8}, {0x9AE9, 0x9AE9}, {0x9AEA, 0x9AEA}, + {0x9AEB, 0x9AEB}, {0x9AEC, 0x9AEC}, {0x9AED, 0x9AED}, {0x9AEE, 0x9AEE}, {0x9AEF, 0x9AEF}, {0x9AF0, 0x9AF0}, {0x9AF1, 0x9AF1}, + {0x9AF2, 0x9AF2}, {0x9AF3, 0x9AF3}, {0x9AF4, 0x9AF4}, {0x9AF5, 0x9AF5}, {0x9AF6, 0x9AF6}, {0x9AF7, 0x9AF7}, {0x9AF8, 0x9AF8}, + {0x9AF9, 0x9AF9}, {0x9AFA, 0x9AFA}, {0x9AFB, 0x9AFB}, {0x9AFC, 0x9AFC}, {0x9AFD, 0x9AFD}, {0x9AFE, 0x9AFE}, {0x9AFF, 0x9AFF}, + {0x9B00, 0x9B00}, {0x9B01, 0x9B01}, {0x9B02, 0x9B02}, {0x9B03, 0x9B03}, {0x9B04, 0x9B04}, {0x9B05, 0x9B05}, {0x9B06, 0x9B06}, + {0x9B07, 0x9B07}, {0x9B08, 0x9B08}, {0x9B09, 0x9B09}, {0x9B0A, 0x9B0A}, {0x9B0B, 0x9B0B}, {0x9B0C, 0x9B0C}, {0x9B0D, 0x9B0D}, + {0x9B0E, 0x9B0E}, {0x9B0F, 0x9B0F}, {0x9B10, 0x9B10}, {0x9B11, 0x9B11}, {0x9B12, 0x9B12}, {0x9B13, 0x9B13}, {0x9B14, 0x9B14}, + {0x9B15, 0x9B15}, {0x9B16, 0x9B16}, {0x9B17, 0x9B17}, {0x9B18, 0x9B18}, {0x9B19, 0x9B19}, {0x9B1A, 0x9B1A}, {0x9B1B, 0x9B1B}, + {0x9B1C, 0x9B1C}, {0x9B1D, 0x9B1D}, {0x9B1E, 0x9B1E}, {0x9B1F, 0x9B1F}, {0x9B20, 0x9B20}, {0x9B21, 0x9B21}, {0x9B22, 0x9B22}, + {0x9B23, 0x9B23}, {0x9B24, 0x9B24}, {0x9B25, 0x9B25}, {0x9B26, 0x9B26}, {0x9B27, 0x9B27}, {0x9B28, 0x9B28}, {0x9B29, 0x9B29}, + {0x9B2A, 0x9B2A}, {0x9B2B, 0x9B2B}, {0x9B2C, 0x9B2C}, {0x9B2D, 0x9B2D}, {0x9B2E, 0x9B2E}, {0x9B2F, 0x9B2F}, {0x9B30, 0x9B30}, + {0x9B31, 0x9B31}, {0x9B32, 0x9B32}, {0x9B33, 0x9B33}, {0x9B34, 0x9B34}, {0x9B35, 0x9B35}, {0x9B36, 0x9B36}, {0x9B37, 0x9B37}, + {0x9B38, 0x9B38}, {0x9B39, 0x9B39}, {0x9B3A, 0x9B3A}, {0x9B3B, 0x9B3B}, {0x9B3C, 0x9B3C}, {0x9B3D, 0x9B3D}, {0x9B3E, 0x9B3E}, + {0x9B3F, 0x9B3F}, {0x9B40, 0x9B40}, {0x9B41, 0x9B41}, {0x9B42, 0x9B42}, {0x9B43, 0x9B43}, {0x9B44, 0x9B44}, {0x9B45, 0x9B45}, + {0x9B46, 0x9B46}, {0x9B47, 0x9B47}, {0x9B48, 0x9B48}, {0x9B49, 0x9B49}, {0x9B4A, 0x9B4A}, {0x9B4B, 0x9B4B}, {0x9B4C, 0x9B4C}, + {0x9B4D, 0x9B4D}, {0x9B4E, 0x9B4E}, {0x9B4F, 0x9B4F}, {0x9B50, 0x9B50}, {0x9B51, 0x9B51}, {0x9B52, 0x9B52}, {0x9B53, 0x9B53}, + {0x9B54, 0x9B54}, {0x9B55, 0x9B55}, {0x9B56, 0x9B56}, {0x9B57, 0x9B57}, {0x9B58, 0x9B58}, {0x9B59, 0x9B59}, {0x9B5A, 0x9B5A}, + {0x9B5B, 0x9B5B}, {0x9B5C, 0x9B5C}, {0x9B5D, 0x9B5D}, {0x9B5E, 0x9B5E}, {0x9B5F, 0x9B5F}, {0x9B60, 0x9B60}, {0x9B61, 0x9B61}, + {0x9B62, 0x9B62}, {0x9B63, 0x9B63}, {0x9B64, 0x9B64}, {0x9B65, 0x9B65}, {0x9B66, 0x9B66}, {0x9B67, 0x9B67}, {0x9B68, 0x9B68}, + {0x9B69, 0x9B69}, {0x9B6A, 0x9B6A}, {0x9B6B, 0x9B6B}, {0x9B6C, 0x9B6C}, {0x9B6D, 0x9B6D}, {0x9B6E, 0x9B6E}, {0x9B6F, 0x9B6F}, + {0x9B70, 0x9B70}, {0x9B71, 0x9B71}, {0x9B72, 0x9B72}, {0x9B73, 0x9B73}, {0x9B74, 0x9B74}, {0x9B75, 0x9B75}, {0x9B76, 0x9B76}, + {0x9B77, 0x9B77}, {0x9B78, 0x9B78}, {0x9B79, 0x9B79}, {0x9B7A, 0x9B7A}, {0x9B7B, 0x9B7B}, {0x9B7C, 0x9B7C}, {0x9B7D, 0x9B7D}, + {0x9B7E, 0x9B7E}, {0x9B7F, 0x9B7F}, {0x9B80, 0x9B80}, {0x9B81, 0x9B81}, {0x9B82, 0x9B82}, {0x9B83, 0x9B83}, {0x9B84, 0x9B84}, + {0x9B85, 0x9B85}, {0x9B86, 0x9B86}, {0x9B87, 0x9B87}, {0x9B88, 0x9B88}, {0x9B89, 0x9B89}, {0x9B8A, 0x9B8A}, {0x9B8B, 0x9B8B}, + {0x9B8C, 0x9B8C}, {0x9B8D, 0x9B8D}, {0x9B8E, 0x9B8E}, {0x9B8F, 0x9B8F}, {0x9B90, 0x9B90}, {0x9B91, 0x9B91}, {0x9B92, 0x9B92}, + {0x9B93, 0x9B93}, {0x9B94, 0x9B94}, {0x9B95, 0x9B95}, {0x9B96, 0x9B96}, {0x9B97, 0x9B97}, {0x9B98, 0x9B98}, {0x9B99, 0x9B99}, + {0x9B9A, 0x9B9A}, {0x9B9B, 0x9B9B}, {0x9B9C, 0x9B9C}, {0x9B9D, 0x9B9D}, {0x9B9E, 0x9B9E}, {0x9B9F, 0x9B9F}, {0x9BA0, 0x9BA0}, + {0x9BA1, 0x9BA1}, {0x9BA2, 0x9BA2}, {0x9BA3, 0x9BA3}, {0x9BA4, 0x9BA4}, {0x9BA5, 0x9BA5}, {0x9BA6, 0x9BA6}, {0x9BA7, 0x9BA7}, + {0x9BA8, 0x9BA8}, {0x9BA9, 0x9BA9}, {0x9BAA, 0x9BAA}, {0x9BAB, 0x9BAB}, {0x9BAC, 0x9BAC}, {0x9BAD, 0x9BAD}, {0x9BAE, 0x9BAE}, + {0x9BAF, 0x9BAF}, {0x9BB0, 0x9BB0}, {0x9BB1, 0x9BB1}, {0x9BB2, 0x9BB2}, {0x9BB3, 0x9BB3}, {0x9BB4, 0x9BB4}, {0x9BB5, 0x9BB5}, + {0x9BB6, 0x9BB6}, {0x9BB7, 0x9BB7}, {0x9BB8, 0x9BB8}, {0x9BB9, 0x9BB9}, {0x9BBA, 0x9BBA}, {0x9BBB, 0x9BBB}, {0x9BBC, 0x9BBC}, + {0x9BBD, 0x9BBD}, {0x9BBE, 0x9BBE}, {0x9BBF, 0x9BBF}, {0x9BC0, 0x9BC0}, {0x9BC1, 0x9BC1}, {0x9BC2, 0x9BC2}, {0x9BC3, 0x9BC3}, + {0x9BC4, 0x9BC4}, {0x9BC5, 0x9BC5}, {0x9BC6, 0x9BC6}, {0x9BC7, 0x9BC7}, {0x9BC8, 0x9BC8}, {0x9BC9, 0x9BC9}, {0x9BCA, 0x9BCA}, + {0x9BCB, 0x9BCB}, {0x9BCC, 0x9BCC}, {0x9BCD, 0x9BCD}, {0x9BCE, 0x9BCE}, {0x9BCF, 0x9BCF}, {0x9BD0, 0x9BD0}, {0x9BD1, 0x9BD1}, + {0x9BD2, 0x9BD2}, {0x9BD3, 0x9BD3}, {0x9BD4, 0x9BD4}, {0x9BD5, 0x9BD5}, {0x9BD6, 0x9BD6}, {0x9BD7, 0x9BD7}, {0x9BD8, 0x9BD8}, + {0x9BD9, 0x9BD9}, {0x9BDA, 0x9BDA}, {0x9BDB, 0x9BDB}, {0x9BDC, 0x9BDC}, {0x9BDD, 0x9BDD}, {0x9BDE, 0x9BDE}, {0x9BDF, 0x9BDF}, + {0x9BE0, 0x9BE0}, {0x9BE1, 0x9BE1}, {0x9BE2, 0x9BE2}, {0x9BE3, 0x9BE3}, {0x9BE4, 0x9BE4}, {0x9BE5, 0x9BE5}, {0x9BE6, 0x9BE6}, + {0x9BE7, 0x9BE7}, {0x9BE8, 0x9BE8}, {0x9BE9, 0x9BE9}, {0x9BEA, 0x9BEA}, {0x9BEB, 0x9BEB}, {0x9BEC, 0x9BEC}, {0x9BED, 0x9BED}, + {0x9BEE, 0x9BEE}, {0x9BEF, 0x9BEF}, {0x9BF0, 0x9BF0}, {0x9BF1, 0x9BF1}, {0x9BF2, 0x9BF2}, {0x9BF3, 0x9BF3}, {0x9BF4, 0x9BF4}, + {0x9BF5, 0x9BF5}, {0x9BF6, 0x9BF6}, {0x9BF7, 0x9BF7}, {0x9BF8, 0x9BF8}, {0x9BF9, 0x9BF9}, {0x9BFA, 0x9BFA}, {0x9BFB, 0x9BFB}, + {0x9BFC, 0x9BFC}, {0x9BFD, 0x9BFD}, {0x9BFE, 0x9BFE}, {0x9BFF, 0x9BFF}, {0x9C00, 0x9C00}, {0x9C01, 0x9C01}, {0x9C02, 0x9C02}, + {0x9C03, 0x9C03}, {0x9C04, 0x9C04}, {0x9C05, 0x9C05}, {0x9C06, 0x9C06}, {0x9C07, 0x9C07}, {0x9C08, 0x9C08}, {0x9C09, 0x9C09}, + {0x9C0A, 0x9C0A}, {0x9C0B, 0x9C0B}, {0x9C0C, 0x9C0C}, {0x9C0D, 0x9C0D}, {0x9C0E, 0x9C0E}, {0x9C0F, 0x9C0F}, {0x9C10, 0x9C10}, + {0x9C11, 0x9C11}, {0x9C12, 0x9C12}, {0x9C13, 0x9C13}, {0x9C14, 0x9C14}, {0x9C15, 0x9C15}, {0x9C16, 0x9C16}, {0x9C17, 0x9C17}, + {0x9C18, 0x9C18}, {0x9C19, 0x9C19}, {0x9C1A, 0x9C1A}, {0x9C1B, 0x9C1B}, {0x9C1C, 0x9C1C}, {0x9C1D, 0x9C1D}, {0x9C1E, 0x9C1E}, + {0x9C1F, 0x9C1F}, {0x9C20, 0x9C20}, {0x9C21, 0x9C21}, {0x9C22, 0x9C22}, {0x9C23, 0x9C23}, {0x9C24, 0x9C24}, {0x9C25, 0x9C25}, + {0x9C26, 0x9C26}, {0x9C27, 0x9C27}, {0x9C28, 0x9C28}, {0x9C29, 0x9C29}, {0x9C2A, 0x9C2A}, {0x9C2B, 0x9C2B}, {0x9C2C, 0x9C2C}, + {0x9C2D, 0x9C2D}, {0x9C2E, 0x9C2E}, {0x9C2F, 0x9C2F}, {0x9C30, 0x9C30}, {0x9C31, 0x9C31}, {0x9C32, 0x9C32}, {0x9C33, 0x9C33}, + {0x9C34, 0x9C34}, {0x9C35, 0x9C35}, {0x9C36, 0x9C36}, {0x9C37, 0x9C37}, {0x9C38, 0x9C38}, {0x9C39, 0x9C39}, {0x9C3A, 0x9C3A}, + {0x9C3B, 0x9C3B}, {0x9C3C, 0x9C3C}, {0x9C3D, 0x9C3D}, {0x9C3E, 0x9C3E}, {0x9C3F, 0x9C3F}, {0x9C40, 0x9C40}, {0x9C41, 0x9C41}, + {0x9C42, 0x9C42}, {0x9C43, 0x9C43}, {0x9C44, 0x9C44}, {0x9C45, 0x9C45}, {0x9C46, 0x9C46}, {0x9C47, 0x9C47}, {0x9C48, 0x9C48}, + {0x9C49, 0x9C49}, {0x9C4A, 0x9C4A}, {0x9C4B, 0x9C4B}, {0x9C4C, 0x9C4C}, {0x9C4D, 0x9C4D}, {0x9C4E, 0x9C4E}, {0x9C4F, 0x9C4F}, + {0x9C50, 0x9C50}, {0x9C51, 0x9C51}, {0x9C52, 0x9C52}, {0x9C53, 0x9C53}, {0x9C54, 0x9C54}, {0x9C55, 0x9C55}, {0x9C56, 0x9C56}, + {0x9C57, 0x9C57}, {0x9C58, 0x9C58}, {0x9C59, 0x9C59}, {0x9C5A, 0x9C5A}, {0x9C5B, 0x9C5B}, {0x9C5C, 0x9C5C}, {0x9C5D, 0x9C5D}, + {0x9C5E, 0x9C5E}, {0x9C5F, 0x9C5F}, {0x9C60, 0x9C60}, {0x9C61, 0x9C61}, {0x9C62, 0x9C62}, {0x9C63, 0x9C63}, {0x9C64, 0x9C64}, + {0x9C65, 0x9C65}, {0x9C66, 0x9C66}, {0x9C67, 0x9C67}, {0x9C68, 0x9C68}, {0x9C69, 0x9C69}, {0x9C6A, 0x9C6A}, {0x9C6B, 0x9C6B}, + {0x9C6C, 0x9C6C}, {0x9C6D, 0x9C6D}, {0x9C6E, 0x9C6E}, {0x9C6F, 0x9C6F}, {0x9C70, 0x9C70}, {0x9C71, 0x9C71}, {0x9C72, 0x9C72}, + {0x9C73, 0x9C73}, {0x9C74, 0x9C74}, {0x9C75, 0x9C75}, {0x9C76, 0x9C76}, {0x9C77, 0x9C77}, {0x9C78, 0x9C78}, {0x9C79, 0x9C79}, + {0x9C7A, 0x9C7A}, {0x9C7B, 0x9C7B}, {0x9C7C, 0x9C7C}, {0x9C7D, 0x9C7D}, {0x9C7E, 0x9C7E}, {0x9C7F, 0x9C7F}, {0x9C80, 0x9C80}, + {0x9C81, 0x9C81}, {0x9C82, 0x9C82}, {0x9C83, 0x9C83}, {0x9C84, 0x9C84}, {0x9C85, 0x9C85}, {0x9C86, 0x9C86}, {0x9C87, 0x9C87}, + {0x9C88, 0x9C88}, {0x9C89, 0x9C89}, {0x9C8A, 0x9C8A}, {0x9C8B, 0x9C8B}, {0x9C8C, 0x9C8C}, {0x9C8D, 0x9C8D}, {0x9C8E, 0x9C8E}, + {0x9C8F, 0x9C8F}, {0x9C90, 0x9C90}, {0x9C91, 0x9C91}, {0x9C92, 0x9C92}, {0x9C93, 0x9C93}, {0x9C94, 0x9C94}, {0x9C95, 0x9C95}, + {0x9C96, 0x9C96}, {0x9C97, 0x9C97}, {0x9C98, 0x9C98}, {0x9C99, 0x9C99}, {0x9C9A, 0x9C9A}, {0x9C9B, 0x9C9B}, {0x9C9C, 0x9C9C}, + {0x9C9D, 0x9C9D}, {0x9C9E, 0x9C9E}, {0x9C9F, 0x9C9F}, {0x9CA0, 0x9CA0}, {0x9CA1, 0x9CA1}, {0x9CA2, 0x9CA2}, {0x9CA3, 0x9CA3}, + {0x9CA4, 0x9CA4}, {0x9CA5, 0x9CA5}, {0x9CA6, 0x9CA6}, {0x9CA7, 0x9CA7}, {0x9CA8, 0x9CA8}, {0x9CA9, 0x9CA9}, {0x9CAA, 0x9CAA}, + {0x9CAB, 0x9CAB}, {0x9CAC, 0x9CAC}, {0x9CAD, 0x9CAD}, {0x9CAE, 0x9CAE}, {0x9CAF, 0x9CAF}, {0x9CB0, 0x9CB0}, {0x9CB1, 0x9CB1}, + {0x9CB2, 0x9CB2}, {0x9CB3, 0x9CB3}, {0x9CB4, 0x9CB4}, {0x9CB5, 0x9CB5}, {0x9CB6, 0x9CB6}, {0x9CB7, 0x9CB7}, {0x9CB8, 0x9CB8}, + {0x9CB9, 0x9CB9}, {0x9CBA, 0x9CBA}, {0x9CBB, 0x9CBB}, {0x9CBC, 0x9CBC}, {0x9CBD, 0x9CBD}, {0x9CBE, 0x9CBE}, {0x9CBF, 0x9CBF}, + {0x9CC0, 0x9CC0}, {0x9CC1, 0x9CC1}, {0x9CC2, 0x9CC2}, {0x9CC3, 0x9CC3}, {0x9CC4, 0x9CC4}, {0x9CC5, 0x9CC5}, {0x9CC6, 0x9CC6}, + {0x9CC7, 0x9CC7}, {0x9CC8, 0x9CC8}, {0x9CC9, 0x9CC9}, {0x9CCA, 0x9CCA}, {0x9CCB, 0x9CCB}, {0x9CCC, 0x9CCC}, {0x9CCD, 0x9CCD}, + {0x9CCE, 0x9CCE}, {0x9CCF, 0x9CCF}, {0x9CD0, 0x9CD0}, {0x9CD1, 0x9CD1}, {0x9CD2, 0x9CD2}, {0x9CD3, 0x9CD3}, {0x9CD4, 0x9CD4}, + {0x9CD5, 0x9CD5}, {0x9CD6, 0x9CD6}, {0x9CD7, 0x9CD7}, {0x9CD8, 0x9CD8}, {0x9CD9, 0x9CD9}, {0x9CDA, 0x9CDA}, {0x9CDB, 0x9CDB}, + {0x9CDC, 0x9CDC}, {0x9CDD, 0x9CDD}, {0x9CDE, 0x9CDE}, {0x9CDF, 0x9CDF}, {0x9CE0, 0x9CE0}, {0x9CE1, 0x9CE1}, {0x9CE2, 0x9CE2}, + {0x9CE3, 0x9CE3}, {0x9CE4, 0x9CE4}, {0x9CE5, 0x9CE5}, {0x9CE6, 0x9CE6}, {0x9CE7, 0x9CE7}, {0x9CE8, 0x9CE8}, {0x9CE9, 0x9CE9}, + {0x9CEA, 0x9CEA}, {0x9CEB, 0x9CEB}, {0x9CEC, 0x9CEC}, {0x9CED, 0x9CED}, {0x9CEE, 0x9CEE}, {0x9CEF, 0x9CEF}, {0x9CF0, 0x9CF0}, + {0x9CF1, 0x9CF1}, {0x9CF2, 0x9CF2}, {0x9CF3, 0x9CF3}, {0x9CF4, 0x9CF4}, {0x9CF5, 0x9CF5}, {0x9CF6, 0x9CF6}, {0x9CF7, 0x9CF7}, + {0x9CF8, 0x9CF8}, {0x9CF9, 0x9CF9}, {0x9CFA, 0x9CFA}, {0x9CFB, 0x9CFB}, {0x9CFC, 0x9CFC}, {0x9CFD, 0x9CFD}, {0x9CFE, 0x9CFE}, + {0x9CFF, 0x9CFF}, {0x9D00, 0x9D00}, {0x9D01, 0x9D01}, {0x9D02, 0x9D02}, {0x9D03, 0x9D03}, {0x9D04, 0x9D04}, {0x9D05, 0x9D05}, + {0x9D06, 0x9D06}, {0x9D07, 0x9D07}, {0x9D08, 0x9D08}, {0x9D09, 0x9D09}, {0x9D0A, 0x9D0A}, {0x9D0B, 0x9D0B}, {0x9D0C, 0x9D0C}, + {0x9D0D, 0x9D0D}, {0x9D0E, 0x9D0E}, {0x9D0F, 0x9D0F}, {0x9D10, 0x9D10}, {0x9D11, 0x9D11}, {0x9D12, 0x9D12}, {0x9D13, 0x9D13}, + {0x9D14, 0x9D14}, {0x9D15, 0x9D15}, {0x9D16, 0x9D16}, {0x9D17, 0x9D17}, {0x9D18, 0x9D18}, {0x9D19, 0x9D19}, {0x9D1A, 0x9D1A}, + {0x9D1B, 0x9D1B}, {0x9D1C, 0x9D1C}, {0x9D1D, 0x9D1D}, {0x9D1E, 0x9D1E}, {0x9D1F, 0x9D1F}, {0x9D20, 0x9D20}, {0x9D21, 0x9D21}, + {0x9D22, 0x9D22}, {0x9D23, 0x9D23}, {0x9D24, 0x9D24}, {0x9D25, 0x9D25}, {0x9D26, 0x9D26}, {0x9D27, 0x9D27}, {0x9D28, 0x9D28}, + {0x9D29, 0x9D29}, {0x9D2A, 0x9D2A}, {0x9D2B, 0x9D2B}, {0x9D2C, 0x9D2C}, {0x9D2D, 0x9D2D}, {0x9D2E, 0x9D2E}, {0x9D2F, 0x9D2F}, + {0x9D30, 0x9D30}, {0x9D31, 0x9D31}, {0x9D32, 0x9D32}, {0x9D33, 0x9D33}, {0x9D34, 0x9D34}, {0x9D35, 0x9D35}, {0x9D36, 0x9D36}, + {0x9D37, 0x9D37}, {0x9D38, 0x9D38}, {0x9D39, 0x9D39}, {0x9D3A, 0x9D3A}, {0x9D3B, 0x9D3B}, {0x9D3C, 0x9D3C}, {0x9D3D, 0x9D3D}, + {0x9D3E, 0x9D3E}, {0x9D3F, 0x9D3F}, {0x9D40, 0x9D40}, {0x9D41, 0x9D41}, {0x9D42, 0x9D42}, {0x9D43, 0x9D43}, {0x9D44, 0x9D44}, + {0x9D45, 0x9D45}, {0x9D46, 0x9D46}, {0x9D47, 0x9D47}, {0x9D48, 0x9D48}, {0x9D49, 0x9D49}, {0x9D4A, 0x9D4A}, {0x9D4B, 0x9D4B}, + {0x9D4C, 0x9D4C}, {0x9D4D, 0x9D4D}, {0x9D4E, 0x9D4E}, {0x9D4F, 0x9D4F}, {0x9D50, 0x9D50}, {0x9D51, 0x9D51}, {0x9D52, 0x9D52}, + {0x9D53, 0x9D53}, {0x9D54, 0x9D54}, {0x9D55, 0x9D55}, {0x9D56, 0x9D56}, {0x9D57, 0x9D57}, {0x9D58, 0x9D58}, {0x9D59, 0x9D59}, + {0x9D5A, 0x9D5A}, {0x9D5B, 0x9D5B}, {0x9D5C, 0x9D5C}, {0x9D5D, 0x9D5D}, {0x9D5E, 0x9D5E}, {0x9D5F, 0x9D5F}, {0x9D60, 0x9D60}, + {0x9D61, 0x9D61}, {0x9D62, 0x9D62}, {0x9D63, 0x9D63}, {0x9D64, 0x9D64}, {0x9D65, 0x9D65}, {0x9D66, 0x9D66}, {0x9D67, 0x9D67}, + {0x9D68, 0x9D68}, {0x9D69, 0x9D69}, {0x9D6A, 0x9D6A}, {0x9D6B, 0x9D6B}, {0x9D6C, 0x9D6C}, {0x9D6D, 0x9D6D}, {0x9D6E, 0x9D6E}, + {0x9D6F, 0x9D6F}, {0x9D70, 0x9D70}, {0x9D71, 0x9D71}, {0x9D72, 0x9D72}, {0x9D73, 0x9D73}, {0x9D74, 0x9D74}, {0x9D75, 0x9D75}, + {0x9D76, 0x9D76}, {0x9D77, 0x9D77}, {0x9D78, 0x9D78}, {0x9D79, 0x9D79}, {0x9D7A, 0x9D7A}, {0x9D7B, 0x9D7B}, {0x9D7C, 0x9D7C}, + {0x9D7D, 0x9D7D}, {0x9D7E, 0x9D7E}, {0x9D7F, 0x9D7F}, {0x9D80, 0x9D80}, {0x9D81, 0x9D81}, {0x9D82, 0x9D82}, {0x9D83, 0x9D83}, + {0x9D84, 0x9D84}, {0x9D85, 0x9D85}, {0x9D86, 0x9D86}, {0x9D87, 0x9D87}, {0x9D88, 0x9D88}, {0x9D89, 0x9D89}, {0x9D8A, 0x9D8A}, + {0x9D8B, 0x9D8B}, {0x9D8C, 0x9D8C}, {0x9D8D, 0x9D8D}, {0x9D8E, 0x9D8E}, {0x9D8F, 0x9D8F}, {0x9D90, 0x9D90}, {0x9D91, 0x9D91}, + {0x9D92, 0x9D92}, {0x9D93, 0x9D93}, {0x9D94, 0x9D94}, {0x9D95, 0x9D95}, {0x9D96, 0x9D96}, {0x9D97, 0x9D97}, {0x9D98, 0x9D98}, + {0x9D99, 0x9D99}, {0x9D9A, 0x9D9A}, {0x9D9B, 0x9D9B}, {0x9D9C, 0x9D9C}, {0x9D9D, 0x9D9D}, {0x9D9E, 0x9D9E}, {0x9D9F, 0x9D9F}, + {0x9DA0, 0x9DA0}, {0x9DA1, 0x9DA1}, {0x9DA2, 0x9DA2}, {0x9DA3, 0x9DA3}, {0x9DA4, 0x9DA4}, {0x9DA5, 0x9DA5}, {0x9DA6, 0x9DA6}, + {0x9DA7, 0x9DA7}, {0x9DA8, 0x9DA8}, {0x9DA9, 0x9DA9}, {0x9DAA, 0x9DAA}, {0x9DAB, 0x9DAB}, {0x9DAC, 0x9DAC}, {0x9DAD, 0x9DAD}, + {0x9DAE, 0x9DAE}, {0x9DAF, 0x9DAF}, {0x9DB0, 0x9DB0}, {0x9DB1, 0x9DB1}, {0x9DB2, 0x9DB2}, {0x9DB3, 0x9DB3}, {0x9DB4, 0x9DB4}, + {0x9DB5, 0x9DB5}, {0x9DB6, 0x9DB6}, {0x9DB7, 0x9DB7}, {0x9DB8, 0x9DB8}, {0x9DB9, 0x9DB9}, {0x9DBA, 0x9DBA}, {0x9DBB, 0x9DBB}, + {0x9DBC, 0x9DBC}, {0x9DBD, 0x9DBD}, {0x9DBE, 0x9DBE}, {0x9DBF, 0x9DBF}, {0x9DC0, 0x9DC0}, {0x9DC1, 0x9DC1}, {0x9DC2, 0x9DC2}, + {0x9DC3, 0x9DC3}, {0x9DC4, 0x9DC4}, {0x9DC5, 0x9DC5}, {0x9DC6, 0x9DC6}, {0x9DC7, 0x9DC7}, {0x9DC8, 0x9DC8}, {0x9DC9, 0x9DC9}, + {0x9DCA, 0x9DCA}, {0x9DCB, 0x9DCB}, {0x9DCC, 0x9DCC}, {0x9DCD, 0x9DCD}, {0x9DCE, 0x9DCE}, {0x9DCF, 0x9DCF}, {0x9DD0, 0x9DD0}, + {0x9DD1, 0x9DD1}, {0x9DD2, 0x9DD2}, {0x9DD3, 0x9DD3}, {0x9DD4, 0x9DD4}, {0x9DD5, 0x9DD5}, {0x9DD6, 0x9DD6}, {0x9DD7, 0x9DD7}, + {0x9DD8, 0x9DD8}, {0x9DD9, 0x9DD9}, {0x9DDA, 0x9DDA}, {0x9DDB, 0x9DDB}, {0x9DDC, 0x9DDC}, {0x9DDD, 0x9DDD}, {0x9DDE, 0x9DDE}, + {0x9DDF, 0x9DDF}, {0x9DE0, 0x9DE0}, {0x9DE1, 0x9DE1}, {0x9DE2, 0x9DE2}, {0x9DE3, 0x9DE3}, {0x9DE4, 0x9DE4}, {0x9DE5, 0x9DE5}, + {0x9DE6, 0x9DE6}, {0x9DE7, 0x9DE7}, {0x9DE8, 0x9DE8}, {0x9DE9, 0x9DE9}, {0x9DEA, 0x9DEA}, {0x9DEB, 0x9DEB}, {0x9DEC, 0x9DEC}, + {0x9DED, 0x9DED}, {0x9DEE, 0x9DEE}, {0x9DEF, 0x9DEF}, {0x9DF0, 0x9DF0}, {0x9DF1, 0x9DF1}, {0x9DF2, 0x9DF2}, {0x9DF3, 0x9DF3}, + {0x9DF4, 0x9DF4}, {0x9DF5, 0x9DF5}, {0x9DF6, 0x9DF6}, {0x9DF7, 0x9DF7}, {0x9DF8, 0x9DF8}, {0x9DF9, 0x9DF9}, {0x9DFA, 0x9DFA}, + {0x9DFB, 0x9DFB}, {0x9DFC, 0x9DFC}, {0x9DFD, 0x9DFD}, {0x9DFE, 0x9DFE}, {0x9DFF, 0x9DFF}, {0x9E00, 0x9E00}, {0x9E01, 0x9E01}, + {0x9E02, 0x9E02}, {0x9E03, 0x9E03}, {0x9E04, 0x9E04}, {0x9E05, 0x9E05}, {0x9E06, 0x9E06}, {0x9E07, 0x9E07}, {0x9E08, 0x9E08}, + {0x9E09, 0x9E09}, {0x9E0A, 0x9E0A}, {0x9E0B, 0x9E0B}, {0x9E0C, 0x9E0C}, {0x9E0D, 0x9E0D}, {0x9E0E, 0x9E0E}, {0x9E0F, 0x9E0F}, + {0x9E10, 0x9E10}, {0x9E11, 0x9E11}, {0x9E12, 0x9E12}, {0x9E13, 0x9E13}, {0x9E14, 0x9E14}, {0x9E15, 0x9E15}, {0x9E16, 0x9E16}, + {0x9E17, 0x9E17}, {0x9E18, 0x9E18}, {0x9E19, 0x9E19}, {0x9E1A, 0x9E1A}, {0x9E1B, 0x9E1B}, {0x9E1C, 0x9E1C}, {0x9E1D, 0x9E1D}, + {0x9E1E, 0x9E1E}, {0x9E1F, 0x9E1F}, {0x9E20, 0x9E20}, {0x9E21, 0x9E21}, {0x9E22, 0x9E22}, {0x9E23, 0x9E23}, {0x9E24, 0x9E24}, + {0x9E25, 0x9E25}, {0x9E26, 0x9E26}, {0x9E27, 0x9E27}, {0x9E28, 0x9E28}, {0x9E29, 0x9E29}, {0x9E2A, 0x9E2A}, {0x9E2B, 0x9E2B}, + {0x9E2C, 0x9E2C}, {0x9E2D, 0x9E2D}, {0x9E2E, 0x9E2E}, {0x9E2F, 0x9E2F}, {0x9E30, 0x9E30}, {0x9E31, 0x9E31}, {0x9E32, 0x9E32}, + {0x9E33, 0x9E33}, {0x9E34, 0x9E34}, {0x9E35, 0x9E35}, {0x9E36, 0x9E36}, {0x9E37, 0x9E37}, {0x9E38, 0x9E38}, {0x9E39, 0x9E39}, + {0x9E3A, 0x9E3A}, {0x9E3B, 0x9E3B}, {0x9E3C, 0x9E3C}, {0x9E3D, 0x9E3D}, {0x9E3E, 0x9E3E}, {0x9E3F, 0x9E3F}, {0x9E40, 0x9E40}, + {0x9E41, 0x9E41}, {0x9E42, 0x9E42}, {0x9E43, 0x9E43}, {0x9E44, 0x9E44}, {0x9E45, 0x9E45}, {0x9E46, 0x9E46}, {0x9E47, 0x9E47}, + {0x9E48, 0x9E48}, {0x9E49, 0x9E49}, {0x9E4A, 0x9E4A}, {0x9E4B, 0x9E4B}, {0x9E4C, 0x9E4C}, {0x9E4D, 0x9E4D}, {0x9E4E, 0x9E4E}, + {0x9E4F, 0x9E4F}, {0x9E50, 0x9E50}, {0x9E51, 0x9E51}, {0x9E52, 0x9E52}, {0x9E53, 0x9E53}, {0x9E54, 0x9E54}, {0x9E55, 0x9E55}, + {0x9E56, 0x9E56}, {0x9E57, 0x9E57}, {0x9E58, 0x9E58}, {0x9E59, 0x9E59}, {0x9E5A, 0x9E5A}, {0x9E5B, 0x9E5B}, {0x9E5C, 0x9E5C}, + {0x9E5D, 0x9E5D}, {0x9E5E, 0x9E5E}, {0x9E5F, 0x9E5F}, {0x9E60, 0x9E60}, {0x9E61, 0x9E61}, {0x9E62, 0x9E62}, {0x9E63, 0x9E63}, + {0x9E64, 0x9E64}, {0x9E65, 0x9E65}, {0x9E66, 0x9E66}, {0x9E67, 0x9E67}, {0x9E68, 0x9E68}, {0x9E69, 0x9E69}, {0x9E6A, 0x9E6A}, + {0x9E6B, 0x9E6B}, {0x9E6C, 0x9E6C}, {0x9E6D, 0x9E6D}, {0x9E6E, 0x9E6E}, {0x9E6F, 0x9E6F}, {0x9E70, 0x9E70}, {0x9E71, 0x9E71}, + {0x9E72, 0x9E72}, {0x9E73, 0x9E73}, {0x9E74, 0x9E74}, {0x9E75, 0x9E75}, {0x9E76, 0x9E76}, {0x9E77, 0x9E77}, {0x9E78, 0x9E78}, + {0x9E79, 0x9E79}, {0x9E7A, 0x9E7A}, {0x9E7B, 0x9E7B}, {0x9E7C, 0x9E7C}, {0x9E7D, 0x9E7D}, {0x9E7E, 0x9E7E}, {0x9E7F, 0x9E7F}, + {0x9E80, 0x9E80}, {0x9E81, 0x9E81}, {0x9E82, 0x9E82}, {0x9E83, 0x9E83}, {0x9E84, 0x9E84}, {0x9E85, 0x9E85}, {0x9E86, 0x9E86}, + {0x9E87, 0x9E87}, {0x9E88, 0x9E88}, {0x9E89, 0x9E89}, {0x9E8A, 0x9E8A}, {0x9E8B, 0x9E8B}, {0x9E8C, 0x9E8C}, {0x9E8D, 0x9E8D}, + {0x9E8E, 0x9E8E}, {0x9E8F, 0x9E8F}, {0x9E90, 0x9E90}, {0x9E91, 0x9E91}, {0x9E92, 0x9E92}, {0x9E93, 0x9E93}, {0x9E94, 0x9E94}, + {0x9E95, 0x9E95}, {0x9E96, 0x9E96}, {0x9E97, 0x9E97}, {0x9E98, 0x9E98}, {0x9E99, 0x9E99}, {0x9E9A, 0x9E9A}, {0x9E9B, 0x9E9B}, + {0x9E9C, 0x9E9C}, {0x9E9D, 0x9E9D}, {0x9E9E, 0x9E9E}, {0x9E9F, 0x9E9F}, {0x9EA0, 0x9EA0}, {0x9EA1, 0x9EA1}, {0x9EA2, 0x9EA2}, + {0x9EA3, 0x9EA3}, {0x9EA4, 0x9EA4}, {0x9EA5, 0x9EA5}, {0x9EA6, 0x9EA6}, {0x9EA7, 0x9EA7}, {0x9EA8, 0x9EA8}, {0x9EA9, 0x9EA9}, + {0x9EAA, 0x9EAA}, {0x9EAB, 0x9EAB}, {0x9EAC, 0x9EAC}, {0x9EAD, 0x9EAD}, {0x9EAE, 0x9EAE}, {0x9EAF, 0x9EAF}, {0x9EB0, 0x9EB0}, + {0x9EB1, 0x9EB1}, {0x9EB2, 0x9EB2}, {0x9EB3, 0x9EB3}, {0x9EB4, 0x9EB4}, {0x9EB5, 0x9EB5}, {0x9EB6, 0x9EB6}, {0x9EB7, 0x9EB7}, + {0x9EB8, 0x9EB8}, {0x9EB9, 0x9EB9}, {0x9EBA, 0x9EBA}, {0x9EBB, 0x9EBB}, {0x9EBC, 0x9EBC}, {0x9EBD, 0x9EBD}, {0x9EBE, 0x9EBE}, + {0x9EBF, 0x9EBF}, {0x9EC0, 0x9EC0}, {0x9EC1, 0x9EC1}, {0x9EC2, 0x9EC2}, {0x9EC3, 0x9EC3}, {0x9EC4, 0x9EC4}, {0x9EC5, 0x9EC5}, + {0x9EC6, 0x9EC6}, {0x9EC7, 0x9EC7}, {0x9EC8, 0x9EC8}, {0x9EC9, 0x9EC9}, {0x9ECA, 0x9ECA}, {0x9ECB, 0x9ECB}, {0x9ECC, 0x9ECC}, + {0x9ECD, 0x9ECD}, {0x9ECE, 0x9ECE}, {0x9ECF, 0x9ECF}, {0x9ED0, 0x9ED0}, {0x9ED1, 0x9ED1}, {0x9ED2, 0x9ED2}, {0x9ED3, 0x9ED3}, + {0x9ED4, 0x9ED4}, {0x9ED5, 0x9ED5}, {0x9ED6, 0x9ED6}, {0x9ED7, 0x9ED7}, {0x9ED8, 0x9ED8}, {0x9ED9, 0x9ED9}, {0x9EDA, 0x9EDA}, + {0x9EDB, 0x9EDB}, {0x9EDC, 0x9EDC}, {0x9EDD, 0x9EDD}, {0x9EDE, 0x9EDE}, {0x9EDF, 0x9EDF}, {0x9EE0, 0x9EE0}, {0x9EE1, 0x9EE1}, + {0x9EE2, 0x9EE2}, {0x9EE3, 0x9EE3}, {0x9EE4, 0x9EE4}, {0x9EE5, 0x9EE5}, {0x9EE6, 0x9EE6}, {0x9EE7, 0x9EE7}, {0x9EE8, 0x9EE8}, + {0x9EE9, 0x9EE9}, {0x9EEA, 0x9EEA}, {0x9EEB, 0x9EEB}, {0x9EEC, 0x9EEC}, {0x9EED, 0x9EED}, {0x9EEE, 0x9EEE}, {0x9EEF, 0x9EEF}, + {0x9EF0, 0x9EF0}, {0x9EF1, 0x9EF1}, {0x9EF2, 0x9EF2}, {0x9EF3, 0x9EF3}, {0x9EF4, 0x9EF4}, {0x9EF5, 0x9EF5}, {0x9EF6, 0x9EF6}, + {0x9EF7, 0x9EF7}, {0x9EF8, 0x9EF8}, {0x9EF9, 0x9EF9}, {0x9EFA, 0x9EFA}, {0x9EFB, 0x9EFB}, {0x9EFC, 0x9EFC}, {0x9EFD, 0x9EFD}, + {0x9EFE, 0x9EFE}, {0x9EFF, 0x9EFF}, {0x9F00, 0x9F00}, {0x9F01, 0x9F01}, {0x9F02, 0x9F02}, {0x9F03, 0x9F03}, {0x9F04, 0x9F04}, + {0x9F05, 0x9F05}, {0x9F06, 0x9F06}, {0x9F07, 0x9F07}, {0x9F08, 0x9F08}, {0x9F09, 0x9F09}, {0x9F0A, 0x9F0A}, {0x9F0B, 0x9F0B}, + {0x9F0C, 0x9F0C}, {0x9F0D, 0x9F0D}, {0x9F0E, 0x9F0E}, {0x9F0F, 0x9F0F}, {0x9F10, 0x9F10}, {0x9F11, 0x9F11}, {0x9F12, 0x9F12}, + {0x9F13, 0x9F13}, {0x9F14, 0x9F14}, {0x9F15, 0x9F15}, {0x9F16, 0x9F16}, {0x9F17, 0x9F17}, {0x9F18, 0x9F18}, {0x9F19, 0x9F19}, + {0x9F1A, 0x9F1A}, {0x9F1B, 0x9F1B}, {0x9F1C, 0x9F1C}, {0x9F1D, 0x9F1D}, {0x9F1E, 0x9F1E}, {0x9F1F, 0x9F1F}, {0x9F20, 0x9F20}, + {0x9F21, 0x9F21}, {0x9F22, 0x9F22}, {0x9F23, 0x9F23}, {0x9F24, 0x9F24}, {0x9F25, 0x9F25}, {0x9F26, 0x9F26}, {0x9F27, 0x9F27}, + {0x9F28, 0x9F28}, {0x9F29, 0x9F29}, {0x9F2A, 0x9F2A}, {0x9F2B, 0x9F2B}, {0x9F2C, 0x9F2C}, {0x9F2D, 0x9F2D}, {0x9F2E, 0x9F2E}, + {0x9F2F, 0x9F2F}, {0x9F30, 0x9F30}, {0x9F31, 0x9F31}, {0x9F32, 0x9F32}, {0x9F33, 0x9F33}, {0x9F34, 0x9F34}, {0x9F35, 0x9F35}, + {0x9F36, 0x9F36}, {0x9F37, 0x9F37}, {0x9F38, 0x9F38}, {0x9F39, 0x9F39}, {0x9F3A, 0x9F3A}, {0x9F3B, 0x9F3B}, {0x9F3C, 0x9F3C}, + {0x9F3D, 0x9F3D}, {0x9F3E, 0x9F3E}, {0x9F3F, 0x9F3F}, {0x9F40, 0x9F40}, {0x9F41, 0x9F41}, {0x9F42, 0x9F42}, {0x9F43, 0x9F43}, + {0x9F44, 0x9F44}, {0x9F45, 0x9F45}, {0x9F46, 0x9F46}, {0x9F47, 0x9F47}, {0x9F48, 0x9F48}, {0x9F49, 0x9F49}, {0x9F4A, 0x9F4A}, + {0x9F4B, 0x9F4B}, {0x9F4C, 0x9F4C}, {0x9F4D, 0x9F4D}, {0x9F4E, 0x9F4E}, {0x9F4F, 0x9F4F}, {0x9F50, 0x9F50}, {0x9F51, 0x9F51}, + {0x9F52, 0x9F52}, {0x9F53, 0x9F53}, {0x9F54, 0x9F54}, {0x9F55, 0x9F55}, {0x9F56, 0x9F56}, {0x9F57, 0x9F57}, {0x9F58, 0x9F58}, + {0x9F59, 0x9F59}, {0x9F5A, 0x9F5A}, {0x9F5B, 0x9F5B}, {0x9F5C, 0x9F5C}, {0x9F5D, 0x9F5D}, {0x9F5E, 0x9F5E}, {0x9F5F, 0x9F5F}, + {0x9F60, 0x9F60}, {0x9F61, 0x9F61}, {0x9F62, 0x9F62}, {0x9F63, 0x9F63}, {0x9F64, 0x9F64}, {0x9F65, 0x9F65}, {0x9F66, 0x9F66}, + {0x9F67, 0x9F67}, {0x9F68, 0x9F68}, {0x9F69, 0x9F69}, {0x9F6A, 0x9F6A}, {0x9F6B, 0x9F6B}, {0x9F6C, 0x9F6C}, {0x9F6D, 0x9F6D}, + {0x9F6E, 0x9F6E}, {0x9F6F, 0x9F6F}, {0x9F70, 0x9F70}, {0x9F71, 0x9F71}, {0x9F72, 0x9F72}, {0x9F73, 0x9F73}, {0x9F74, 0x9F74}, + {0x9F75, 0x9F75}, {0x9F76, 0x9F76}, {0x9F77, 0x9F77}, {0x9F78, 0x9F78}, {0x9F79, 0x9F79}, {0x9F7A, 0x9F7A}, {0x9F7B, 0x9F7B}, + {0x9F7C, 0x9F7C}, {0x9F7D, 0x9F7D}, {0x9F7E, 0x9F7E}, {0x9F7F, 0x9F7F}, {0x9F80, 0x9F80}, {0x9F81, 0x9F81}, {0x9F82, 0x9F82}, + {0x9F83, 0x9F83}, {0x9F84, 0x9F84}, {0x9F85, 0x9F85}, {0x9F86, 0x9F86}, {0x9F87, 0x9F87}, {0x9F88, 0x9F88}, {0x9F89, 0x9F89}, + {0x9F8A, 0x9F8A}, {0x9F8B, 0x9F8B}, {0x9F8C, 0x9F8C}, {0x9F8D, 0x9F8D}, {0x9F8E, 0x9F8E}, {0x9F8F, 0x9F8F}, {0x9F90, 0x9F90}, + {0x9F91, 0x9F91}, {0x9F92, 0x9F92}, {0x9F93, 0x9F93}, {0x9F94, 0x9F94}, {0x9F95, 0x9F95}, {0x9F96, 0x9F96}, {0x9F97, 0x9F97}, + {0x9F98, 0x9F98}, {0x9F99, 0x9F99}, {0x9F9A, 0x9F9A}, {0x9F9B, 0x9F9B}, {0x9F9C, 0x9F9C}, {0x9F9D, 0x9F9D}, {0x9F9E, 0x9F9E}, + {0x9F9F, 0x9F9F}, {0x9FA0, 0x9FA0}, {0x9FA1, 0x9FA1}, {0x9FA2, 0x9FA2}, {0x9FA3, 0x9FA3}, {0x9FA4, 0x9FA4}, {0x9FA5, 0x9FA5}, + {0x9FA6, 0x9FA6}, {0x9FA7, 0x9FA7}, {0x9FA8, 0x9FA8}, {0x9FA9, 0x9FA9}, {0x9FAA, 0x9FAA}, {0x9FAB, 0x9FAB}, {0x9FAC, 0x9FAC}, + {0x9FAD, 0x9FAD}, {0x9FAE, 0x9FAE}, {0x9FAF, 0x9FAF}, {0x9FB0, 0x9FB0}, {0x9FB1, 0x9FB1}, {0x9FB2, 0x9FB2}, {0x9FB3, 0x9FB3}, + {0x9FB4, 0x9FB4}, {0x9FB5, 0x9FB5}, {0x9FB6, 0x9FB6}, {0x9FB7, 0x9FB7}, {0x9FB8, 0x9FB8}, {0x9FB9, 0x9FB9}, {0x9FBA, 0x9FBA}, + {0x9FBB, 0x9FBB}, {0x9FBC, 0x9FBC}, {0x9FBD, 0x9FBD}, {0x9FBE, 0x9FBE}, {0x9FBF, 0x9FBF}, {0x9FC0, 0x9FC0}, {0x9FC1, 0x9FC1}, + {0x9FC2, 0x9FC2}, {0x9FC3, 0x9FC3}, {0x9FC4, 0x9FC4}, {0x9FC5, 0x9FC5}, {0x9FC6, 0x9FC6}, {0x9FC7, 0x9FC7}, {0x9FC8, 0x9FC8}, + {0x9FC9, 0x9FC9}, {0x9FCA, 0x9FCA}, {0x9FCB, 0x9FCB}, {0x9FCC, 0x9FCC}, {0x9FCD, 0x9FCD}, {0x9FCE, 0x9FCE}, {0x9FCF, 0x9FCF}, + {0x9FD0, 0x9FD0}, {0x9FD1, 0x9FD1}, {0x9FD2, 0x9FD2}, {0x9FD3, 0x9FD3}, {0x9FD4, 0x9FD4}, {0x9FD5, 0x9FD5}, {0x9FD6, 0x9FD6}, + {0x9FD7, 0x9FD7}, {0x9FD8, 0x9FD8}, {0x9FD9, 0x9FD9}, {0x9FDA, 0x9FDA}, {0x9FDB, 0x9FDB}, {0x9FDC, 0x9FDC}, {0x9FDD, 0x9FDD}, + {0x9FDE, 0x9FDE}, {0x9FDF, 0x9FDF}, {0x9FE0, 0x9FE0}, {0x9FE1, 0x9FE1}, {0x9FE2, 0x9FE2}, {0x9FE3, 0x9FE3}, {0x9FE4, 0x9FE4}, + {0x9FE5, 0x9FE5}, {0x9FE6, 0x9FE6}, {0x9FE7, 0x9FE7}, {0x9FE8, 0x9FE8}, {0x9FE9, 0x9FE9}, {0x9FEA, 0x9FEA}, {0x9FEB, 0x9FEB}, + {0x9FEC, 0x9FEC}, {0x9FED, 0x9FED}, {0x9FEE, 0x9FEE}, {0x9FEF, 0x9FEF}, {0x9FF0, 0x9FF0}, {0x9FF1, 0x9FF1}, {0x9FF2, 0x9FF2}, + {0x9FF3, 0x9FF3}, {0x9FF4, 0x9FF4}, {0x9FF5, 0x9FF5}, {0x9FF6, 0x9FF6}, {0x9FF7, 0x9FF7}, {0x9FF8, 0x9FF8}, {0x9FF9, 0x9FF9}, + {0x9FFA, 0x9FFA}, {0x9FFB, 0x9FFB}, {0x9FFC, 0x9FFC}, {0x9FFD, 0x9FFD}, {0x9FFE, 0x9FFE}, {0x9FFF, 0x9FFF}, // Halfwidth and Fullwidth Forms (Latin) {0xFF41, 0xFF21}, {0xFF42, 0xFF22}, {0xFF43, 0xFF23}, {0xFF44, 0xFF24}, {0xFF45, 0xFF25}, {0xFF46, 0xFF26}, {0xFF47, 0xFF27}, {0xFF48, 0xFF28}, {0xFF49, 0xFF29}, {0xFF4A, 0xFF2A}, {0xFF4B, 0xFF2B}, {0xFF4C, 0xFF2C}, {0xFF4D, 0xFF2D}, {0xFF4E, 0xFF2E}, @@ -199,6 +3213,8 @@ constexpr std::pair kAlphabet[] = { // clang-format on }; +#if RX_WITH_STDLIB_DEBUG + constexpr int checkAlphabetSorted() { for (int i = 1; i < std::end(kAlphabet) - std::begin(kAlphabet); i++) { if (kAlphabet[i - 1] >= kAlphabet[i]) { @@ -227,6 +3243,8 @@ constexpr bool checkAlphabetLowUpperUtf8SizeEquals() { static_assert(checkAlphabetSorted() == -1, "Alphabet must be sorted"); static_assert(checkAlphabetLowUpperUtf8SizeEquals(), "The length of utf8 capital and small letters must be the same"); +#endif // RX_WITH_STDLIB_DEBUG + CustomLocale::CustomLocale() noexcept { for (uint32_t i = 0; i < UINT16_MAX; ++i) { customLocale_[i].isAlpha = false; diff --git a/cpp_src/tools/lsn.h b/cpp_src/tools/lsn.h index 1b87bb9ea..8aa340e36 100644 --- a/cpp_src/tools/lsn.h +++ b/cpp_src/tools/lsn.h @@ -44,6 +44,9 @@ struct lsn_t { lsn_t(int64_t counter, int16_t server) { validateCounter(counter); validateServerId(server); + if (counter < 0) { + counter = kDefaultCounter; + } payload_ = server * kMaxCounter + counter; } explicit operator int64_t() const noexcept { return payload_; } @@ -73,6 +76,9 @@ struct lsn_t { int64_t SetCounter(int64_t counter) { validateCounter(counter); payload_ = Server() * kMaxCounter + counter; + if (counter < 0) { + counter = kDefaultCounter; + } return payload_; } int64_t Counter() const noexcept { return payload_ % kMaxCounter; } diff --git a/cpp_src/tools/serializer.h b/cpp_src/tools/serializer.h index fb528cda1..3d33d9310 100644 --- a/cpp_src/tools/serializer.h +++ b/cpp_src/tools/serializer.h @@ -147,9 +147,9 @@ class Serializer { Variant getPVStringVariant(); const v_string_hdr* getPVStringPtr(); - const uint8_t* buf_; - size_t len_; - size_t pos_; + const uint8_t* buf_{nullptr}; + size_t len_{0}; + size_t pos_{0}; }; class WrSerializer { @@ -263,8 +263,8 @@ class WrSerializer { } private: - WrSerializer* ser_; - size_t pos_; + const WrSerializer* ser_{nullptr}; + size_t pos_{0}; }; public: @@ -287,8 +287,8 @@ class WrSerializer { void End(); private: - WrSerializer* ser_; - size_t pos_; + WrSerializer* ser_{nullptr}; + size_t pos_{0}; }; SliceHelper StartSlice() { @@ -463,22 +463,20 @@ class WrSerializer { size_t Cap() const noexcept { return cap_; } void Reserve(size_t cap) { if (cap > cap_) { - cap_ = cap; - uint8_t* b = new uint8_t[cap_]; - memcpy(b, buf_, len_); + auto b = std::make_unique(cap); + memcpy(b.get(), buf_, len_); if (HasAllocatedBuffer()) { delete[] buf_; // NOLINT(*.NewDelete) False positive } - buf_ = b; + buf_ = b.release(); + cap_ = cap; hasExternalBuf_ = false; } } RX_ALWAYS_INLINE std::string_view Slice() const noexcept { return {reinterpret_cast(buf_), len_}; } const char* c_str() noexcept { - if (!len_ || buf_[len_] != 0) { - grow(1); - buf_[len_] = 0; - } + grow(1); + buf_[len_] = 0; return reinterpret_cast(buf_); } bool HasHeap() const noexcept { return buf_ != inBuf_ && cap_; } @@ -492,11 +490,11 @@ class WrSerializer { Reserve((newCap == newCapAligned) ? newCap : (newCapAligned + 0x1000)); } } - uint8_t* buf_ = nullptr; - size_t len_ = 0; - size_t cap_ = 0; + uint8_t* buf_{nullptr}; + size_t len_{0}; + size_t cap_{0}; uint8_t inBuf_[0x100]; - bool hasExternalBuf_ = false; + bool hasExternalBuf_{false}; }; inline int msgpack_wrserializer_write(void* data, const char* buf, size_t len) { diff --git a/cpp_src/wal/walselecter.cc b/cpp_src/wal/walselecter.cc index 369f9f427..bfaf08b17 100644 --- a/cpp_src/wal/walselecter.cc +++ b/cpp_src/wal/walselecter.cc @@ -6,6 +6,8 @@ #include "core/rdxcontext.h" #include "tools/semversion.h" +#include "tools/logger.h" + namespace reindexer { const SemVersion kMinUnknownReplSupportRxVersion("2.6.0"); @@ -72,7 +74,8 @@ void WALSelecter::operator()(LocalQueryResults& result, SelectCtx& params, bool if (firstIt != walEnd) { WALRecord firstRec = *firstIt; if (!allowTxWithoutBegining_ && firstRec.inTransaction && firstRec.type != WalInitTransaction) { - throw Error(errOutdatedWAL, "WAL starts from init tx record. LSN: %d, type: %d", firstIt.GetLSN(), firstRec.type); + throw Error(errOutdatedWAL, "WAL starts from tx record, which is not 'init tx'. LSN: %d, type: %d", firstIt.GetLSN(), + firstRec.type); } } for (auto it = firstIt; count && it != walEnd; ++it) { diff --git a/cpp_src/wal/waltracker.h b/cpp_src/wal/waltracker.h index 4e47ed4e4..f5bbfeb94 100644 --- a/cpp_src/wal/waltracker.h +++ b/cpp_src/wal/waltracker.h @@ -65,7 +65,7 @@ class WALTracker { /// @param server - Server ID void SetServer(int16_t server) { lsnCounter_.SetServer(server); } /// Get server id from local LSN counter - int16_t GetServer() { return lsnCounter_.Server(); } + int16_t GetServer() const noexcept { return lsnCounter_.Server(); } /// Reset WAL state void Reset(); @@ -97,11 +97,11 @@ class WALTracker { iterator end() const { return {lsnCounter_.Counter(), this}; } /// Get upper_bound /// @param lsn LSN counter of record - /// @return iterator pointing LSN record greate than lsn + /// @return iterator pointing LSN record greate than LSN iterator upper_bound(lsn_t lsn) const { return !available(lsn) ? end() : iterator{lsn.Counter() + 1, this}; } /// Get inclusive_upper_bound /// @param lsn LSN counter of record - /// @return iterator pointing LSN record greate or equal to lsn + /// @return iterator pointing LSN record greate or equal to LSN iterator inclusive_upper_bound(lsn_t lsn) const { return !available(lsn) ? end() : iterator{lsn.Counter(), this}; } /// Check if LSN is outdated, and complete log is not available /// @param lsn LSN of record diff --git a/dependencies.sh b/dependencies.sh index 53d748c89..c13c4565a 100755 --- a/dependencies.sh +++ b/dependencies.sh @@ -40,7 +40,7 @@ debian_debs="build-essential g++ libunwind-dev libgoogle-perftools-dev libsnappy alpine_apks="g++ snappy-dev leveldb-dev libunwind-dev make curl cmake unzip git" arch_pkgs="gcc snappy leveldb make curl cmake unzip git" redos_rpms="gcc gcc-c++ make snappy-devel leveldb-devel gperftools-devel findutils curl tar unzip git cmake rpm-build python-srpm-macros" -altlinux_rpms="gcc gcc-c++ make libsnappy-devel libleveldb-devel gperftools-devel curl unzip git cmake ctest rpm-build rpmdevtools" +altlinux_rpms="gcc gcc-c++ make libsnappy-devel libleveldb-devel libgperftools-devel curl unzip git cmake ctest rpm-build rpmdevtools" cmake_installed () { info_msg "Check for installed cmake ..... " diff --git a/dsl/dsl.go b/dsl/dsl.go index bf4945939..1cf39afa5 100644 --- a/dsl/dsl.go +++ b/dsl/dsl.go @@ -71,6 +71,10 @@ type Aggregation struct { Fields []string `json:"fields"` } +type EqualPosition struct { + Positions []string `json:"positions"` +} + type sort Sort type Sort struct { @@ -80,13 +84,14 @@ type Sort struct { } type Filter struct { - Op string `json:"Op,omitempty"` - Field string `json:"Field,omitempty"` - Joined *JoinQuery `json:"Join_Query,omitempty"` - SubQ *SubQuery `json:"Subquery,omitempty"` - Cond string `json:"Cond,omitempty"` - Value interface{} `json:"Value,omitempty"` - Filters []Filter `json:"Filters,omitempty"` + Op string `json:"Op,omitempty"` + Field string `json:"Field,omitempty"` + Joined *JoinQuery `json:"Join_Query,omitempty"` + SubQ *SubQuery `json:"Subquery,omitempty"` + Cond string `json:"Cond,omitempty"` + Value interface{} `json:"Value,omitempty"` + EqualPositions []EqualPosition `json:"equal_positions,omitempty"` + Filters []Filter `json:"Filters,omitempty"` } type JoinOnCondition struct { @@ -136,13 +141,14 @@ type SubQuery struct { } type filter struct { - Op string `json:"op,omitempty"` - Field string `json:"field,omitempty"` - Joined *joinQuery `json:"join_query,omitempty"` - SubQ *subQuery `json:"subquery,omitempty"` - Cond string `json:"cond,omitempty"` - Value value `json:"value,omitempty"` - Filters []filter `json:"filters,omitempty"` + Op string `json:"op,omitempty"` + Field string `json:"field,omitempty"` + Joined *joinQuery `json:"join_query,omitempty"` + SubQ *subQuery `json:"subquery,omitempty"` + Cond string `json:"cond,omitempty"` + Value value `json:"value,omitempty"` + EqualPositions []EqualPosition `json:"equal_positions,omitempty"` + Filters []filter `json:"filters,omitempty"` } type value struct { @@ -216,6 +222,7 @@ func (f *Filter) fillFilter(flt *filter) error { f.Op = flt.Op f.Cond = flt.Cond f.Field = flt.Field + f.EqualPositions = flt.EqualPositions if flt.Joined != nil { f.Joined = &JoinQuery{joinQueryBase: joinQueryBase{Namespace: flt.Joined.Namespace, Type: flt.Joined.Type, Sort: flt.Joined.Sort, diff --git a/fulltext.md b/fulltext.md index a464a2b76..a6bfdddb0 100644 --- a/fulltext.md +++ b/fulltext.md @@ -18,6 +18,7 @@ Reindexer has builtin full text search engine. This document describes usage of - [Highlight](#highlight) - [Snippet](#snippet) - [Snippet_n](#snippet_n) + - [Debug_rank](#debug_rank) - [Typos algorithm](#typos-algorithm) - [Typos handling details](#typos-handling-details) - [More examples](#more-examples) @@ -193,7 +194,7 @@ It is possible to merge multiple queries results and sort final result by releva ``` ## Using select functions It is possible to use select functions to process result data. -For now you can use snippet, snippet_n and highlight. For composite indexes the result of the function will be written in to corresponding subfields. +For now you can use snippet, snippet_n and highlight, debug_rank. For composite indexes the result of the function will be written in to corresponding subfields. You can not put [,)\0] symbols in functions params. If the value contains special characters, it must be enclosed in single quotes. @@ -273,6 +274,10 @@ b.Query("items").Match("text", query).Limit(limit).Offset(offset).Functions("tex result: "{me text str}" +### Debug_rank + +This function outputs additional information about ranking of the found word in the text in the key-value format. Returned format and content may vary depending on reindexer's version. Works with `text`-index only. + ## Typos algorithm Reindexer finds misspelled words by matching terms with deleted symbols. diff --git a/query.go b/query.go index 815481f23..33537ef60 100644 --- a/query.go +++ b/query.go @@ -325,7 +325,6 @@ func (q *Query) WhereQuery(subQuery *Query, condition int, keys interface{}) *Qu } // Where - Add comparing two fields where condition to DB query -// For composite indexes keys must be []interface{}, with value of each subindex func (q *Query) WhereBetweenFields(firstField string, condition int, secondField string) *Query { q.ser.PutVarCUInt(queryBetweenFieldsCondition) q.ser.PutVarCUInt(q.nextOp) @@ -502,13 +501,13 @@ func (q *Query) WhereComposite(index string, condition int, keys ...interface{}) return q.Where(index, condition, keys) } -// WhereString - Add where condition to DB query with string args +// Match - Add where string EQ-condition to DB query with string args func (q *Query) Match(index string, keys ...string) *Query { return q.WhereString(index, EQ, keys...) } -// WhereString - Add where condition to DB query with bool args +// WhereBool - Add where condition to DB query with bool args func (q *Query) WhereBool(index string, condition int, keys ...bool) *Query { q.ser.PutVarCUInt(queryCondition).PutVString(index).PutVarCUInt(q.nextOp).PutVarCUInt(condition) @@ -658,14 +657,14 @@ func (q *Query) SortStFieldDistance(field1 string, field2 string, desc bool) *Qu return q.Sort(sb.String(), desc) } -// AND - next condition will added with AND +// AND - next condition will be added with AND // This is the default operation for WHERE statement. Do not have to be called explicitly in user's code. Used in DSL conversion func (q *Query) And() *Query { q.nextOp = opAND return q } -// OR - next condition will added with OR +// OR - next condition will be added with OR // Implements short-circuiting: // if the previous condition is successful the next will not be evaluated, but except Join conditions func (q *Query) Or() *Query { @@ -673,7 +672,7 @@ func (q *Query) Or() *Query { return q } -// Not - next condition will added with NOT AND +// Not - next condition will be added with NOT AND // Implements short-circuiting: // if the previous condition is failed the next will not be evaluated func (q *Query) Not() *Query { @@ -1047,6 +1046,9 @@ func (q *Query) Get() (item interface{}, found bool) { // GetCtx will execute query, and return 1 st item, panic on error func (q *Query) GetCtx(ctx context.Context) (item interface{}, found bool) { + if q.root != nil { + q = q.root + } iter := q.Limit(1).MustExecCtx(ctx) defer iter.Close() if iter.Next() { @@ -1062,6 +1064,9 @@ func (q *Query) GetJson() (json []byte, found bool) { // GetJsonCtx will execute query, and return 1 st item, panic on error func (q *Query) GetJsonCtx(ctx context.Context) (json []byte, found bool) { + if q.root != nil { + q = q.root + } it := q.Limit(1).ExecToJsonCtx(ctx) defer it.Close() if it.Error() != nil { diff --git a/reindexer_impl.go b/reindexer_impl.go index 36615f53d..9ae68efb7 100644 --- a/reindexer_impl.go +++ b/reindexer_impl.go @@ -1010,7 +1010,7 @@ func (db *reindexerImpl) mustBeginTx(ctx context.Context, namespace string) *Tx return tx } -func (db *reindexerImpl) addFilterDSL(filter *dsl.Filter, q *Query) error { +func (db *reindexerImpl) addFilterDSL(filter *dsl.Filter, q *Query, fields *map[string]bool) error { if filter.Field == "" { return ErrEmptyFieldName } @@ -1020,6 +1020,7 @@ func (db *reindexerImpl) addFilterDSL(filter *dsl.Filter, q *Query) error { } if filter.Value != nil || cond == bindings.ANY || cond == bindings.EMPTY { // Skip filter if value is nil (for backwards compatibility reasons) + (*fields)[filter.Field] = q.nextOp == opAND q.Where(filter.Field, cond, filter.Value) } else { q.And() @@ -1176,9 +1177,12 @@ func (db *reindexerImpl) addSubqueryDSL(filter *dsl.Filter, q *Query) error { } func (db *reindexerImpl) handleFiltersDSL(filters []dsl.Filter, joinIDs *map[string]int, q *Query) (*Query, error) { + equalPositionsFilters := make([]*dsl.Filter, 0, len(filters)) + fields := make(map[string]bool) + for fi := range filters { filter := &filters[fi] - switch strings.ToLower(filters[fi].Op) { + switch strings.ToLower(filter.Op) { case "": q.And() case "and": @@ -1188,7 +1192,7 @@ func (db *reindexerImpl) handleFiltersDSL(filters []dsl.Filter, joinIDs *map[str case "not": q.Not() default: - return nil, bindings.NewError(fmt.Sprintf("rq: dsl filter op is invalid: '%s'", filters[fi].Op), ErrCodeParams) + return nil, bindings.NewError(fmt.Sprintf("rq: dsl filter op is invalid: '%s'", filter.Op), ErrCodeParams) } if filter.Joined != nil { @@ -1247,14 +1251,63 @@ func (db *reindexerImpl) handleFiltersDSL(filters []dsl.Filter, joinIDs *map[str return nil, err } continue + } else if len(filter.EqualPositions) > 0 { + equalPositionsFilters = append(equalPositionsFilters, filter) + continue } - if err := db.addFilterDSL(filter, q); err != nil { + if err := db.addFilterDSL(filter, q, &fields); err != nil { return nil, err } } + + if err := db.processEqualPositions(q, equalPositionsFilters, fields); err != nil { + return nil, err + } + return q, nil } +func (db *reindexerImpl) processEqualPositions(q *Query, filters []*dsl.Filter, conditionFields map[string]bool) error { + for _, filter := range filters { + if filter.Cond != "" || + filter.Op != "" || + filter.Field != "" || + filter.Value != nil || + filter.Filters != nil || + filter.Joined != nil || + filter.SubQ != nil { + return bindings.NewError("rq: filter: filter with 'equal_positions'-field should not contain any other fields besides it", ErrCodeParams) + } + + for _, EqualPositionsElement := range filter.EqualPositions { + fieldsCount := len(EqualPositionsElement.Positions) + if fieldsCount < 2 { + return bindings.NewError(fmt.Sprintf("rq: filter: 'equal_positions' is supposed to have at least 2 arguments. Arguments: %v", + EqualPositionsElement.Positions), ErrCodeParams) + } + + fields := make([]string, 0, fieldsCount) + for _, field := range EqualPositionsElement.Positions { + isAndOp, exist := conditionFields[field] + if !exist { + return bindings.NewError("rq: filter: fields from 'equal_positions'-filter must be specified in the 'where'-conditions of other filters in the current bracket", + ErrCodeParams) + } + if !isAndOp { + return bindings.NewError(fmt.Sprintf("rq: filter: only AND operation allowed for equal position; equal position field with not AND operation: '%s'; equal position fields: %v", + field, + EqualPositionsElement.Positions), + ErrCodeParams) + } + fields = append(fields, field) + } + + q.EqualPosition(fields...) + } + } + return nil +} + func (db *reindexerImpl) addAggregationsDSL(q *Query, aggs []dsl.Aggregation) error { for _, agg := range aggs { if len(agg.Fields) == 0 { diff --git a/test/dsl_test.go b/test/dsl_test.go index 4c396ce5f..b5719ae91 100644 --- a/test/dsl_test.go +++ b/test/dsl_test.go @@ -26,6 +26,12 @@ type TestDSLJoinItem struct { JID int `reindex:"jid,,pk"` } +type TestDSLEqualPositionItem struct { + ID int `reindex:"id,,pk"` + ArrayField1 []int `reindex:"array_field_1"` + ArrayField2 []int `reindex:"array_field_2"` +} + func init() { tnamespaces["test_namespace_dsl"] = TestDSLItem{} tnamespaces["test_namespace_dsl_ft"] = TestDSLFtItem{} @@ -34,6 +40,8 @@ func init() { tnamespaces["test_namespace_dsl_2"] = TestDSLItem{} tnamespaces["test_namespace_dsl_joined_3"] = TestDSLJoinItem{} + + tnamespaces["test_namespace_dsl_equal_position"] = TestDSLEqualPositionItem{} } func newTestDSLItem(id int) interface{} { @@ -117,6 +125,15 @@ func getTestDSLJoinItemsIDs(items []interface{}) []int { return resultIDs } +func getTestDSLEqualPositionItemsIDs(items []interface{}) []int { + resultIDs := make([]int, len(items)) + for i, v := range items { + item := v.(*TestDSLEqualPositionItem) + resultIDs[i] = item.ID + } + return resultIDs +} + func execDSLTwice(t *testing.T, testF func(*testing.T, *reindexer.Query), jsonDSL string) { var marshaledJSON []byte { @@ -144,6 +161,21 @@ func execDSLTwice(t *testing.T, testF func(*testing.T, *reindexer.Query), jsonDS } } +func fillTestDSLEqualPositionItem(t *testing.T, ns string, start int, count int) { + tx := newTestTx(DB, ns) + for i := 0; i < count; i++ { + if err := tx.Upsert( + TestDSLEqualPositionItem{ + ID: start + i, + ArrayField1: []int{1 - i%2, 1, 2, 3, 100 * (i % 2)}, + ArrayField2: []int{0 + i%2, -1, -2, -3, 100}, + }); err != nil { + require.NoError(t, err) + } + } + tx.MustCommit() +} + func TestDSLQueries(t *testing.T) { t.Parallel() @@ -151,6 +183,7 @@ func TestDSLQueries(t *testing.T) { fillTestDSLFtItems(t, "test_namespace_dsl_ft") fillTestDSLJoinItems(t, "test_namespace_dsl_joined_1", 80, 40) fillTestDSLJoinItems(t, "test_namespace_dsl_joined_2", 10, 10) + fillTestDSLEqualPositionItem(t, "test_namespace_dsl_equal_position", 0, 10) t.Run("basic dsl parsing", func(t *testing.T) { const jsonDSL = ` @@ -1741,6 +1774,97 @@ func TestDSLQueries(t *testing.T) { require.Equal(t, expectedIDs, getTestDSLItemsIDs(items)) }, jsonDSL) }) + + t.Run("dsl with equal_positions", func(t *testing.T) { + const eqPosFilter = ` + { + "equal_positions": + [ + { + "positions": + [ + "array_field_1", + "array_field_2" + ] + } + ] + }` + + whereFilter := func(val1 int, val2 int) string { + return fmt.Sprintf( + ` + { + "field": "array_field_1", + "cond": "eq", + "value": %d + }, + { + "field": "array_field_2", + "cond": "eq", + "value": %d + }`, + val1, + val2, + ) + } + + // the corresponding sql-like condition: + // ( array_field_1 = 100 AND array_field_2 = 100 EQUAL_POSITION(array_field_1, array_field_2) ) + // AND + // ( + // ( array_field_1 = 1 AND array_field_2 = 0 EQUAL_POSITION(array_field_1, array_field_2) ) + // OR + // ( array_field_1 = 0 AND array_field_2 = 1 EQUAL_POSITION(array_field_1, array_field_2) ) + // ) + jsonDSL := fmt.Sprintf( + ` + { + "namespace": "test_namespace_dsl_equal_position", + "type": "select", + "filters": + [ + %[1]s, + %[4]s, + { + "filters": + [ + { + "filters": + [ + %[2]s, + %[4]s + ] + }, + { + "op": "or", + "filters": + [ + %[3]s, + %[4]s + ] + } + ] + } + ], + "sort": { + "field": "id" + } + }`, + whereFilter(100, 100), + whereFilter(1, 0), + whereFilter(0, 1), + eqPosFilter, + ) + + execDSLTwice(t, func(t *testing.T, q *reindexer.Query) { + it := q.MustExec() + require.NoError(t, it.Error()) + expectedIDs := []int{1, 3, 5, 7, 9} + items, err := it.FetchAll() + require.NoError(t, err) + require.Equal(t, expectedIDs, getTestDSLEqualPositionItemsIDs(items)) + }, jsonDSL) + }) } func TestDSLQueriesParsingErrors(t *testing.T) { @@ -2968,4 +3092,115 @@ func TestCreateDSLQueriesErrors(t *testing.T) { ` checkErrorQueryFrom(t, jsonDSL, "rq: nested join quieries are not supported") }) + + const wrongJsonDSLTmplt = ` + { + "namespace": "test_namespace_dsl_equal_position", + "type": "select", + "filters": + [ + { + "op": "and", + "cond": "eq", + "field": "f1", + "value": 0 + }, + { + "op": "and", + "cond": "eq", + "field": "f2", + "value": 0 + }, + %s + ] + }` + + testCase := func(errorMessage string, equalPositions string) { + checkErrorQueryFrom(t, fmt.Sprintf(wrongJsonDSLTmplt, equalPositions), errorMessage) + } + + t.Run("dsl equal_positions must contain at least 2 arguments", func(t *testing.T) { + testCase( + "rq: filter: 'equal_positions' is supposed to have at least 2 arguments. Arguments: [f1]", + `{ + "equal_positions": + [ + { + "positions": + [ + "f1" + ] + } + ] + + }`, + ) + }) + + t.Run("dsl equal_positions fields must be specified in other filters", func(t *testing.T) { + testCase( + "rq: filter: fields from 'equal_positions'-filter must be specified in the 'where'-conditions of other filters in the current bracket", + `{ + "equal_positions": + [ + { + "positions": + [ + "f1", + "f2", + "f3" + ] + } + ] + + }`, + ) + }) + + t.Run("dsl equal_positions should not contain extra fields", func(t *testing.T) { + testCase( + "rq: filter: filter with 'equal_positions'-field should not contain any other fields besides it", + `{ + "equal_positions": + [ + { + "positions": + [ + "f1", + "f2" + ] + } + ], + "value": 100, + "cond": "eq", + "field": "f1" + }`, + ) + }) + + t.Run("dsl equal_positions fields should be represented using AND operation only", func(t *testing.T) { + testCase( + "rq: filter: only AND operation allowed for equal position; equal position field with not AND operation: 'f3'; equal position fields: [f1 f2 f3]", + `{ + "op": "or", + "cond": "eq", + "field": "f3", + "value": 0 + }, + { + "equal_positions": + [ + { + "positions": + [ + "f1", + "f2", + "f3" + ] + } + ] + + }`, + ) + }) } diff --git a/test/queries_test.go b/test/queries_test.go index bd42e4747..7c46f356a 100644 --- a/test/queries_test.go +++ b/test/queries_test.go @@ -558,7 +558,7 @@ func TestQueries(t *testing.T) { panic(err) } - CheckTestItemsQueries(t, testCaseWithIDOnlyIndexe) + CheckTestItemsQueries(t, testCaseWithIDOnlyIndexes) }) t.Run("Sparse indexed queries", func(t *testing.T) { t.Parallel() @@ -1285,7 +1285,7 @@ var testCaseWithCommonIndexes = IndexesTestCase{ }, Item: TestItem{}, } -var testCaseWithIDOnlyIndexe = IndexesTestCase{ +var testCaseWithIDOnlyIndexes = IndexesTestCase{ Name: "TEST WITH ID ONLY INDEX", Namespace: "test_items_id_only", Options: sortDistinctOptions{ diff --git a/test/replication_v3_compatibility_test.go b/test/replication_v3_compatibility_test.go index 8501bde4e..bb9fda829 100644 --- a/test/replication_v3_compatibility_test.go +++ b/test/replication_v3_compatibility_test.go @@ -414,7 +414,7 @@ func TestReplV3CompatibilityChainTransition(t *testing.T) { const dataCount = 1000 nodes := []nodeData{{ - ServerID: 1, + ServerID: 0, Cfg: config.DefaultServerConfig(), HTTPAddr: "127.0.0.1:31088", RPCAddr: "127.0.0.1:31534",