diff --git a/apps/esp_pio/src/app_context.cpp b/apps/esp_pio/src/app_context.cpp index 25a9f19d..91ecdcd4 100644 --- a/apps/esp_pio/src/app_context.cpp +++ b/apps/esp_pio/src/app_context.cpp @@ -11,8 +11,10 @@ #include "board/MotionBoard.h" #include "chat/infra/mesh_protocol_utils.h" #include "chat/runtime/self_identity_policy.h" +#include "platform/esp/arduino_common/memory_diag.h" #include "sys/event_bus.h" #include "ui/chat_ui_runtime_proxy.h" +#include "ui/ui_boot.h" #ifdef USING_ST25R3916 #endif #include @@ -259,25 +261,40 @@ bool AppContext::init(BoardBase& board, LoraBoard* lora_board, GpsBoard* gps_boa } assignBoards(board, lora_board, gps_board, motion_board); + platform::esp::arduino_common::memory_diag::logHeapSnapshot("appctx.after_assign_boards"); if (!sys::EventBus::init()) { return false; } + platform::esp::arduino_common::memory_diag::logHeapSnapshot("appctx.after_event_bus"); if (platform_bindings_.load_app_config) { + ::ui::boot::set_log_line("Loading app config..."); platform_bindings_.load_app_config(config_); } + platform::esp::arduino_common::memory_diag::logHeapSnapshot("appctx.after_load_config"); + ::ui::boot::set_log_line("Initializing GPS services..."); initGpsRuntime(disable_hw_init); + platform::esp::arduino_common::memory_diag::logHeapSnapshot("appctx.after_gps_runtime"); initTrackRecorder(); + platform::esp::arduino_common::memory_diag::logHeapSnapshot("appctx.after_track_recorder"); + ::ui::boot::set_log_line("Initializing chat runtime..."); initChatRuntime(use_mock_adapter); + platform::esp::arduino_common::memory_diag::logHeapSnapshot("appctx.after_chat_runtime"); + ::ui::boot::set_log_line("Initializing team services..."); initTeamServices(); + platform::esp::arduino_common::memory_diag::logHeapSnapshot("appctx.after_team_services"); + ::ui::boot::set_log_line("Initializing contacts..."); initContactServices(); + platform::esp::arduino_common::memory_diag::logHeapSnapshot("appctx.after_contact_services"); if (platform_bindings_.finalize_startup) { + ::ui::boot::set_log_line("Finalizing startup..."); platform_bindings_.finalize_startup(*this); } + platform::esp::arduino_common::memory_diag::logHeapSnapshot("appctx.after_finalize_startup"); return true; } diff --git a/apps/esp_pio/src/startup_runtime.cpp b/apps/esp_pio/src/startup_runtime.cpp index abe83479..d3acbfbb 100644 --- a/apps/esp_pio/src/startup_runtime.cpp +++ b/apps/esp_pio/src/startup_runtime.cpp @@ -12,6 +12,7 @@ #include "ui/app_registry.h" #include "ui/app_runtime.h" #include "ui/startup_shell.h" +#include "ui/ui_boot.h" namespace { @@ -77,6 +78,7 @@ void run() ui::startup_shell::prepareBootUi(waking_from_sleep); bool use_mock = false; + ui::boot::set_log_line("Initializing app context..."); if (apps::esp_pio::app_runtime_access::initialize(use_mock)) { const auto& runtime_status = apps::esp_pio::app_runtime_access::status(); @@ -94,7 +96,9 @@ void run() runtime_status.background_tasks_started ? 1 : 0); } + ui::boot::set_log_line("Building main menu..."); initializeShell(); + ui::boot::set_log_line("Startup complete"); finishStartup(waking_from_sleep); } diff --git a/docs/LOCALE_PACKS.md b/docs/LOCALE_PACKS.md index af41b770..9bac6e44 100644 --- a/docs/LOCALE_PACKS.md +++ b/docs/LOCALE_PACKS.md @@ -193,10 +193,10 @@ Manifests are plain `key=value` files. ```ini kind=font -id=zh-hans-cjk -display_name=Simplified Chinese CJK +id=zh-hans-core +display_name=Simplified Chinese Core usage=both -estimated_ram_bytes=476075 +estimated_ram_bytes=217456 source=binfont file=font.bin ranges=ranges.txt @@ -249,6 +249,20 @@ ime_pack=zh-hans-pinyin strings=strings.tsv ``` +Example with tiered Chinese coverage: + +```ini +kind=locale +id=zh-Hans +display_name=Simplified Chinese +native_name=简体中文 +ui_font_pack=zh-hans-core +content_font_pack=zh-hans-core +preferred_content_supplement_packs=zh-hans-ext +ime_pack=zh-hans-pinyin +strings=strings.tsv +``` + Fields: - `id` @@ -261,6 +275,8 @@ Fields: Font pack used for interface chrome in this locale. - `content_font_pack` Font pack preferred for content surfaces in this locale. +- `preferred_content_supplement_packs` + Optional comma-separated list of content supplement font packs to try first when this locale encounters missing glyphs. - `ime_pack` Optional IME dependency. - `strings` diff --git a/modules/ui_shared/include/ui/assets/fonts/font_utils.h b/modules/ui_shared/include/ui/assets/fonts/font_utils.h index bade8bdf..cdc1a30e 100644 --- a/modules/ui_shared/include/ui/assets/fonts/font_utils.h +++ b/modules/ui_shared/include/ui/assets/fonts/font_utils.h @@ -27,6 +27,7 @@ enum class FontScope : uint8_t struct LocalizedFontBinding { const lv_font_t* base = nullptr; + const lv_font_t* explicit_fallback = nullptr; FontScope scope = FontScope::Ui; lv_font_t composed{}; bool used = false; @@ -88,20 +89,25 @@ inline void sync_localized_font_binding(LocalizedFontBinding& binding) } binding.composed = *binding.base; - const lv_font_t* fallback = binding.scope == FontScope::Content - ? ::ui::i18n::active_content_font_fallback() - : ::ui::i18n::active_ui_font_fallback(); + const lv_font_t* fallback = binding.explicit_fallback + ? binding.explicit_fallback + : (binding.scope == FontScope::Content + ? ::ui::i18n::active_content_font_fallback() + : ::ui::i18n::active_ui_font_fallback()); binding.composed.fallback = (fallback && fallback != binding.base) ? fallback : nullptr; } -inline LocalizedFontBinding* find_localized_font_binding(const lv_font_t* base_font, FontScope scope) +inline LocalizedFontBinding* find_localized_font_binding(const lv_font_t* base_font, + FontScope scope, + const lv_font_t* explicit_fallback = nullptr) { LocalizedFontBinding* bindings = localized_font_binding_storage(); const std::size_t binding_count = localized_font_binding_storage_size(); for (std::size_t index = 0; index < binding_count; ++index) { LocalizedFontBinding& binding = bindings[index]; - if (binding.used && binding.base == base_font && binding.scope == scope) + if (binding.used && binding.base == base_font && binding.scope == scope && + binding.explicit_fallback == explicit_fallback) { return &binding; } @@ -109,7 +115,9 @@ inline LocalizedFontBinding* find_localized_font_binding(const lv_font_t* base_f return nullptr; } -inline LocalizedFontBinding* acquire_localized_font_binding(const lv_font_t* base_font, FontScope scope) +inline LocalizedFontBinding* acquire_localized_font_binding(const lv_font_t* base_font, + FontScope scope, + const lv_font_t* explicit_fallback = nullptr) { LocalizedFontBinding* bindings = localized_font_binding_storage(); const std::size_t binding_count = localized_font_binding_storage_size(); @@ -120,6 +128,7 @@ inline LocalizedFontBinding* acquire_localized_font_binding(const lv_font_t* bas { binding.used = true; binding.base = base_font; + binding.explicit_fallback = explicit_fallback; binding.scope = scope; sync_localized_font_binding(binding); return &binding; @@ -193,6 +202,35 @@ inline const lv_font_t* localized_font(const lv_font_t* ascii_font = nullptr) return localized_font(FontScope::Ui, nullptr, ascii_font); } +inline const lv_font_t* composed_font_with_fallback(const lv_font_t* ascii_font, + const lv_font_t* fallback_font, + FontScope scope = FontScope::Ui) +{ + const lv_font_t* base_font = unwrap_localized_font(ascii_font ? ascii_font : ui_chrome_font()); + const lv_font_t* fallback = unwrap_localized_font(fallback_font); + if (!base_font) + { + base_font = ui_chrome_font(); + } + if (!fallback || fallback == base_font) + { + return base_font; + } + + if (LocalizedFontBinding* existing = find_localized_font_binding(base_font, scope, fallback)) + { + sync_localized_font_binding(*existing); + return &existing->composed; + } + + if (LocalizedFontBinding* created = acquire_localized_font_binding(base_font, scope, fallback)) + { + return &created->composed; + } + + return base_font; +} + inline const lv_font_t* localized_font(const char* text, const lv_font_t* ascii_font) { return localized_font(FontScope::Ui, text, ascii_font); @@ -212,6 +250,10 @@ inline void apply_font(lv_obj_t* label, const lv_font_t* font) { if (label && font) { + if (lv_obj_get_style_text_font(label, LV_PART_MAIN) == font) + { + return; + } lv_obj_set_style_text_font(label, font, 0); } } diff --git a/modules/ui_shared/include/ui/localization.h b/modules/ui_shared/include/ui/localization.h index 0d1c9a72..eeade609 100644 --- a/modules/ui_shared/include/ui/localization.h +++ b/modules/ui_shared/include/ui/localization.h @@ -31,6 +31,7 @@ bool set_locale(const char* locale_id, bool persist = true); bool set_locale_by_index(std::size_t index, bool persist = true); const lv_font_t* active_ui_font_fallback(); const lv_font_t* active_content_font_fallback(); +const lv_font_t* locale_preview_font(const char* locale_id, const lv_font_t* ascii_font = nullptr); bool ensure_content_font_for_text(const char* text); const char* active_ime_pack_id(); bool active_locale_supports_script_input(); diff --git a/modules/ui_shared/include/ui/runtime/pack_repository.h b/modules/ui_shared/include/ui/runtime/pack_repository.h index 55d56297..84847cce 100644 --- a/modules/ui_shared/include/ui/runtime/pack_repository.h +++ b/modules/ui_shared/include/ui/runtime/pack_repository.h @@ -48,5 +48,6 @@ bool is_supported(); bool load_installed_packages(std::vector& out_installed, std::string& out_error); bool fetch_catalog(std::vector& out_packages, std::string& out_error); bool install_package(const PackageRecord& package, std::string& out_error); +bool uninstall_package(const PackageRecord& package, std::string& out_error); } // namespace ui::runtime::packs diff --git a/modules/ui_shared/include/ui/ui_boot.h b/modules/ui_shared/include/ui/ui_boot.h index 6c05d6f1..e78a8c70 100644 --- a/modules/ui_shared/include/ui/ui_boot.h +++ b/modules/ui_shared/include/ui/ui_boot.h @@ -14,6 +14,9 @@ namespace ui::boot // Show the boot splash overlay (background + logo fade-in). void show(); +// Update the single-line boot log shown in the lower-left corner. +void set_log_line(const char* text); + // Signal that background loading is complete. // Splash will hide after the minimum display time has elapsed. void mark_ready(); diff --git a/modules/ui_shared/src/ui/i18n/resource_pack_registry.cpp b/modules/ui_shared/src/ui/i18n/resource_pack_registry.cpp index 9f406607..d674bbd3 100644 --- a/modules/ui_shared/src/ui/i18n/resource_pack_registry.cpp +++ b/modules/ui_shared/src/ui/i18n/resource_pack_registry.cpp @@ -83,6 +83,7 @@ struct LocalePackRecord std::string native_name; std::string ui_font_pack_id; std::string content_font_pack_id; + std::vector preferred_content_supplement_pack_ids; std::string ime_pack_id; bool builtin = false; std::vector> translations; @@ -185,6 +186,35 @@ std::string lowercase_ascii(std::string value) return value; } +std::vector split_csv_strings(const char* value) +{ + std::vector items; + if (!value || value[0] == '\0') + { + return items; + } + + std::size_t start = 0; + const std::string text = value; + while (start <= text.size()) + { + const std::size_t end = text.find(',', start); + std::string item = text.substr(start, end == std::string::npos ? std::string::npos : (end - start)); + trim_in_place(item); + if (!item.empty()) + { + items.push_back(std::move(item)); + } + if (end == std::string::npos) + { + break; + } + start = end + 1U; + } + + return items; +} + std::string join_path(const std::string& base, const std::string& child) { if (base.empty()) @@ -837,11 +867,65 @@ void unload_external_font_pack(FontPackRecord& pack) #endif } -void release_runtime_fonts() +bool should_retain_loaded_external_pack(FontPackRecord* pack) +{ + return pack != nullptr && !pack->builtin && is_font_runtime_loaded(*pack); +} + +bool is_retained_pack(const std::vector& retained_packs, const FontPackRecord* pack) +{ + if (pack == nullptr) + { + return false; + } + + for (const FontPackRecord* retained : retained_packs) + { + if (retained == pack) + { + return true; + } + } + + return false; +} + +void append_retained_external_pack(std::vector& retained_packs, FontPackRecord* pack) +{ + if (should_retain_loaded_external_pack(pack)) + { + append_unique_pack(retained_packs, pack); + } +} + +bool can_preserve_content_pack(FontPackRecord* pack, + FontPackRecord* next_ui_pack, + FontPackRecord* next_content_pack) +{ + if (!should_retain_loaded_external_pack(pack) || !font_pack_supports_content(*pack)) + { + return false; + } + if (pack == next_ui_pack || pack == next_content_pack) + { + return false; + } + + const auto& profile = ::ui::runtime::current_memory_profile(); + if (profile.max_content_supplement_packs == 0 || profile.max_content_supplement_ram_bytes == 0) + { + return false; + } + + return pack->estimated_ram_bytes == 0 || + pack->estimated_ram_bytes <= profile.max_content_supplement_ram_bytes; +} + +void release_runtime_fonts_except(const std::vector& retained_packs) { for (auto& pack : s_font_packs) { - if (!pack.builtin) + if (!pack.builtin && !is_retained_pack(retained_packs, &pack)) { unload_external_font_pack(pack); } @@ -852,6 +936,11 @@ void release_runtime_fonts() reset_font_chain(s_content_font_chain); } +void release_runtime_fonts() +{ + release_runtime_fonts_except({}); +} + bool load_font_pack(FontPackRecord& pack) { if (pack.builtin) @@ -868,6 +957,11 @@ bool load_font_pack(FontPackRecord& pack) } #if UI_I18N_HAVE_BINFONT + std::printf("%s font load begin id=%s source=%s est_ram=%lu\n", + kLogTag, + pack.id.c_str(), + pack.source_path.c_str(), + static_cast(pack.estimated_ram_bytes)); pack.owned_font = lv_binfont_create(pack.source_path.c_str()); if (pack.owned_font == nullptr) { @@ -1044,6 +1138,68 @@ bool can_add_content_supplement(const FontPackRecord& pack) FontPackRecord* choose_content_supplement(const std::vector& missing) { + auto choose_best_candidate = + [&](const std::vector& candidates) -> FontPackRecord* + { + FontPackRecord* best = nullptr; + std::size_t best_hits = 0; + std::size_t best_bytes = 0; + + for (FontPackRecord* pack : candidates) + { + if (!pack || pack == s_active_content_font_pack || pack == s_active_ui_font_pack) + { + continue; + } + if (!font_pack_supports_content(*pack)) + { + continue; + } + if (pack->coverage.empty()) + { + continue; + } + if (!can_add_content_supplement(*pack)) + { + continue; + } + + const std::size_t hits = coverage_hit_count(*pack, missing); + if (hits == 0) + { + continue; + } + + const std::size_t bytes = pack->estimated_ram_bytes; + if (best == nullptr || hits > best_hits || (hits == best_hits && bytes < best_bytes)) + { + best = pack; + best_hits = hits; + best_bytes = bytes; + } + } + + return best; + }; + + if (s_active_locale != nullptr && !s_active_locale->preferred_content_supplement_pack_ids.empty()) + { + std::vector preferred_candidates; + preferred_candidates.reserve(s_active_locale->preferred_content_supplement_pack_ids.size()); + for (const std::string& pack_id : s_active_locale->preferred_content_supplement_pack_ids) + { + if (FontPackRecord* pack = find_pack_by_id(s_font_packs, pack_id.c_str())) + { + append_unique_pack(preferred_candidates, pack); + } + } + + if (FontPackRecord* best = choose_best_candidate(preferred_candidates)) + { + return best; + } + } + FontPackRecord* best = nullptr; std::size_t best_hits = 0; std::size_t best_bytes = 0; @@ -1325,6 +1481,14 @@ bool parse_locale_strings(const std::string& path, line_start = line_end + 1U; } + std::sort(out.begin(), + out.end(), + [](const std::pair& lhs, + const std::pair& rhs) + { + return lhs.first < rhs.first; + }); + return !out.empty(); } @@ -1376,6 +1540,15 @@ bool catalog_external_locale_pack(const std::string& pack_dir) { pack.content_font_pack_id = content_font_pack; } + if (const char* preferred_supplements = + manifest_value(manifest, "preferred_content_supplement_packs")) + { + pack.preferred_content_supplement_pack_ids = split_csv_strings(preferred_supplements); + } + else if (const char* supplements = manifest_value(manifest, "content_supplement_packs")) + { + pack.preferred_content_supplement_pack_ids = split_csv_strings(supplements); + } if (pack.content_font_pack_id.empty()) { pack.content_font_pack_id = pack.ui_font_pack_id; @@ -1511,6 +1684,28 @@ bool locale_dependencies_resolved(const LocalePackRecord& locale) locale.ime_pack_id.c_str()); return false; } + for (const std::string& supplement_id : locale.preferred_content_supplement_pack_ids) + { + const FontPackRecord* supplement = find_pack_by_id(s_font_packs, supplement_id.c_str()); + if (supplement == nullptr) + { + std::printf("%s skip locale id=%s reason=missing_content_supplement_pack font=%s\n", + kLogTag, + locale.id.c_str(), + supplement_id.c_str()); + return false; + } + if (!font_pack_supports_content(*supplement)) + { + std::printf( + "%s skip locale id=%s reason=content_supplement_usage font=%s usage=%s\n", + kLogTag, + locale.id.c_str(), + supplement->id.c_str(), + usage_name(supplement->usage)); + return false; + } + } return true; } @@ -1599,14 +1794,27 @@ void clear_registry() s_registry_ready = false; } -bool activate_locale(LocalePackRecord* locale) +bool activate_locale_internal(LocalePackRecord* locale, FontPackRecord* preserved_content_pack) { - release_runtime_fonts(); + FontPackRecord* next_ui_font_pack = + locale ? find_pack_by_id(s_font_packs, locale->ui_font_pack_id.c_str()) : nullptr; + FontPackRecord* next_content_font_pack = + locale ? find_pack_by_id(s_font_packs, locale->content_font_pack_id.c_str()) : nullptr; + if (preserved_content_pack == nullptr && + can_preserve_content_pack(s_active_content_font_pack, next_ui_font_pack, next_content_font_pack)) + { + preserved_content_pack = s_active_content_font_pack; + } + + std::vector retained_packs; + append_retained_external_pack(retained_packs, next_ui_font_pack); + append_retained_external_pack(retained_packs, next_content_font_pack); + append_retained_external_pack(retained_packs, preserved_content_pack); + release_runtime_fonts_except(retained_packs); s_active_locale = locale; - s_active_ui_font_pack = locale ? find_pack_by_id(s_font_packs, locale->ui_font_pack_id.c_str()) : nullptr; - s_active_content_font_pack = - locale ? find_pack_by_id(s_font_packs, locale->content_font_pack_id.c_str()) : nullptr; + s_active_ui_font_pack = next_ui_font_pack; + s_active_content_font_pack = next_content_font_pack; s_active_ime_pack = (locale && !locale->ime_pack_id.empty()) ? find_pack_by_id(s_ime_packs, locale->ime_pack_id.c_str()) : nullptr; @@ -1618,11 +1826,19 @@ bool activate_locale(LocalePackRecord* locale) LocalePackRecord* fallback = resolve_active_locale(kDefaultLocaleId); if (fallback && fallback != locale) { - return activate_locale(fallback); + return activate_locale_internal(fallback, preserved_content_pack); } } } + if (can_preserve_content_pack(preserved_content_pack, s_active_ui_font_pack, s_active_content_font_pack)) + { + append_unique_pack(s_content_supplement_packs, preserved_content_pack); + std::printf("%s font retain id=%s role=content_supplement\n", + kLogTag, + preserved_content_pack->id.c_str()); + } + rebuild_runtime_font_chains(); std::printf("%s active locale=%s ui_font=%s content_font=%s ime=%s ui_chain=%s content_chain=%s\n", @@ -1636,6 +1852,11 @@ bool activate_locale(LocalePackRecord* locale) return true; } +bool activate_locale(LocalePackRecord* locale) +{ + return activate_locale_internal(locale, nullptr); +} + void rebuild_registry() { clear_registry(); @@ -1665,12 +1886,18 @@ const char* lookup_translation(const LocalePackRecord& locale, const char* engli return ""; } - for (const auto& entry : locale.translations) - { - if (entry.first == english) + const auto it = std::lower_bound( + locale.translations.begin(), + locale.translations.end(), + english, + [](const std::pair& entry, const char* key) { - return entry.second.c_str(); - } + return entry.first < key; + }); + + if (it != locale.translations.end() && it->first == english) + { + return it->second.c_str(); } return english; @@ -1775,6 +2002,33 @@ const lv_font_t* active_content_font_fallback() return s_content_font_chain.head; } +const lv_font_t* locale_preview_font(const char* locale_id, const lv_font_t* ascii_font) +{ + ensure_registry(); + + const lv_font_t* base_font = ascii_font ? ascii_font : ::ui::fonts::ui_chrome_font(); + if (!locale_id || locale_id[0] == '\0') + { + return base_font; + } + + LocalePackRecord* locale = find_pack_by_id(s_locale_packs, locale_id); + if (locale == nullptr) + { + return base_font; + } + + FontPackRecord* ui_pack = find_pack_by_id(s_font_packs, locale->ui_font_pack_id.c_str()); + if (ui_pack == nullptr || !ensure_font_pack_loaded(ui_pack)) + { + return base_font; + } + + return ::ui::fonts::composed_font_with_fallback(base_font, + resolved_font(ui_pack), + ::ui::fonts::FontScope::Ui); +} + bool ensure_content_font_for_text(const char* text) { ensure_registry(); diff --git a/modules/ui_shared/src/ui/runtime/memory_profile.cpp b/modules/ui_shared/src/ui/runtime/memory_profile.cpp index 988d094e..ab63834b 100644 --- a/modules/ui_shared/src/ui/runtime/memory_profile.cpp +++ b/modules/ui_shared/src/ui/runtime/memory_profile.cpp @@ -25,7 +25,7 @@ MemoryProfile make_standard_profile() profile.kind = MemoryProfileKind::Standard; profile.max_locale_font_ram_bytes = 768U * 1024U; profile.max_content_supplement_ram_bytes = 640U * 1024U; - profile.max_content_supplement_packs = 1; + profile.max_content_supplement_packs = 2; profile.max_map_decode_tiles = 4; profile.retain_map_decode_cache_on_page_exit = false; return profile; diff --git a/modules/ui_shared/src/ui/runtime/pack_repository.cpp b/modules/ui_shared/src/ui/runtime/pack_repository.cpp index 594c1d73..7fdd0373 100644 --- a/modules/ui_shared/src/ui/runtime/pack_repository.cpp +++ b/modules/ui_shared/src/ui/runtime/pack_repository.cpp @@ -52,12 +52,14 @@ namespace constexpr const char* kCatalogUrl = "https://vicliu624.github.io/trail-mate/data/packs.json"; constexpr const char* kCatalogBaseUrl = "https://vicliu624.github.io/trail-mate"; constexpr const char* kPackRoot = "/trailmate/packs"; -constexpr const char* kIndexDir = "/trailmate/packs/.index"; -constexpr const char* kTempDir = "/trailmate/packs/.index/tmp"; -constexpr const char* kInstalledIndexPath = "/trailmate/packs/.index/installed.json"; +constexpr const char* kIndexDir = "/trailmate/packs/index"; +constexpr const char* kTempDir = "/trailmate/packs/index/tmp"; +constexpr const char* kInstalledIndexPath = "/trailmate/packs/index/installed.json"; +constexpr const char* kLegacyInstalledIndexPath = "/trailmate/packs/.index/installed.json"; constexpr int kHttpBufferSize = 1024; constexpr int kHttpTxBufferSize = 512; constexpr std::size_t kTlsLargeAllocThresholdBytes = 4096; +constexpr std::size_t kFileWriteChunkBytes = 4096; constexpr std::size_t kZipEocdMinSize = 22; constexpr std::size_t kZipTailSearchMax = 0x10000 + kZipEocdMinSize; constexpr std::uint32_t kZipEocdSignature = 0x06054B50u; @@ -180,6 +182,27 @@ std::string join_url(const std::string& base, const std::string& path) return normalized_base + "/" + path; } +std::string join_logical_path(const std::string& base, const std::string& leaf) +{ + if (base.empty()) + { + return leaf; + } + if (leaf.empty()) + { + return base; + } + if (leaf.front() == '/') + { + return leaf; + } + if (base.back() == '/') + { + return base + leaf; + } + return base + "/" + leaf; +} + std::string active_memory_profile_name() { const ui::runtime::MemoryProfile& profile = ui::runtime::current_memory_profile(); @@ -192,6 +215,7 @@ struct ParsedVersion int minor = 0; int patch = 0; std::string prerelease; + bool valid = false; }; ParsedVersion parse_version(const std::string& text) @@ -203,6 +227,23 @@ ParsedVersion parse_version(const std::string& text) } std::string numeric = text; + + const std::size_t first_digit = numeric.find_first_of("0123456789"); + if (first_digit == std::string::npos) + { + return version; + } + if (first_digit > 0) + { + numeric = numeric.substr(first_digit); + } + + const std::size_t plus = numeric.find('+'); + if (plus != std::string::npos) + { + numeric = numeric.substr(0, plus); + } + const std::size_t dash = numeric.find('-'); if (dash != std::string::npos) { @@ -221,7 +262,13 @@ ParsedVersion parse_version(const std::string& text) end == std::string::npos ? std::string::npos : (end - start)); if (!token.empty()) { - parts[part_index] = std::atoi(token.c_str()); + char* parse_end = nullptr; + const long parsed = std::strtol(token.c_str(), &parse_end, 10); + if (parse_end != token.c_str()) + { + parts[part_index] = static_cast(parsed); + version.valid = true; + } } ++part_index; if (end == std::string::npos) @@ -279,25 +326,32 @@ bool ensure_dir_recursive(const std::string& logical_dir) } std::string current; - for (char ch : logical_dir) + std::size_t start = 0; + while (start < logical_dir.size()) { - current.push_back(ch); - if (ch != '/') + const std::size_t slash = logical_dir.find('/', start); + const std::size_t end = + (slash == std::string::npos) ? logical_dir.size() : slash; + const std::string segment = logical_dir.substr(start, end - start); + if (!segment.empty()) { - continue; - } - if (!current.empty() && !SD.exists(current.c_str())) - { - if (!SD.mkdir(current.c_str())) + current.push_back('/'); + current += segment; + if (!SD.exists(current.c_str())) { - return false; + if (!SD.mkdir(current.c_str())) + { + std::printf("[Packs] mkdir failed path=%s\n", current.c_str()); + return false; + } } } - } - if (!SD.exists(logical_dir.c_str())) - { - return SD.mkdir(logical_dir.c_str()); + if (slash == std::string::npos) + { + break; + } + start = slash + 1; } return true; } @@ -326,12 +380,33 @@ bool write_binary_file(const std::string& logical_path, const void* data, std::s File file = SD.open(logical_path.c_str(), FILE_WRITE); if (!file) { + std::printf("[Packs] open for write failed path=%s len=%lu\n", + logical_path.c_str(), + static_cast(len)); return false; } - const std::size_t written = file.write(static_cast(data), len); + const std::uint8_t* bytes = static_cast(data); + std::size_t written = 0; + while (written < len) + { + const std::size_t chunk = std::min(kFileWriteChunkBytes, len - written); + const std::size_t chunk_written = file.write(bytes + written, chunk); + if (chunk_written != chunk) + { + std::printf("[Packs] write failed path=%s offset=%lu chunk=%lu wrote=%lu total=%lu\n", + logical_path.c_str(), + static_cast(written), + static_cast(chunk), + static_cast(chunk_written), + static_cast(len)); + file.close(); + return false; + } + written += chunk_written; + } file.close(); - return written == len; + return true; } bool write_text_file(const std::string& logical_path, const std::string& text) @@ -381,6 +456,68 @@ bool remove_file_if_exists(const std::string& logical_path) return SD.remove(logical_path.c_str()); } +bool remove_dir_recursive_if_exists(const std::string& logical_path) +{ + if (logical_path.empty() || !SD.exists(logical_path.c_str())) + { + return true; + } + + File node = SD.open(logical_path.c_str(), FILE_READ); + if (!node) + { + return false; + } + + if (!node.isDirectory()) + { + node.close(); + return SD.remove(logical_path.c_str()); + } + + while (true) + { + File entry = node.openNextFile(); + if (!entry) + { + break; + } + + std::string child_path = entry.name(); + if (!child_path.empty() && child_path.front() != '/') + { + child_path = join_logical_path(logical_path, child_path); + } + + const bool is_dir = entry.isDirectory(); + entry.close(); + + if (child_path.empty()) + { + continue; + } + + if (is_dir) + { + if (!remove_dir_recursive_if_exists(child_path)) + { + node.close(); + return false; + } + continue; + } + + if (!SD.remove(child_path.c_str())) + { + node.close(); + return false; + } + } + + node.close(); + return SD.rmdir(logical_path.c_str()); +} + class RandomAccessFile { public: @@ -514,9 +651,23 @@ bool write_binary_file(const std::string& logical_path, const void* data, std::s { return false; } - const std::size_t written = std::fwrite(data, 1, len, file); + + const std::uint8_t* bytes = static_cast(data); + std::size_t written = 0; + while (written < len) + { + const std::size_t chunk = std::min(kFileWriteChunkBytes, len - written); + const std::size_t chunk_written = std::fwrite(bytes + written, 1, chunk, file); + if (chunk_written != chunk) + { + std::fclose(file); + return false; + } + written += chunk_written; + } + std::fclose(file); - return written == len; + return true; } bool write_text_file(const std::string& logical_path, const std::string& text) @@ -582,6 +733,74 @@ bool remove_file_if_exists(const std::string& logical_path) return std::remove(host_path(logical_path).c_str()) == 0; } +bool remove_dir_recursive_if_exists(const std::string& logical_path) +{ + if (logical_path.empty()) + { + return true; + } + + const std::string host_dir = host_path(logical_path); + struct stat st + { + }; + if (::stat(host_dir.c_str(), &st) != 0) + { + return errno == ENOENT; + } + + if (!S_ISDIR(st.st_mode)) + { + return std::remove(host_dir.c_str()) == 0; + } + + DIR* dir = ::opendir(host_dir.c_str()); + if (!dir) + { + return false; + } + + bool ok = true; + while (ok) + { + struct dirent* entry = ::readdir(dir); + if (!entry) + { + break; + } + + const char* name = entry->d_name; + if (!name || std::strcmp(name, ".") == 0 || std::strcmp(name, "..") == 0) + { + continue; + } + + const std::string child_logical = join_logical_path(logical_path, name); + const std::string child_host = host_path(child_logical); + + struct stat child_st + { + }; + if (::stat(child_host.c_str(), &child_st) != 0) + { + ok = false; + break; + } + + if (S_ISDIR(child_st.st_mode)) + { + ok = remove_dir_recursive_if_exists(child_logical); + } + else + { + ok = std::remove(child_host.c_str()) == 0; + } + } + + ::closedir(dir); + return ok && ::rmdir(host_dir.c_str()) == 0; +} + class RandomAccessFile { public: @@ -1011,7 +1230,24 @@ bool compatible_with_firmware(const PackageRecord& package) { return true; } - return compare_versions(platform::ui::device::firmware_version(), + + const char* current_version = platform::ui::device::firmware_version(); + const ParsedVersion current = parse_version(current_version ? current_version : ""); + const ParsedVersion required = parse_version(package.min_firmware_version); + + if (!required.valid) + { + return true; + } + if (!current.valid) + { + std::printf("[Packs] firmware gate skipped current=%s required=%s\n", + current_version ? current_version : "", + package.min_firmware_version.c_str()); + return true; + } + + return compare_versions(current_version ? current_version : "", package.min_firmware_version) >= 0; } @@ -1020,13 +1256,22 @@ bool load_installed_index(InstalledIndex& out_index, std::string& out_error) out_index = InstalledIndex{}; out_error.clear(); - if (!logical_file_exists(kInstalledIndexPath)) + const char* index_path = nullptr; + if (logical_file_exists(kInstalledIndexPath)) + { + index_path = kInstalledIndexPath; + } + else if (logical_file_exists(kLegacyInstalledIndexPath)) + { + index_path = kLegacyInstalledIndexPath; + } + else { return true; } std::string text; - if (!read_text_file(kInstalledIndexPath, text)) + if (!read_text_file(index_path, text)) { out_error = "Read installed index failed"; return false; @@ -1293,7 +1538,7 @@ bool extract_zip_payload(const std::string& logical_zip_path, std::string& out_e if (!write_binary_file(logical_target, output.data(), output.size())) { - out_error = "Write extracted payload failed"; + out_error = std::string("Write extracted payload failed: ") + logical_target; file.close(); return false; } @@ -1324,6 +1569,41 @@ void merge_installed_state(const std::vector& installed, } } +bool remove_package_payload(const PackageRecord& package, std::string& out_error) +{ + const struct PayloadGroup + { + const char* dir_name; + const std::vector* ids; + const char* label; + } groups[] = { + {"locales", &package.provided_locale_ids, "locale"}, + {"fonts", &package.provided_font_ids, "font"}, + {"ime", &package.provided_ime_ids, "IME"}, + }; + + for (const PayloadGroup& group : groups) + { + for (const std::string& id : *group.ids) + { + if (id.empty()) + { + continue; + } + + const std::string logical_path = + join_logical_path(join_logical_path(kPackRoot, group.dir_name), id); + if (!remove_dir_recursive_if_exists(logical_path)) + { + out_error = std::string("Remove ") + group.label + " pack failed"; + return false; + } + } + } + + return true; +} + } // namespace bool is_supported() @@ -1540,6 +1820,50 @@ bool install_package(const PackageRecord& package, std::string& out_error) return true; } +bool uninstall_package(const PackageRecord& package, std::string& out_error) +{ + out_error.clear(); + + if (package.id.empty()) + { + out_error = "Package metadata is incomplete"; + return false; + } + if (!platform::ui::device::card_ready()) + { + out_error = "SD card is not ready"; + return false; + } + + InstalledIndex index; + if (!load_installed_index(index, out_error)) + { + return false; + } + + if (!remove_package_payload(package, out_error)) + { + return false; + } + + index.packages.erase( + std::remove_if(index.packages.begin(), + index.packages.end(), + [&](const InstalledPackageRecord& record) + { + return record.id == package.id; + }), + index.packages.end()); + + if (!save_installed_index(index, out_error)) + { + return false; + } + + ::ui::i18n::reload_language(); + return true; +} + } // namespace ui::runtime::packs #else @@ -1573,6 +1897,13 @@ bool install_package(const PackageRecord& package, std::string& out_error) return false; } +bool uninstall_package(const PackageRecord& package, std::string& out_error) +{ + (void)package; + out_error = "Pack installation is unsupported on this platform"; + return false; +} + } // namespace ui::runtime::packs #endif diff --git a/modules/ui_shared/src/ui/screens/chat/chat_compose_components.cpp b/modules/ui_shared/src/ui/screens/chat/chat_compose_components.cpp index a9fafedb..ae152d21 100644 --- a/modules/ui_shared/src/ui/screens/chat/chat_compose_components.cpp +++ b/modules/ui_shared/src/ui/screens/chat/chat_compose_components.cpp @@ -97,7 +97,6 @@ static void set_btn_label_text(lv_obj_t* btn, const char* text) if (child && lv_obj_check_type(child, &lv_label_class)) { ::ui::i18n::set_label_text(child, text); - ::ui::fonts::apply_localized_font(child, lv_label_get_text(child), ::ui::fonts::ui_chrome_font()); } } @@ -117,6 +116,17 @@ static void fit_btn_to_label(lv_obj_t* btn, int pad_lr) } } +static void refresh_textarea_content_font(lv_obj_t* textarea) +{ + if (!textarea) + { + return; + } + + const char* text = lv_textarea_get_text(textarea); + ::ui::fonts::apply_content_font(textarea, text ? text : "", ::ui::fonts::ui_chrome_font()); +} + void ChatComposeScreen::setEnabled(bool enabled) { if (!impl_) return; @@ -285,6 +295,7 @@ ChatComposeScreen::ChatComposeScreen(lv_obj_t* parent, chat::ConversationId conv lv_textarea_set_placeholder_text(impl_->w.textarea, ""); lv_textarea_set_one_line(impl_->w.textarea, false); lv_textarea_set_max_length(impl_->w.textarea, kMaxInputBytes); + refresh_textarea_content_font(impl_->w.textarea); impl_->send_ctx.screen = this; impl_->send_ctx.intent = ActionIntent::Send; @@ -427,6 +438,7 @@ void ChatComposeScreen::clearText() else { lv_textarea_set_text(impl_->w.textarea, ""); + refresh_textarea_content_font(impl_->w.textarea); } refresh_len(); } @@ -567,6 +579,7 @@ void ChatComposeScreen::on_text_changed(lv_event_t* e) { return; } + refresh_textarea_content_font(screen->impl_->w.textarea); screen->refresh_len(); } diff --git a/modules/ui_shared/src/ui/screens/chat/chat_compose_layout.cpp b/modules/ui_shared/src/ui/screens/chat/chat_compose_layout.cpp index 8df62a38..df854ff2 100644 --- a/modules/ui_shared/src/ui/screens/chat/chat_compose_layout.cpp +++ b/modules/ui_shared/src/ui/screens/chat/chat_compose_layout.cpp @@ -50,7 +50,6 @@ static lv_obj_t* create_btn_with_label(lv_obj_t* parent, int w, int h, const cha ::ui::i18n::set_label_text(label, text); lv_obj_set_width(label, LV_PCT(100)); lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0); - ::ui::fonts::apply_localized_font(label, lv_label_get_text(label), ::ui::fonts::ui_chrome_font()); lv_obj_set_style_text_color(label, lv_color_hex(0x3A2A1A), 0); lv_label_set_long_mode(label, LV_LABEL_LONG_CLIP); lv_obj_center(label); @@ -118,7 +117,6 @@ void create(lv_obj_t* parent, const Spec& spec, Widgets& w) w.len_label = lv_label_create(w.action_bar); ::ui::i18n::set_label_text_fmt(w.len_label, "Remain: %u", 233U); - ::ui::fonts::apply_localized_font(w.len_label, lv_label_get_text(w.len_label), ::ui::fonts::ui_chrome_font()); lv_obj_set_style_text_color(w.len_label, lv_color_hex(0x6A5646), 0); } diff --git a/modules/ui_shared/src/ui/screens/chat/chat_compose_styles.cpp b/modules/ui_shared/src/ui/screens/chat/chat_compose_styles.cpp index 2a07388e..d0118ed8 100644 --- a/modules/ui_shared/src/ui/screens/chat/chat_compose_styles.cpp +++ b/modules/ui_shared/src/ui/screens/chat/chat_compose_styles.cpp @@ -36,7 +36,7 @@ void init_once() lv_style_set_bg_color(&s_textarea, lv_color_hex(0xFFF7E9)); lv_style_set_bg_opa(&s_textarea, LV_OPA_COVER); lv_style_set_text_color(&s_textarea, lv_color_hex(0x3A2A1A)); - lv_style_set_text_font(&s_textarea, ::ui::fonts::localized_font(::ui::fonts::ui_chrome_font())); + lv_style_set_text_font(&s_textarea, ::ui::fonts::ui_chrome_font()); lv_style_set_border_width(&s_textarea, 1); lv_style_set_border_color(&s_textarea, lv_color_hex(0xD9B06A)); lv_style_set_radius(&s_textarea, 6); diff --git a/modules/ui_shared/src/ui/screens/extensions/extensions_page_runtime.cpp b/modules/ui_shared/src/ui/screens/extensions/extensions_page_runtime.cpp index 8fd0e2c4..585f4793 100644 --- a/modules/ui_shared/src/ui/screens/extensions/extensions_page_runtime.cpp +++ b/modules/ui_shared/src/ui/screens/extensions/extensions_page_runtime.cpp @@ -1,5 +1,6 @@ #include "ui/screens/extensions/extensions_page_runtime.h" +#include #include #include #include @@ -8,9 +9,11 @@ #include "platform/ui/device_runtime.h" #include "platform/ui/wifi_runtime.h" #include "ui/app_runtime.h" +#include "ui/components/info_card.h" +#include "ui/components/two_pane_layout.h" +#include "ui/components/two_pane_styles.h" #include "ui/localization.h" #include "ui/page/page_profile.h" -#include "ui/runtime/memory_profile.h" #include "ui/runtime/pack_repository.h" #include "ui/ui_theme.h" #include "ui/widgets/system_notification.h" @@ -24,18 +27,42 @@ namespace { using Host = extensions::ui::shell::Host; +namespace info_card = ::ui::components::info_card; +namespace two_pane_layout = ::ui::components::two_pane_layout; +namespace two_pane_styles = ::ui::components::two_pane_styles; +namespace packs = ::ui::runtime::packs; + +constexpr std::size_t kInvalidIndex = static_cast(-1); + +enum class MainView : uint8_t +{ + List = 0, + Detail, +}; struct RuntimeState { const Host* host = nullptr; + lv_group_t* previous_group = nullptr; lv_obj_t* root = nullptr; lv_obj_t* content = nullptr; - lv_obj_t* toolbar = nullptr; + lv_obj_t* filter_panel = nullptr; + lv_obj_t* filter_btn = nullptr; + lv_obj_t* main_panel = nullptr; + lv_obj_t* header_card = nullptr; + lv_obj_t* title_label = nullptr; lv_obj_t* status_label = nullptr; - lv_obj_t* list = nullptr; lv_obj_t* refresh_btn = nullptr; + lv_obj_t* body_panel = nullptr; + lv_obj_t* detail_back_btn = nullptr; + lv_obj_t* primary_action_btn = nullptr; + lv_obj_t* uninstall_btn = nullptr; ::ui::widgets::TopBar top_bar; - std::vector packages; + MainView view = MainView::List; + std::string selected_package_id; + std::vector packages; + std::vector filtered_indices; + std::vector list_buttons; }; RuntimeState s_runtime{}; @@ -89,18 +116,61 @@ std::string format_size(std::size_t bytes) return buffer; } -std::string compatibility_text(const ui::runtime::packs::PackageRecord& package) +std::string join_values(const std::vector& values) +{ + if (values.empty()) + { + return "None"; + } + + std::string joined; + for (std::size_t i = 0; i < values.size(); ++i) + { + if (i > 0) + { + joined += ", "; + } + joined += values[i]; + } + return joined; +} + +bool is_language_package(const packs::PackageRecord& package) +{ + return package.package_type.empty() || package.package_type == "locale-bundle"; +} + +bool can_install_or_update(const packs::PackageRecord& package) +{ + return package.compatible_firmware && package.compatible_memory_profile && + (!package.installed || package.update_available); +} + +const char* primary_action_label(const packs::PackageRecord& package) +{ + if (!package.compatible_firmware || !package.compatible_memory_profile) + { + return "Incompatible"; + } + if (package.update_available) + { + return "Update"; + } + return "Install"; +} + +std::string compatibility_text(const packs::PackageRecord& package) { if (package.compatible_firmware && package.compatible_memory_profile) { - return ::ui::i18n::tr("Compatibility: this device"); + return "Compatible with this device"; } - std::string text = ::ui::i18n::tr("Compatibility: "); + std::string text = "Compatibility: "; bool appended = false; if (!package.compatible_memory_profile) { - text += ::ui::i18n::tr("memory profile mismatch"); + text += "memory profile mismatch"; appended = true; } if (!package.compatible_firmware) @@ -114,8 +184,12 @@ std::string compatibility_text(const ui::runtime::packs::PackageRecord& package) return text; } -std::string state_text(const ui::runtime::packs::PackageRecord& package) +std::string state_text(const packs::PackageRecord& package) { + if (!package.compatible_firmware || !package.compatible_memory_profile) + { + return "Incompatible"; + } if (package.update_available) { return ::ui::i18n::format("Update available: %s", package.version.c_str()); @@ -124,14 +198,14 @@ std::string state_text(const ui::runtime::packs::PackageRecord& package) { return ::ui::i18n::format("Installed: %s", package.installed_record.version.c_str()); } - return ::ui::i18n::tr("Not installed"); + return "Available to install"; } -const char* action_label(const ui::runtime::packs::PackageRecord& package) +std::string state_badge_text(const packs::PackageRecord& package) { if (!package.compatible_firmware || !package.compatible_memory_profile) { - return "Incompatible"; + return "Blocked"; } if (package.update_available) { @@ -141,7 +215,33 @@ const char* action_label(const ui::runtime::packs::PackageRecord& package) { return "Installed"; } - return "Install"; + return "Ready"; +} + +lv_color_t state_color(const packs::PackageRecord& package) +{ + if (!package.compatible_firmware || !package.compatible_memory_profile) + { + return ::ui::theme::error(); + } + if (package.update_available) + { + return ::ui::theme::status_blue(); + } + if (package.installed) + { + return ::ui::theme::status_green(); + } + return lv_color_hex(two_pane_styles::kAccent); +} + +std::string package_counts_text(const packs::PackageRecord& package) +{ + return ::ui::i18n::format("%lu locales %lu fonts %lu IME %s", + static_cast(package.provided_locale_ids.size()), + static_cast(package.provided_font_ids.size()), + static_cast(package.provided_ime_ids.size()), + format_size(package.archive_size_bytes).c_str()); } void update_top_bar_status() @@ -149,15 +249,24 @@ void update_top_bar_status() const platform::ui::wifi::Status wifi = platform::ui::wifi::status(); if (!wifi.supported) { - ::ui::widgets::top_bar_set_right_text(s_runtime.top_bar, ::ui::i18n::tr("No Wi-Fi")); + ::ui::widgets::top_bar_set_right_text(s_runtime.top_bar, "No Wi-Fi"); return; } if (!wifi.connected) { - ::ui::widgets::top_bar_set_right_text(s_runtime.top_bar, ::ui::i18n::tr("Offline")); + ::ui::widgets::top_bar_set_right_text(s_runtime.top_bar, "Offline"); return; } - ::ui::widgets::top_bar_set_right_text(s_runtime.top_bar, ::ui::i18n::tr("Online")); + ::ui::widgets::top_bar_set_right_text(s_runtime.top_bar, "Online"); +} + +void set_header_title(const char* text) +{ + if (s_runtime.title_label == nullptr) + { + return; + } + ::ui::i18n::set_label_text(s_runtime.title_label, text ? text : ""); } void set_status_text(const char* text) @@ -169,159 +278,192 @@ void set_status_text(const char* text) ::ui::i18n::set_content_label_text_raw(s_runtime.status_label, text ? text : ""); } -void clear_list() +void set_status_text(const std::string& text) { - if (s_runtime.list == nullptr) + set_status_text(text.c_str()); +} + +void apply_root_style(lv_obj_t* obj) +{ + if (!obj) { return; } - lv_obj_clean(s_runtime.list); - if (app_g != nullptr && s_runtime.top_bar.back_btn != nullptr) + lv_obj_set_style_bg_color(obj, lv_color_hex(two_pane_styles::kSidePanelBg), 0); + lv_obj_set_style_bg_opa(obj, LV_OPA_COVER, 0); +} + +void apply_list_item_style(lv_obj_t* item) +{ + if (!item) + { + return; + } + if (info_card::use_tdeck_layout()) + { + info_card::apply_item_style(item); + return; + } + two_pane_styles::apply_list_item(item); +} + +void style_detail_card(lv_obj_t* card) +{ + if (!card) + { + return; + } + + lv_obj_set_width(card, LV_PCT(100)); + lv_obj_set_height(card, LV_SIZE_CONTENT); + lv_obj_set_style_bg_color(card, lv_color_hex(two_pane_styles::kSidePanelBg), 0); + lv_obj_set_style_bg_opa(card, LV_OPA_COVER, 0); + lv_obj_set_style_border_width(card, 1, 0); + lv_obj_set_style_border_color(card, lv_color_hex(two_pane_styles::kBorder), 0); + lv_obj_set_style_radius(card, 10, 0); + lv_obj_set_style_pad_all(card, 8, 0); + lv_obj_set_style_pad_row(card, 5, 0); + lv_obj_set_flex_flow(card, LV_FLEX_FLOW_COLUMN); + lv_obj_clear_flag(card, LV_OBJ_FLAG_SCROLLABLE); +} + +lv_obj_t* create_wrapped_label(lv_obj_t* parent, + const std::string& text, + lv_color_t color, + bool use_title_font = false) +{ + lv_obj_t* label = lv_label_create(parent); + lv_obj_set_width(label, LV_PCT(100)); + lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP); + lv_obj_set_style_text_color(label, color, 0); + if (use_title_font) + { + lv_obj_set_style_text_font(label, &lv_font_montserrat_16, 0); + } + ::ui::i18n::set_content_label_text_raw(label, text.c_str()); + return label; +} + +lv_obj_t* create_section_card(lv_obj_t* parent, + const char* title, + const std::string& body, + lv_color_t body_color = lv_color_hex(two_pane_styles::kTextMuted)) +{ + lv_obj_t* card = lv_obj_create(parent); + style_detail_card(card); + + lv_obj_t* title_label = lv_label_create(card); + lv_obj_set_width(title_label, LV_PCT(100)); + lv_label_set_long_mode(title_label, LV_LABEL_LONG_WRAP); + two_pane_styles::apply_label_primary(title_label); + ::ui::i18n::set_label_text(title_label, title ? title : ""); + + lv_obj_t* body_label = lv_label_create(card); + lv_obj_set_width(body_label, LV_PCT(100)); + lv_label_set_long_mode(body_label, LV_LABEL_LONG_WRAP); + lv_obj_set_style_text_color(body_label, body_color, 0); + ::ui::i18n::set_content_label_text_raw(body_label, body.c_str()); + return card; +} + +void clear_body() +{ + s_runtime.detail_back_btn = nullptr; + s_runtime.primary_action_btn = nullptr; + s_runtime.uninstall_btn = nullptr; + s_runtime.list_buttons.clear(); + + if (s_runtime.body_panel != nullptr) + { + lv_obj_clean(s_runtime.body_panel); + } +} + +void sync_focus_group(lv_obj_t* preferred_focus = nullptr) +{ + if (app_g == nullptr) + { + return; + } + + lv_group_remove_all_objs(app_g); + + if (s_runtime.top_bar.back_btn != nullptr) { - lv_group_remove_all_objs(app_g); lv_group_add_obj(app_g, s_runtime.top_bar.back_btn); - if (s_runtime.refresh_btn != nullptr) + } + if (s_runtime.filter_btn != nullptr) + { + lv_group_add_obj(app_g, s_runtime.filter_btn); + } + if (s_runtime.refresh_btn != nullptr) + { + lv_group_add_obj(app_g, s_runtime.refresh_btn); + } + if (s_runtime.detail_back_btn != nullptr) + { + lv_group_add_obj(app_g, s_runtime.detail_back_btn); + } + for (lv_obj_t* btn : s_runtime.list_buttons) + { + if (btn != nullptr) { - lv_group_add_obj(app_g, s_runtime.refresh_btn); + lv_group_add_obj(app_g, btn); + } + } + if (s_runtime.primary_action_btn != nullptr) + { + lv_group_add_obj(app_g, s_runtime.primary_action_btn); + } + if (s_runtime.uninstall_btn != nullptr) + { + lv_group_add_obj(app_g, s_runtime.uninstall_btn); + } + + if (preferred_focus != nullptr && lv_obj_is_valid(preferred_focus)) + { + lv_group_focus_obj(preferred_focus); + } + else if (s_runtime.filter_btn != nullptr) + { + lv_group_focus_obj(s_runtime.filter_btn); + } + else if (s_runtime.top_bar.back_btn != nullptr) + { + lv_group_focus_obj(s_runtime.top_bar.back_btn); + } + + set_default_group(app_g); + lv_group_set_editing(app_g, false); +} + +void rebuild_filtered_indices() +{ + s_runtime.filtered_indices.clear(); + for (std::size_t i = 0; i < s_runtime.packages.size(); ++i) + { + if (is_language_package(s_runtime.packages[i])) + { + s_runtime.filtered_indices.push_back(i); } } } -void show_empty_message(const char* text) +std::size_t find_package_index(const std::string& id) { - clear_list(); - if (s_runtime.list == nullptr) + if (id.empty()) { - return; + return kInvalidIndex; } - lv_obj_t* label = lv_label_create(s_runtime.list); - lv_obj_set_width(label, LV_PCT(100)); - lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP); - lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0); - lv_obj_set_style_text_color(label, ui::theme::text_muted(), 0); - ::ui::i18n::set_content_label_text_raw(label, text ? text : ""); -} - -void rebuild_list(); - -void on_install_clicked(lv_event_t* event) -{ - const uintptr_t raw_index = reinterpret_cast(lv_event_get_user_data(event)); - if (raw_index == 0U) + for (std::size_t i = 0; i < s_runtime.packages.size(); ++i) { - return; - } - - const std::size_t index = static_cast(raw_index - 1U); - if (index >= s_runtime.packages.size()) - { - return; - } - - std::string error; - set_status_text(::ui::i18n::tr("Installing package...")); - if (!ui::runtime::packs::install_package(s_runtime.packages[index], error)) - { - set_status_text(error.c_str()); - ::ui::SystemNotification::show(error.c_str(), 3000); - return; - } - - ::ui::SystemNotification::show(::ui::i18n::tr("Package installed"), 2000); - rebuild_list(); -} - -void create_package_card(const ui::runtime::packs::PackageRecord& package, std::size_t index) -{ - lv_obj_t* card = lv_obj_create(s_runtime.list); - lv_obj_set_width(card, LV_PCT(100)); - lv_obj_set_style_bg_color(card, ui::theme::surface(), 0); - lv_obj_set_style_bg_opa(card, LV_OPA_COVER, 0); - lv_obj_set_style_border_width(card, 1, 0); - lv_obj_set_style_border_color(card, ui::theme::border(), 0); - lv_obj_set_style_radius(card, 14, 0); - lv_obj_set_style_pad_all(card, 10, 0); - lv_obj_set_style_pad_row(card, 6, 0); - lv_obj_set_flex_flow(card, LV_FLEX_FLOW_COLUMN); - lv_obj_clear_flag(card, LV_OBJ_FLAG_SCROLLABLE); - - lv_obj_t* title_row = lv_obj_create(card); - lv_obj_set_width(title_row, LV_PCT(100)); - lv_obj_set_style_bg_opa(title_row, LV_OPA_TRANSP, 0); - lv_obj_set_style_border_width(title_row, 0, 0); - lv_obj_set_style_pad_all(title_row, 0, 0); - lv_obj_set_style_pad_column(title_row, 8, 0); - lv_obj_set_flex_flow(title_row, LV_FLEX_FLOW_ROW); - lv_obj_set_flex_align(title_row, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); - lv_obj_clear_flag(title_row, LV_OBJ_FLAG_SCROLLABLE); - - lv_obj_t* title = lv_label_create(title_row); - lv_obj_set_flex_grow(title, 1); - lv_obj_set_width(title, LV_PCT(100)); - lv_label_set_long_mode(title, LV_LABEL_LONG_WRAP); - lv_obj_set_style_text_color(title, ui::theme::text(), 0); - lv_obj_set_style_text_font(title, &lv_font_montserrat_16, 0); - const std::string title_text = ::ui::i18n::format("%s %s", - package.display_name.c_str(), - package.version.c_str()); - ::ui::i18n::set_content_label_text_raw(title, title_text.c_str()); - - lv_obj_t* action_btn = lv_btn_create(title_row); - lv_obj_set_size(action_btn, 96, ::ui::page_profile::resolve_control_button_height()); - lv_obj_add_event_cb(action_btn, - on_install_clicked, - LV_EVENT_CLICKED, - reinterpret_cast(static_cast(index + 1U))); - lv_obj_add_event_cb(action_btn, on_focus_scroll, LV_EVENT_FOCUSED, nullptr); - if ((!package.compatible_firmware || !package.compatible_memory_profile) || - (package.installed && !package.update_available)) - { - lv_obj_add_state(action_btn, LV_STATE_DISABLED); - } - lv_obj_t* action_label_obj = lv_label_create(action_btn); - ::ui::i18n::set_label_text(action_label_obj, action_label(package)); - lv_obj_center(action_label_obj); - - lv_obj_t* summary = lv_label_create(card); - lv_obj_set_width(summary, LV_PCT(100)); - lv_label_set_long_mode(summary, LV_LABEL_LONG_WRAP); - lv_obj_set_style_text_color(summary, ui::theme::text_muted(), 0); - ::ui::i18n::set_content_label_text_raw(summary, package.summary.c_str()); - - lv_obj_t* meta = lv_label_create(card); - lv_obj_set_width(meta, LV_PCT(100)); - lv_label_set_long_mode(meta, LV_LABEL_LONG_WRAP); - lv_obj_set_style_text_color(meta, ui::theme::text_muted(), 0); - const std::string meta_text = - ::ui::i18n::format("Size: %s", format_size(package.archive_size_bytes).c_str()); - ::ui::i18n::set_content_label_text_raw(meta, meta_text.c_str()); - - lv_obj_t* compat = lv_label_create(card); - lv_obj_set_width(compat, LV_PCT(100)); - lv_label_set_long_mode(compat, LV_LABEL_LONG_WRAP); - lv_obj_set_style_text_color(compat, - (package.compatible_firmware && package.compatible_memory_profile) - ? ui::theme::text_muted() - : ui::theme::error(), - 0); - const std::string compat_text = compatibility_text(package); - ::ui::i18n::set_content_label_text_raw(compat, compat_text.c_str()); - - lv_obj_t* state = lv_label_create(card); - lv_obj_set_width(state, LV_PCT(100)); - lv_label_set_long_mode(state, LV_LABEL_LONG_WRAP); - lv_obj_set_style_text_color(state, - package.update_available ? ui::theme::status_blue() - : ui::theme::status_green(), - 0); - const std::string state_value = state_text(package); - ::ui::i18n::set_content_label_text_raw(state, state_value.c_str()); - - if (app_g != nullptr) - { - lv_group_add_obj(app_g, action_btn); + if (s_runtime.packages[i].id == id) + { + return i; + } } + return kInvalidIndex; } bool load_catalog(std::string& out_error) @@ -335,53 +477,466 @@ bool load_catalog(std::string& out_error) return false; } - if (!ui::runtime::packs::fetch_catalog(s_runtime.packages, out_error)) - { - return false; - } - return true; + return packs::fetch_catalog(s_runtime.packages, out_error); } -void rebuild_list() +void show_list_view(); +void refresh_catalog_and_render(); + +void on_filter_clicked(lv_event_t* event) +{ + (void)event; + lv_obj_add_state(s_runtime.filter_btn, LV_STATE_CHECKED); + show_list_view(); +} + +void on_refresh_clicked(lv_event_t* event) +{ + (void)event; + refresh_catalog_and_render(); +} + +void on_package_clicked(lv_event_t* event) +{ + const uintptr_t raw_index = reinterpret_cast(lv_event_get_user_data(event)); + if (raw_index == 0U) + { + return; + } + + const std::size_t package_index = static_cast(raw_index - 1U); + if (package_index >= s_runtime.packages.size()) + { + return; + } + + s_runtime.selected_package_id = s_runtime.packages[package_index].id; + s_runtime.view = MainView::Detail; + refresh_catalog_and_render(); +} + +void on_detail_back_clicked(lv_event_t* event) +{ + (void)event; + show_list_view(); +} + +void on_primary_action_clicked(lv_event_t* event) +{ + const uintptr_t raw_index = reinterpret_cast(lv_event_get_user_data(event)); + if (raw_index == 0U) + { + return; + } + + const std::size_t package_index = static_cast(raw_index - 1U); + if (package_index >= s_runtime.packages.size()) + { + return; + } + + const packs::PackageRecord& package = s_runtime.packages[package_index]; + std::string error; + set_status_text("Installing package..."); + if (!packs::install_package(package, error)) + { + set_status_text(error); + ::ui::SystemNotification::show(error.c_str(), 3000); + return; + } + + ::ui::SystemNotification::show("Package installed", 2000); + s_runtime.selected_package_id = package.id; + s_runtime.view = MainView::Detail; + refresh_catalog_and_render(); +} + +void on_uninstall_clicked(lv_event_t* event) +{ + const uintptr_t raw_index = reinterpret_cast(lv_event_get_user_data(event)); + if (raw_index == 0U) + { + return; + } + + const std::size_t package_index = static_cast(raw_index - 1U); + if (package_index >= s_runtime.packages.size()) + { + return; + } + + const packs::PackageRecord& package = s_runtime.packages[package_index]; + std::string error; + set_status_text("Uninstalling package..."); + if (!packs::uninstall_package(package, error)) + { + set_status_text(error); + ::ui::SystemNotification::show(error.c_str(), 3000); + return; + } + + ::ui::SystemNotification::show("Package uninstalled", 2000); + s_runtime.selected_package_id = package.id; + s_runtime.view = MainView::Detail; + refresh_catalog_and_render(); +} + +lv_obj_t* create_action_button(lv_obj_t* parent, + const char* label, + lv_event_cb_t handler, + void* user_data, + bool enabled) +{ + lv_obj_t* button = lv_btn_create(parent); + lv_obj_set_width(button, LV_PCT(100)); + lv_obj_set_height(button, ::ui::page_profile::resolve_control_button_height()); + two_pane_layout::make_non_scrollable(button); + two_pane_styles::apply_btn_basic(button); + lv_obj_add_event_cb(button, handler, LV_EVENT_CLICKED, user_data); + lv_obj_add_event_cb(button, on_focus_scroll, LV_EVENT_FOCUSED, nullptr); + if (!enabled) + { + lv_obj_add_state(button, LV_STATE_DISABLED); + } + + lv_obj_t* text = lv_label_create(button); + ::ui::i18n::set_label_text(text, label ? label : ""); + lv_obj_center(text); + return button; +} + +void show_message_body(const char* text) +{ + clear_body(); + set_header_title("Language Packs"); + + lv_obj_t* card = lv_obj_create(s_runtime.body_panel); + style_detail_card(card); + + lv_obj_t* label = lv_label_create(card); + lv_obj_set_width(label, LV_PCT(100)); + lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP); + lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0); + lv_obj_set_style_text_color(label, lv_color_hex(two_pane_styles::kTextMuted), 0); + ::ui::i18n::set_content_label_text_raw(label, text ? text : ""); +} + +void create_package_list_item(const packs::PackageRecord& package, std::size_t package_index) +{ + const auto& profile = ::ui::page_profile::current(); + + lv_obj_t* item = lv_btn_create(s_runtime.body_panel); + lv_obj_set_width(item, LV_PCT(100)); + lv_obj_add_event_cb(item, + on_package_clicked, + LV_EVENT_CLICKED, + reinterpret_cast(static_cast(package_index + 1U))); + lv_obj_add_event_cb(item, on_focus_scroll, LV_EVENT_FOCUSED, nullptr); + apply_list_item_style(item); + + if (info_card::use_tdeck_layout()) + { + info_card::configure_item(item, profile.list_item_height); + info_card::ContentOptions options{}; + options.header_meta = true; + options.body_meta = true; + const auto slots = info_card::create_content(item, options); + + ::ui::i18n::set_content_label_text_raw(slots.header_main_label, package.display_name.c_str()); + two_pane_styles::apply_label_primary(slots.header_main_label); + + ::ui::i18n::set_content_label_text_raw(slots.header_meta_label, state_badge_text(package).c_str()); + two_pane_styles::apply_label_primary(slots.header_meta_label); + + ::ui::i18n::set_content_label_text_raw(slots.body_main_label, package.summary.c_str()); + two_pane_styles::apply_label_muted(slots.body_main_label); + + const std::string detail = package_counts_text(package); + ::ui::i18n::set_content_label_text_raw(slots.body_meta_label, detail.c_str()); + lv_obj_set_style_text_color(slots.body_meta_label, state_color(package), 0); + } + else + { + lv_obj_set_height(item, LV_SIZE_CONTENT); + lv_obj_set_style_pad_all(item, 8, 0); + lv_obj_set_style_pad_row(item, 4, 0); + lv_obj_set_flex_flow(item, LV_FLEX_FLOW_COLUMN); + lv_obj_clear_flag(item, LV_OBJ_FLAG_SCROLLABLE); + + create_wrapped_label(item, + package.display_name, + lv_color_hex(two_pane_styles::kTextPrimary), + true); + create_wrapped_label(item, state_badge_text(package), state_color(package)); + create_wrapped_label(item, + package.summary, + lv_color_hex(two_pane_styles::kTextMuted)); + + const std::string detail = package_counts_text(package); + create_wrapped_label(item, + detail, + (!package.compatible_firmware || !package.compatible_memory_profile) + ? ::ui::theme::error() + : lv_color_hex(two_pane_styles::kTextMuted)); + } + + s_runtime.list_buttons.push_back(item); +} + +void render_list_view() +{ + clear_body(); + set_header_title("Language Packs"); + + if (s_runtime.filtered_indices.empty()) + { + set_status_text("No language packs available"); + show_message_body("No language packs available"); + sync_focus_group(s_runtime.filter_btn); + return; + } + + set_status_text(::ui::i18n::format("Available language packs: %lu", + static_cast(s_runtime.filtered_indices.size()))); + + for (std::size_t index : s_runtime.filtered_indices) + { + create_package_list_item(s_runtime.packages[index], index); + } + + sync_focus_group(!s_runtime.list_buttons.empty() ? s_runtime.list_buttons.front() : s_runtime.filter_btn); +} + +void render_detail_view(std::size_t package_index) +{ + if (package_index >= s_runtime.packages.size()) + { + show_list_view(); + return; + } + + const packs::PackageRecord& package = s_runtime.packages[package_index]; + clear_body(); + set_header_title("Package Details"); + set_status_text(state_text(package)); + + lv_obj_t* hero = lv_obj_create(s_runtime.body_panel); + style_detail_card(hero); + create_wrapped_label(hero, + ::ui::i18n::format("%s %s", + package.display_name.c_str(), + package.version.c_str()), + lv_color_hex(two_pane_styles::kTextPrimary), + true); + create_wrapped_label(hero, state_text(package), state_color(package)); + create_wrapped_label(hero, package.summary, lv_color_hex(two_pane_styles::kTextMuted)); + + lv_obj_t* actions = lv_obj_create(s_runtime.body_panel); + style_detail_card(actions); + s_runtime.detail_back_btn = + create_action_button(actions, "Back to list", on_detail_back_clicked, nullptr, true); + + if (can_install_or_update(package) || !package.compatible_firmware || + !package.compatible_memory_profile) + { + s_runtime.primary_action_btn = + create_action_button(actions, + primary_action_label(package), + on_primary_action_clicked, + reinterpret_cast(static_cast(package_index + 1U)), + can_install_or_update(package)); + } + + if (package.installed) + { + s_runtime.uninstall_btn = + create_action_button(actions, + "Uninstall", + on_uninstall_clicked, + reinterpret_cast(static_cast(package_index + 1U)), + true); + } + + if (!package.description.empty()) + { + create_section_card(s_runtime.body_panel, + "About", + package.description, + lv_color_hex(two_pane_styles::kTextMuted)); + } + + std::string details = ::ui::i18n::format("Archive: %s\nExtra font RAM: %s\nProfiles: %s\n%s", + format_size(package.archive_size_bytes).c_str(), + format_size(package.estimated_unique_font_ram_bytes).c_str(), + join_values(package.supported_memory_profiles).c_str(), + compatibility_text(package).c_str()); + create_section_card(s_runtime.body_panel, + "Package Info", + details, + package.compatible_firmware && package.compatible_memory_profile + ? lv_color_hex(two_pane_styles::kTextMuted) + : ::ui::theme::error()); + + std::string contents = ::ui::i18n::format("Locales: %s\nFonts: %s\nIME: %s", + join_values(package.provided_locale_ids).c_str(), + join_values(package.provided_font_ids).c_str(), + join_values(package.provided_ime_ids).c_str()); + create_section_card(s_runtime.body_panel, "Contents", contents); + + std::string source = ::ui::i18n::format("Author: %s\nHomepage: %s", + package.author.empty() ? "Unknown" : package.author.c_str(), + package.homepage.empty() ? "-" : package.homepage.c_str()); + create_section_card(s_runtime.body_panel, "Source", source); + + lv_obj_t* preferred = s_runtime.primary_action_btn ? s_runtime.primary_action_btn + : (s_runtime.uninstall_btn ? s_runtime.uninstall_btn + : s_runtime.detail_back_btn); + sync_focus_group(preferred); +} + +void render_current_view() +{ + update_top_bar_status(); + rebuild_filtered_indices(); + + if (s_runtime.filtered_indices.empty()) + { + s_runtime.view = MainView::List; + render_list_view(); + return; + } + + if (s_runtime.view == MainView::Detail) + { + const std::size_t selected_index = find_package_index(s_runtime.selected_package_id); + if (selected_index != kInvalidIndex && is_language_package(s_runtime.packages[selected_index])) + { + render_detail_view(selected_index); + return; + } + + s_runtime.view = MainView::List; + s_runtime.selected_package_id.clear(); + } + + render_list_view(); +} + +void refresh_catalog_and_render() { update_top_bar_status(); std::string error; if (!load_catalog(error)) { - set_status_text(error.c_str()); - show_empty_message(error.c_str()); + set_status_text(error); + show_message_body(error.c_str()); + sync_focus_group(s_runtime.refresh_btn ? s_runtime.refresh_btn : s_runtime.filter_btn); return; } - if (s_runtime.packages.empty()) - { - set_status_text(::ui::i18n::tr("No packages available")); - show_empty_message(::ui::i18n::tr("No packages available")); - return; - } - - set_status_text(::ui::i18n::format("Available packages: %lu", - static_cast(s_runtime.packages.size())) - .c_str()); - clear_list(); - for (std::size_t i = 0; i < s_runtime.packages.size(); ++i) - { - create_package_card(s_runtime.packages[i], i); - } - - if (app_g != nullptr && s_runtime.top_bar.back_btn != nullptr) - { - lv_group_focus_obj(s_runtime.top_bar.back_btn); - set_default_group(app_g); - lv_group_set_editing(app_g, false); - } + render_current_view(); } -void on_refresh_clicked(lv_event_t* event) +void show_list_view() { - (void)event; - rebuild_list(); + s_runtime.view = MainView::List; + render_current_view(); +} + +void create_filter_panel(lv_obj_t* parent) +{ + const auto& profile = ::ui::page_profile::current(); + two_pane_layout::SidePanelSpec panel_spec{}; + panel_spec.width = profile.filter_panel_width; + panel_spec.pad_row = profile.filter_panel_pad_row; + panel_spec.margin_right = 0; + + s_runtime.filter_panel = two_pane_layout::create_side_panel(parent, panel_spec); + two_pane_styles::apply_panel_side(s_runtime.filter_panel); + + s_runtime.filter_btn = lv_btn_create(s_runtime.filter_panel); + lv_obj_set_size(s_runtime.filter_btn, LV_PCT(100), profile.filter_button_height); + lv_obj_add_flag(s_runtime.filter_btn, LV_OBJ_FLAG_CHECKABLE); + lv_obj_add_state(s_runtime.filter_btn, LV_STATE_CHECKED); + two_pane_layout::make_non_scrollable(s_runtime.filter_btn); + two_pane_styles::apply_btn_filter(s_runtime.filter_btn); + lv_obj_add_event_cb(s_runtime.filter_btn, on_filter_clicked, LV_EVENT_CLICKED, nullptr); + lv_obj_add_event_cb(s_runtime.filter_btn, on_focus_scroll, LV_EVENT_FOCUSED, nullptr); + + lv_obj_t* label = lv_label_create(s_runtime.filter_btn); + ::ui::i18n::set_label_text(label, "Language"); + two_pane_styles::apply_label_primary(label); + lv_obj_center(label); +} + +void create_main_panel(lv_obj_t* parent) +{ + const auto& profile = ::ui::page_profile::current(); + + two_pane_layout::MainPanelSpec panel_spec{}; + panel_spec.pad_all = 0; + panel_spec.pad_row = profile.list_panel_pad_row; + panel_spec.pad_left = profile.list_panel_pad_left; + panel_spec.pad_right = profile.list_panel_pad_right; + panel_spec.pad_bottom = profile.list_panel_margin_bottom; + panel_spec.scrollbar_mode = LV_SCROLLBAR_MODE_OFF; + + s_runtime.main_panel = two_pane_layout::create_main_panel(parent, panel_spec); + two_pane_styles::apply_panel_main(s_runtime.main_panel); + + s_runtime.header_card = lv_obj_create(s_runtime.main_panel); + style_detail_card(s_runtime.header_card); + lv_obj_set_style_pad_row(s_runtime.header_card, 4, 0); + + lv_obj_t* header_row = lv_obj_create(s_runtime.header_card); + lv_obj_set_size(header_row, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_style_bg_opa(header_row, LV_OPA_TRANSP, 0); + lv_obj_set_style_border_width(header_row, 0, 0); + lv_obj_set_style_pad_all(header_row, 0, 0); + lv_obj_set_style_pad_column(header_row, 8, 0); + lv_obj_set_flex_flow(header_row, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(header_row, + LV_FLEX_ALIGN_SPACE_BETWEEN, + LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER); + two_pane_layout::make_non_scrollable(header_row); + + s_runtime.title_label = lv_label_create(header_row); + lv_obj_set_width(s_runtime.title_label, 0); + lv_obj_set_flex_grow(s_runtime.title_label, 1); + lv_label_set_long_mode(s_runtime.title_label, LV_LABEL_LONG_WRAP); + two_pane_styles::apply_label_primary(s_runtime.title_label); + lv_obj_set_style_text_font(s_runtime.title_label, &lv_font_montserrat_16, 0); + ::ui::i18n::set_label_text(s_runtime.title_label, "Language Packs"); + + s_runtime.refresh_btn = lv_btn_create(header_row); + lv_obj_set_width(s_runtime.refresh_btn, ::ui::page_profile::resolve_control_button_min_width()); + lv_obj_set_height(s_runtime.refresh_btn, ::ui::page_profile::resolve_control_button_height()); + two_pane_layout::make_non_scrollable(s_runtime.refresh_btn); + two_pane_styles::apply_btn_basic(s_runtime.refresh_btn); + lv_obj_add_event_cb(s_runtime.refresh_btn, on_refresh_clicked, LV_EVENT_CLICKED, nullptr); + lv_obj_add_event_cb(s_runtime.refresh_btn, on_focus_scroll, LV_EVENT_FOCUSED, nullptr); + lv_obj_t* refresh_label = lv_label_create(s_runtime.refresh_btn); + ::ui::i18n::set_label_text(refresh_label, "Refresh"); + lv_obj_center(refresh_label); + + s_runtime.status_label = lv_label_create(s_runtime.header_card); + lv_obj_set_width(s_runtime.status_label, LV_PCT(100)); + lv_label_set_long_mode(s_runtime.status_label, LV_LABEL_LONG_WRAP); + two_pane_styles::apply_label_muted(s_runtime.status_label); + ::ui::i18n::set_label_text(s_runtime.status_label, "Loading..."); + + s_runtime.body_panel = lv_obj_create(s_runtime.main_panel); + lv_obj_set_width(s_runtime.body_panel, LV_PCT(100)); + lv_obj_set_height(s_runtime.body_panel, 0); + lv_obj_set_flex_grow(s_runtime.body_panel, 1); + lv_obj_set_style_bg_opa(s_runtime.body_panel, LV_OPA_TRANSP, 0); + lv_obj_set_style_border_width(s_runtime.body_panel, 0, 0); + lv_obj_set_style_pad_all(s_runtime.body_panel, 0, 0); + lv_obj_set_style_pad_row(s_runtime.body_panel, profile.list_panel_pad_row, 0); + lv_obj_set_flex_flow(s_runtime.body_panel, LV_FLEX_FLOW_COLUMN); + lv_obj_set_scrollbar_mode(s_runtime.body_panel, LV_SCROLLBAR_MODE_AUTO); } } // namespace @@ -396,89 +951,36 @@ bool is_available() void enter(const shell::Host* host, lv_obj_t* parent) { + s_runtime = RuntimeState{}; s_runtime.host = host; - - lv_group_t* previous_group = lv_group_get_default(); + s_runtime.previous_group = lv_group_get_default(); set_default_group(nullptr); - s_runtime.root = lv_obj_create(parent); - lv_obj_set_size(s_runtime.root, LV_PCT(100), LV_PCT(100)); - lv_obj_set_style_bg_color(s_runtime.root, ::ui::theme::page_bg(), 0); - lv_obj_set_style_bg_opa(s_runtime.root, LV_OPA_COVER, 0); - lv_obj_set_style_border_width(s_runtime.root, 0, 0); - lv_obj_set_style_radius(s_runtime.root, 0, 0); - lv_obj_set_style_pad_all(s_runtime.root, 0, 0); - lv_obj_set_style_pad_row(s_runtime.root, 0, 0); - lv_obj_set_flex_flow(s_runtime.root, LV_FLEX_FLOW_COLUMN); - lv_obj_clear_flag(s_runtime.root, LV_OBJ_FLAG_SCROLLABLE); + const auto& profile = ::ui::page_profile::current(); + two_pane_layout::RootSpec root_spec{}; + root_spec.pad_row = profile.top_content_gap; + s_runtime.root = two_pane_layout::create_root(parent, root_spec); + apply_root_style(s_runtime.root); ::ui::widgets::top_bar_init(s_runtime.top_bar, s_runtime.root); - ::ui::widgets::top_bar_set_title(s_runtime.top_bar, ::ui::i18n::tr("Extensions")); + ::ui::widgets::top_bar_set_title(s_runtime.top_bar, "Extensions"); ::ui::widgets::top_bar_set_back_callback(s_runtime.top_bar, on_back, nullptr); - s_runtime.content = lv_obj_create(s_runtime.root); - lv_obj_set_width(s_runtime.content, LV_PCT(100)); - lv_obj_set_flex_grow(s_runtime.content, 1); - lv_obj_set_style_bg_opa(s_runtime.content, LV_OPA_TRANSP, 0); - lv_obj_set_style_border_width(s_runtime.content, 0, 0); - lv_obj_set_style_pad_all(s_runtime.content, 10, 0); - lv_obj_set_style_pad_row(s_runtime.content, 8, 0); - lv_obj_set_flex_flow(s_runtime.content, LV_FLEX_FLOW_COLUMN); - lv_obj_clear_flag(s_runtime.content, LV_OBJ_FLAG_SCROLLABLE); + two_pane_layout::ContentSpec content_spec{}; + content_spec.pad_left = profile.content_pad_left; + content_spec.pad_right = profile.content_pad_right; + content_spec.pad_top = profile.content_pad_top; + content_spec.pad_bottom = profile.content_pad_bottom; + s_runtime.content = two_pane_layout::create_content_row(s_runtime.root, content_spec); - s_runtime.toolbar = lv_obj_create(s_runtime.content); - lv_obj_set_width(s_runtime.toolbar, LV_PCT(100)); - lv_obj_set_style_bg_color(s_runtime.toolbar, ::ui::theme::surface(), 0); - lv_obj_set_style_bg_opa(s_runtime.toolbar, LV_OPA_COVER, 0); - lv_obj_set_style_border_width(s_runtime.toolbar, 1, 0); - lv_obj_set_style_border_color(s_runtime.toolbar, ::ui::theme::border(), 0); - lv_obj_set_style_radius(s_runtime.toolbar, 12, 0); - lv_obj_set_style_pad_all(s_runtime.toolbar, 8, 0); - lv_obj_set_style_pad_column(s_runtime.toolbar, 8, 0); - lv_obj_set_flex_flow(s_runtime.toolbar, LV_FLEX_FLOW_ROW); - lv_obj_set_flex_align(s_runtime.toolbar, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); - lv_obj_clear_flag(s_runtime.toolbar, LV_OBJ_FLAG_SCROLLABLE); + create_filter_panel(s_runtime.content); + create_main_panel(s_runtime.content); + refresh_catalog_and_render(); - s_runtime.status_label = lv_label_create(s_runtime.toolbar); - lv_obj_set_flex_grow(s_runtime.status_label, 1); - lv_obj_set_width(s_runtime.status_label, LV_PCT(100)); - lv_label_set_long_mode(s_runtime.status_label, LV_LABEL_LONG_WRAP); - lv_obj_set_style_text_color(s_runtime.status_label, ::ui::theme::text_muted(), 0); - ::ui::i18n::set_label_text(s_runtime.status_label, "Loading..."); - - s_runtime.refresh_btn = lv_btn_create(s_runtime.toolbar); - lv_obj_set_size(s_runtime.refresh_btn, 90, ::ui::page_profile::resolve_control_button_height()); - lv_obj_add_event_cb(s_runtime.refresh_btn, on_refresh_clicked, LV_EVENT_CLICKED, nullptr); - lv_obj_add_event_cb(s_runtime.refresh_btn, on_focus_scroll, LV_EVENT_FOCUSED, nullptr); - lv_obj_t* refresh_label = lv_label_create(s_runtime.refresh_btn); - ::ui::i18n::set_label_text(refresh_label, "Refresh"); - lv_obj_center(refresh_label); - - s_runtime.list = lv_obj_create(s_runtime.content); - lv_obj_set_width(s_runtime.list, LV_PCT(100)); - lv_obj_set_flex_grow(s_runtime.list, 1); - lv_obj_set_style_bg_opa(s_runtime.list, LV_OPA_TRANSP, 0); - lv_obj_set_style_border_width(s_runtime.list, 0, 0); - lv_obj_set_style_pad_all(s_runtime.list, 0, 0); - lv_obj_set_style_pad_row(s_runtime.list, 8, 0); - lv_obj_set_flex_flow(s_runtime.list, LV_FLEX_FLOW_COLUMN); - lv_obj_set_scrollbar_mode(s_runtime.list, LV_SCROLLBAR_MODE_AUTO); - - if (app_g != nullptr && s_runtime.top_bar.back_btn != nullptr) + if (app_g == nullptr && s_runtime.previous_group != nullptr) { - lv_group_remove_all_objs(app_g); - lv_group_add_obj(app_g, s_runtime.top_bar.back_btn); - lv_group_add_obj(app_g, s_runtime.refresh_btn); - lv_group_focus_obj(s_runtime.top_bar.back_btn); - set_default_group(app_g); - lv_group_set_editing(app_g, false); + set_default_group(s_runtime.previous_group); } - else - { - set_default_group(previous_group); - } - - rebuild_list(); } void exit(lv_obj_t* parent) @@ -488,6 +990,10 @@ void exit(lv_obj_t* parent) { lv_obj_del(s_runtime.root); } + if (s_runtime.previous_group != nullptr) + { + set_default_group(s_runtime.previous_group); + } s_runtime = RuntimeState{}; } diff --git a/modules/ui_shared/src/ui/screens/settings/settings_page_components.cpp b/modules/ui_shared/src/ui/screens/settings/settings_page_components.cpp index 219d8799..a7f46c3a 100644 --- a/modules/ui_shared/src/ui/screens/settings/settings_page_components.cpp +++ b/modules/ui_shared/src/ui/screens/settings/settings_page_components.cpp @@ -24,6 +24,7 @@ #include "platform/ui/tracker_runtime.h" #include "platform/ui/wifi_runtime.h" #include "ui/app_runtime.h" +#include "ui/assets/fonts/font_utils.h" #include "ui/components/info_card.h" #include "ui/localization.h" #include "ui/menu/menu_layout.h" @@ -97,6 +98,7 @@ static void update_item_value(settings::ui::ItemWidget& widget); static void open_factory_reset_modal(); static bool option_labels_are_translated(const settings::ui::SettingItem& item); static bool option_labels_use_content_font(const settings::ui::SettingItem& item); +static void apply_locale_preview_font(lv_obj_t* label, const settings::ui::SettingItem& item, int value); static void copy_bounded(char* out, size_t out_len, const char* text) { @@ -948,6 +950,11 @@ static void update_item_value(settings::ui::ItemWidget& widget) { ::ui::i18n::set_label_text_raw(widget.value_label, value); } + + if (widget.def->enum_value) + { + apply_locale_preview_font(widget.value_label, *widget.def, *widget.def->enum_value); + } } static void modal_prepare_group() @@ -1875,6 +1882,7 @@ static void open_option_modal(const settings::ui::SettingItem& item, settings::u } style::apply_label_primary(label); lv_obj_center(label); + apply_locale_preview_font(label, item, item.options[i].value); s_option_clicks[s_option_click_count] = {&item, item.options[i].value, &widget}; lv_obj_add_event_cb(btn, on_option_clicked, LV_EVENT_CLICKED, @@ -2348,6 +2356,37 @@ static bool option_labels_use_content_font(const settings::ui::SettingItem& item has_pref_key(item, "wifi_network"); } +static const ::ui::i18n::LocaleInfo* locale_info_for_option_value(const settings::ui::SettingItem& item, int value) +{ + if (!has_pref_key(item, "display_locale") || value < 0) + { + return nullptr; + } + + return ::ui::i18n::locale_at(static_cast(value)); +} + +static void apply_locale_preview_font(lv_obj_t* label, const settings::ui::SettingItem& item, int value) +{ + if (!label) + { + return; + } + + const ::ui::i18n::LocaleInfo* locale = locale_info_for_option_value(item, value); + if (!locale || !locale->id) + { + return; + } + + const lv_font_t* preview_font = + ::ui::i18n::locale_preview_font(locale->id, ::ui::fonts::ui_chrome_font()); + if (preview_font) + { + lv_obj_set_style_text_font(label, preview_font, 0); + } +} + static bool should_show_item(const settings::ui::SettingItem& item) { if (!item.pref_key) diff --git a/modules/ui_shared/src/ui/startup_shell.cpp b/modules/ui_shared/src/ui/startup_shell.cpp index 7292fe8f..7a5574ce 100644 --- a/modules/ui_shared/src/ui/startup_shell.cpp +++ b/modules/ui_shared/src/ui/startup_shell.cpp @@ -2,6 +2,7 @@ #include +#include "lvgl.h" #include "platform/ui/screen_runtime.h" #include "platform/ui/time_runtime.h" #include "ui/app_runtime.h" @@ -16,6 +17,16 @@ namespace ui::startup_shell { +namespace +{ + +void present_boot_overlay_now() +{ + lv_timer_handler(); + lv_refr_now(nullptr); +} + +} // namespace bool format_menu_time(char* out, size_t out_len) { @@ -94,12 +105,14 @@ platform::ui::screen::Hooks buildScreenSleepHooks(const Hooks& hooks) void prepareBootUi(bool waking_from_sleep) { - ::ui::i18n::reload_language(); - ui::SystemNotification::init(); if (!waking_from_sleep) { ui::boot::show(); + ui::boot::set_log_line("Loading language packs..."); + present_boot_overlay_now(); } + ::ui::i18n::reload_language(); + ui::SystemNotification::init(); } void initializeShell(const Hooks& hooks) diff --git a/modules/ui_shared/src/ui/startup_ui_shell.cpp b/modules/ui_shared/src/ui/startup_ui_shell.cpp index 03f0163c..e253bd8d 100644 --- a/modules/ui_shared/src/ui/startup_ui_shell.cpp +++ b/modules/ui_shared/src/ui/startup_ui_shell.cpp @@ -1,5 +1,6 @@ #include "ui/startup_ui_shell.h" +#include "lvgl.h" #include "ui/app_runtime.h" #include "ui/localization.h" #include "ui/menu/menu_layout.h" @@ -12,6 +13,12 @@ namespace bool s_shell_initialized = false; +void present_boot_overlay_now() +{ + lv_timer_handler(); + lv_refr_now(nullptr); +} + bool lock_ui(const Hooks& hooks) { return hooks.lock_ui ? hooks.lock_ui(hooks.lock_timeout_ms) : true; @@ -29,9 +36,9 @@ void unlock_ui(const Hooks& hooks) bool prepareBootUi(const Hooks& hooks, bool waking_from_sleep) { - ::ui::i18n::reload_language(); if (waking_from_sleep) { + ::ui::i18n::reload_language(); return true; } if (!lock_ui(hooks)) @@ -39,7 +46,10 @@ bool prepareBootUi(const Hooks& hooks, bool waking_from_sleep) return false; } ui::boot::show(); + ui::boot::set_log_line("Loading language packs..."); + present_boot_overlay_now(); unlock_ui(hooks); + ::ui::i18n::reload_language(); return true; } diff --git a/modules/ui_shared/src/ui/ui_boot.cpp b/modules/ui_shared/src/ui/ui_boot.cpp index c3ae5edb..84d1da4a 100644 --- a/modules/ui_shared/src/ui/ui_boot.cpp +++ b/modules/ui_shared/src/ui/ui_boot.cpp @@ -5,6 +5,12 @@ #include "ui/ui_boot.h" +#include + +#if !defined(LV_FONT_MONTSERRAT_12) || !LV_FONT_MONTSERRAT_12 +#define lv_font_montserrat_12 lv_font_montserrat_14 +#endif + namespace { @@ -15,12 +21,18 @@ constexpr uint32_t kMinShowMs = 900; constexpr uint32_t kMinShowMs = 3000; #endif constexpr uint32_t kBootBgColor = 0xF6E6C6; +constexpr uint32_t kBootLogTextColor = 0x8A6A3A; +constexpr lv_coord_t kBootLogPadX = 10; +constexpr lv_coord_t kBootLogPadBottom = 8; +constexpr std::size_t kBootLogTextCapacity = 96; lv_obj_t* s_root = nullptr; lv_obj_t* s_logo = nullptr; +lv_obj_t* s_log_label = nullptr; lv_timer_t* s_gate_timer = nullptr; uint32_t s_start_ms = 0; bool s_ready = false; +char s_log_text[kBootLogTextCapacity] = ""; extern "C" { @@ -46,10 +58,12 @@ void cleanup() lv_obj_del(s_root); s_root = nullptr; s_logo = nullptr; + s_log_label = nullptr; } s_ready = false; s_start_ms = 0; + s_log_text[0] = '\0'; } void check_gate() @@ -68,6 +82,17 @@ void check_gate() cleanup(); } +void refresh_log_label() +{ + if (!s_log_label) + { + return; + } + + lv_label_set_text(s_log_label, s_log_text); + lv_refr_now(nullptr); +} + } // namespace namespace ui::boot @@ -122,6 +147,15 @@ void show() lv_anim_start(&anim); #endif + s_log_label = lv_label_create(s_root); + lv_obj_set_width(s_log_label, screen_w - (kBootLogPadX * 2)); + lv_obj_set_style_text_color(s_log_label, lv_color_hex(kBootLogTextColor), 0); + lv_obj_set_style_text_font(s_log_label, &lv_font_montserrat_12, 0); + lv_obj_set_style_text_align(s_log_label, LV_TEXT_ALIGN_LEFT, 0); + lv_label_set_long_mode(s_log_label, LV_LABEL_LONG_DOT); + lv_obj_align(s_log_label, LV_ALIGN_BOTTOM_LEFT, kBootLogPadX, -kBootLogPadBottom); + lv_label_set_text(s_log_label, s_log_text); + s_gate_timer = lv_timer_create( [](lv_timer_t*) { @@ -131,6 +165,19 @@ void show() lv_timer_set_repeat_count(s_gate_timer, -1); } +void set_log_line(const char* text) +{ + const char* value = text ? text : ""; + if (std::strcmp(s_log_text, value) == 0) + { + return; + } + + std::strncpy(s_log_text, value, kBootLogTextCapacity - 1); + s_log_text[kBootLogTextCapacity - 1] = '\0'; + refresh_log_label(); +} + void mark_ready() { s_ready = true; diff --git a/modules/ui_shared/src/ui/widgets/ime/ime_widget.cpp b/modules/ui_shared/src/ui/widgets/ime/ime_widget.cpp index e08db072..8bc580c3 100644 --- a/modules/ui_shared/src/ui/widgets/ime/ime_widget.cpp +++ b/modules/ui_shared/src/ui/widgets/ime/ime_widget.cpp @@ -107,9 +107,8 @@ void set_button_label(lv_obj_t* button, const char* text) { label = lv_label_create(button); } - lv_obj_set_style_text_font(label, ::ui::fonts::localized_font(::ui::fonts::ui_chrome_font()), 0); lv_obj_set_style_text_color(label, lv_color_hex(0x3A2A1A), 0); - lv_label_set_text(label, text ? text : ""); + ::ui::i18n::set_content_label_text_raw(label, text ? text : ""); lv_obj_center(label); } @@ -177,6 +176,22 @@ bool resolve_touch_button_id(lv_event_t* e, lv_obj_t* matrix, uint32_t& button_i } #endif +void refresh_textarea_content_font(lv_obj_t* textarea) +{ + if (!textarea) + { + return; + } + + const char* text = lv_textarea_get_text(textarea); + ::ui::fonts::apply_content_font(textarea, text ? text : "", ::ui::fonts::ui_chrome_font()); +} + +void set_candidates_label_text(lv_obj_t* label, const char* text) +{ + ::ui::i18n::set_content_label_text_raw(label, text ? text : ""); +} + } // namespace extern "C" void ui_ime_toggle_mode() @@ -202,6 +217,7 @@ void ImeWidget::init(lv_obj_t* parent, lv_obj_t* textarea) { const char* cur = lv_textarea_get_text(textarea_); committed_text_ = cur ? std::string(cur) : std::string(); + refresh_textarea_content_font(textarea_); } s_active_ime = this; @@ -269,8 +285,7 @@ void ImeWidget::init_compact_ui(lv_obj_t* parent) LV_EVENT_KEY, this); candidates_label_ = lv_label_create(container_); - lv_label_set_text(candidates_label_, ""); - lv_obj_set_style_text_font(candidates_label_, ::ui::fonts::localized_font(::ui::fonts::ui_chrome_font()), 0); + set_candidates_label_text(candidates_label_, ""); lv_obj_set_style_text_color(candidates_label_, lv_color_hex(0x3A2A1A), 0); lv_obj_set_flex_grow(candidates_label_, 1); lv_obj_set_style_text_align(candidates_label_, LV_TEXT_ALIGN_RIGHT, 0); @@ -336,10 +351,9 @@ void ImeWidget::init_touch_ui(lv_obj_t* parent) LV_EVENT_KEY, this); candidates_label_ = lv_label_create(top_row_); - ::ui::i18n::set_label_text(candidates_label_, "English keyboard"); + set_candidates_label_text(candidates_label_, ::ui::i18n::tr("English keyboard")); lv_obj_set_flex_grow(candidates_label_, 1); lv_obj_set_style_text_align(candidates_label_, LV_TEXT_ALIGN_LEFT, 0); - lv_obj_set_style_text_font(candidates_label_, ::ui::fonts::localized_font(::ui::fonts::ui_chrome_font()), 0); lv_obj_set_style_text_color(candidates_label_, lv_color_hex(0x6B4A1E), 0); candidate_row_ = lv_obj_create(container_); @@ -445,6 +459,7 @@ void ImeWidget::setMode(Mode mode) { lv_textarea_set_accepted_chars(textarea_, nullptr); } + refresh_textarea_content_font(textarea_); } candidate_window_start_ = 0; refresh_labels(); @@ -661,6 +676,7 @@ void ImeWidget::sync_textarea() return; } lv_textarea_set_text(textarea_, committed_text_.c_str()); + refresh_textarea_content_font(textarea_); lv_textarea_set_cursor_pos(textarea_, LV_TEXTAREA_CURSOR_LAST); lv_obj_add_state(textarea_, LV_STATE_FOCUSED); if (lv_group_get_default()) @@ -821,13 +837,13 @@ void ImeWidget::refresh_labels() #if UI_SHARED_TOUCH_IME_ENABLED if (touch_keyboard_enabled_) { - ::ui::i18n::set_label_text(candidates_label_, "English keyboard"); + set_candidates_label_text(candidates_label_, ::ui::i18n::tr("English keyboard")); refresh_touch_keyboard(); refresh_touch_candidates(); return; } #endif - lv_label_set_text(candidates_label_, ""); + set_candidates_label_text(candidates_label_, ""); return; } @@ -837,13 +853,13 @@ void ImeWidget::refresh_labels() #if UI_SHARED_TOUCH_IME_ENABLED if (touch_keyboard_enabled_) { - ::ui::i18n::set_label_text(candidates_label_, "Number keyboard"); + set_candidates_label_text(candidates_label_, ::ui::i18n::tr("Number keyboard")); refresh_touch_keyboard(); refresh_touch_candidates(); return; } #endif - lv_label_set_text(candidates_label_, ""); + set_candidates_label_text(candidates_label_, ""); return; } @@ -854,7 +870,7 @@ void ImeWidget::refresh_labels() std::string hint = ime_.hasBuffer() ? ::ui::i18n::format("Pinyin: %s", ime_.buffer().c_str()) : std::string(::ui::i18n::tr("Pinyin keyboard")); - lv_label_set_text(candidates_label_, hint.c_str()); + set_candidates_label_text(candidates_label_, hint.c_str()); refresh_touch_keyboard(); refresh_touch_candidates(); return; @@ -872,11 +888,11 @@ void ImeWidget::refresh_candidates() } if (!ime_.hasBuffer()) { - lv_label_set_text(candidates_label_, ""); + set_candidates_label_text(candidates_label_, ""); return; } std::string text = make_candidates_text(ime_.candidates(), ime_.candidateIndex()); - lv_label_set_text(candidates_label_, text.c_str()); + set_candidates_label_text(candidates_label_, text.c_str()); } void ImeWidget::on_toggle_clicked(lv_event_t* e) diff --git a/modules/ui_shared/src/ui/widgets/top_bar.cpp b/modules/ui_shared/src/ui/widgets/top_bar.cpp index 59cec87b..9ed42050 100644 --- a/modules/ui_shared/src/ui/widgets/top_bar.cpp +++ b/modules/ui_shared/src/ui/widgets/top_bar.cpp @@ -162,7 +162,7 @@ void top_bar_set_title(TopBar& bar, const char* title) } lv_label_set_text(bar.title_label, title); - ::ui::fonts::apply_localized_font( + ::ui::fonts::apply_content_font( bar.title_label, title, resolve_top_bar_font(lv_obj_get_height(bar.container))); } @@ -180,7 +180,7 @@ void top_bar_set_right_text(TopBar& bar, const char* text) } lv_label_set_text(bar.right_label, text); - ::ui::fonts::apply_localized_font( + ::ui::fonts::apply_content_font( bar.right_label, text, resolve_top_bar_font(lv_obj_get_height(bar.container))); } diff --git a/packs/zh-Hans/DESCRIPTION.txt b/packs/zh-Hans/DESCRIPTION.txt index e3df4eb7..a5f54db8 100644 --- a/packs/zh-Hans/DESCRIPTION.txt +++ b/packs/zh-Hans/DESCRIPTION.txt @@ -1,5 +1,11 @@ -Simplified Chinese installs the zh-Hans locale, the zh-hans-cjk external CJK font pack, -and the zh-hans-pinyin IME registration used by the built-in Pinyin input backend. +Simplified Chinese installs the zh-Hans locale, a tiered two-pack font stack, and the +zh-hans-pinyin IME registration used by the built-in Pinyin input backend. + +The bundle ships: +- zh-hans-core: the common-glyph UI/content font loaded first for fast startup and lower steady-state RAM use +- zh-hans-ext: the remaining Chinese glyph coverage that the runtime can load on demand as a content supplement +- zh-hans-pinyin: the built-in Pinyin IME registration layer Use this bundle when you want a Chinese interface, Chinese text entry, or reliable -rendering of Chinese names and chat content while another locale remains active. +rendering of Chinese names and chat content while another locale remains active, without +paying the full monolithic CJK font cost up front. diff --git a/packs/zh-Hans/README.md b/packs/zh-Hans/README.md index 98b43037..1ee90beb 100644 --- a/packs/zh-Hans/README.md +++ b/packs/zh-Hans/README.md @@ -1,17 +1,20 @@ # zh-Hans Pack Bundle -This bundle keeps Simplified Chinese fully external to the firmware image. +This bundle keeps Simplified Chinese external to the firmware image and splits the CJK +coverage into a smaller core font plus an on-demand extension font. It contains: - locale pack: `zh-Hans` -- font pack: `zh-hans-cjk` +- font pack: `zh-hans-core` +- font pack: `zh-hans-ext` - IME pack: `zh-hans-pinyin` The locale manifest points to: -- `ui_font_pack=zh-hans-cjk` -- `content_font_pack=zh-hans-cjk` +- `ui_font_pack=zh-hans-core` +- `content_font_pack=zh-hans-core` +- `preferred_content_supplement_packs=zh-hans-ext` - `ime_pack=zh-hans-pinyin` Bundle-level package metadata lives in: @@ -25,7 +28,13 @@ Bundle-level package metadata lives in: - `package.ini` - `DESCRIPTION.txt` - `README.md` -- `fonts/zh-hans-cjk/` +- `fonts/zh-hans-core/` + - `manifest.ini` + - `build.ini` + - `charset.txt` + - `ranges.txt` + - `font.bin` after generation +- `fonts/zh-hans-ext/` - `manifest.ini` - `build.ini` - `charset.txt` @@ -37,21 +46,67 @@ Bundle-level package metadata lives in: - `ime/zh-hans-pinyin/` - `manifest.ini` -## Generate The Font Pack +## Pack Strategy -1. Refresh the subset files: +- `zh-hans-core` contains locale strings, manifest-facing names, and the highest-ranked + glyphs from the built-in Pinyin dictionary. +- `zh-hans-ext` contains the remaining glyphs from the Pinyin dictionary that are not + already present in `zh-hans-core`. +- On Chinese UI locale, the runtime loads `zh-hans-core` immediately and only brings in + `zh-hans-ext` when displayed content requires additional coverage. +- On non-Chinese UI locales, the runtime can load one or both packs as content + supplements when Chinese text appears. + +## Refresh The Ranked Glyph Sources ```bash -python tools/build_locale_pack_charset.py --pack-root packs/zh-Hans --extra-chars-file tools/pinyin_chars.txt +python tools/extract_pinyin_chars.py ``` -2. Generate `font.bin`: +This writes: + +- `tools/pinyin_chars.txt` +- `tools/pinyin_ranked_chars.txt` + +## Generate The Font Pack Charset Files + +Core pack: + +```bash +python tools/build_locale_pack_charset.py --pack-root packs/zh-Hans --font-pack-id zh-hans-core +``` + +Extension pack: + +```bash +python tools/build_locale_pack_charset.py --pack-root packs/zh-Hans --font-pack-id zh-hans-ext +``` + +The `build.ini` files are the source of truth. `scripts/build_pack_repository.py` uses +them to regenerate `charset.txt`, `ranges.txt`, and `font.bin` during repository builds. + +## Generate The Font Binaries Manually + +Core pack: ```powershell python tools/generate_binfont_with_lv_font_conv.py ` --font tools/fonts/NotoSansCJKsc-Regular.otf ` - --charset-file packs/zh-Hans/fonts/zh-hans-cjk/charset.txt ` - --output packs/zh-Hans/fonts/zh-hans-cjk/font.bin ` + --charset-file packs/zh-Hans/fonts/zh-hans-core/charset.txt ` + --output packs/zh-Hans/fonts/zh-hans-core/font.bin ` + --size 16 ` + --bpp 2 ` + --node-exe C:\Users\VicLi\AppData\Local\nodejs22\current\node.exe ` + --no-compress +``` + +Extension pack: + +```powershell +python tools/generate_binfont_with_lv_font_conv.py ` + --font tools/fonts/NotoSansCJKsc-Regular.otf ` + --charset-file packs/zh-Hans/fonts/zh-hans-ext/charset.txt ` + --output packs/zh-Hans/fonts/zh-hans-ext/font.bin ` --size 16 ` --bpp 2 ` --node-exe C:\Users\VicLi\AppData\Local\nodejs22\current\node.exe ` @@ -60,10 +115,11 @@ python tools/generate_binfont_with_lv_font_conv.py ` Notes: -- `charset.txt` and `ranges.txt` are derived from translated strings plus the built-in Pinyin candidate set. -- `estimated_ram_bytes` in the font manifest reflects the runtime LVGL load cost, not the raw file size. -- `build.ini` is the source-of-truth for generating `font.bin` during Pages/package builds. -- `font.bin` is ignored by Git. Regenerate it whenever the strings or IME glyph subset changes. +- `estimated_ram_bytes` in each font manifest should track the generated `font.bin` size. +- `zh-hans-core` is intentionally the smaller steady-state font. `zh-hans-ext` is a + content supplement, not a UI font. +- `font.bin` files are ignored by Git. Regenerate them whenever strings or IME glyph + data change. ## Distribution Package @@ -72,19 +128,25 @@ Notes: - `site/assets/packs/zh-Hans-1.0.0.zip` - `site/data/packs.json` -The zip is the bundle artifact for a future Extensions downloader. Its `payload/` directory unpacks into `/trailmate/packs/...`. +The zip is the bundle artifact used by the Extensions downloader. Its `payload/` +directory unpacks into `/trailmate/packs/...`. ## Copy To SD Card Copy the bundle contents so the SD card ends up with: ```text -/trailmate/packs/fonts/zh-hans-cjk/manifest.ini -/trailmate/packs/fonts/zh-hans-cjk/ranges.txt -/trailmate/packs/fonts/zh-hans-cjk/font.bin +/trailmate/packs/fonts/zh-hans-core/manifest.ini +/trailmate/packs/fonts/zh-hans-core/ranges.txt +/trailmate/packs/fonts/zh-hans-core/font.bin +/trailmate/packs/fonts/zh-hans-ext/manifest.ini +/trailmate/packs/fonts/zh-hans-ext/ranges.txt +/trailmate/packs/fonts/zh-hans-ext/font.bin /trailmate/packs/locales/zh-Hans/manifest.ini /trailmate/packs/locales/zh-Hans/strings.tsv /trailmate/packs/ime/zh-hans-pinyin/manifest.ini ``` -After reboot, `简体中文` appears in Settings. The font is only loaded when the locale becomes active or when Chinese content needs to be rendered as a supplement on a different UI locale. +After reboot, `简体中文` appears in Settings. The runtime loads the core pack when the +locale becomes active, and it can add the extension pack later when extra Chinese glyphs +are needed on chat/content surfaces. diff --git a/packs/zh-Hans/fonts/zh-hans-cjk/charset.txt b/packs/zh-Hans/fonts/zh-hans-cjk/charset.txt deleted file mode 100644 index 3500a168..00000000 --- a/packs/zh-Hans/fonts/zh-hans-cjk/charset.txt +++ /dev/null @@ -1,106 +0,0 @@ -°。一丁七万丈三上下丌不与丐丑专且丕世丘丙业丛东丝丞丢两严丧丨个丫丬中丰串临丶丸丹为主丽举丿乃久乇么义之乌乍乎乏乐乒乓乔乖乘乙乜 -九乞也习乡书乩买乱乳乾了予争事二亍于亏云互亓五井亘亚些亟亠亡亢交亥亦产亨亩享京亭亮亲亳亵人亻亿什仁仂仃仄仅仆仇仉今介仍从仑仓仔仕 -他仗付仙仝仞仟仡代令以仨仪仫们仰仲仳仵件价任份仿企伉伊伍伎伏伐休众优伙会伛伞伟传伢伤伥伦伧伪伫伯估伲伴伶伸伺似伽佃但位低住佐佑体 -何佗佘余佚佛作佝佞佟你佣佤佥佧佩佬佯佰佳佴佶佻佼佾使侃侄侈侉例侍侏侑侔侗供依侠侣侥侦侧侨侩侪侬侮侯侵便促俄俅俊俎俏俐俑俗俘俚俜保 -俞俟信俣俦俨俩俪俭修俯俱俳俸俺俾倌倍倏倒倔倘候倚倜借倡倥倦倨倩倪倬倭倮债值倾偃假偈偌偎偏偕做停健偬偶偷偻偾偿傀傅傈傍傣傥傧储傩催 -傲傺傻像僖僚僦僧僬僭僮僳僵僻儆儇儋儒儡儿兀允元兄充兆先光克免兑兔兕兖党兜兢入全八公六兮兰共关兴兵其具典兹养兼兽冀冁冂内冈冉册再冒 -冕冖冗写军农冠冢冤冥冫冬冯冰冱冲决况冶冷冻冼冽净凄准凇凉凋凌减凑凛凝几凡凤凫凭凯凰凳凵凶凸凹出击凼函凿刀刁刂刃分切刈刊刍刎刑划刖 -列刘则刚创初删判刨利别刭刮到刳制刷券刹刺刻刽刿剀剁剂剃削剌前剐剑剔剖剜剞剡剥剧剩剪副割剽剿劁劂劈劐劓力劝办功加务劢劣动助努劫劬劭 -励劲劳劾势勃勇勉勋勐勒勖勘募勤勰勹勺勾勿匀包匆匈匍匏匐匕化北匙匚匝匠匡匣匦匪匮匹区医匾匿十千卅升午卉半华协卑卒卓单卖南博卜卞卟占 -卡卢卣卤卦卧卩卫卮卯印危即却卵卷卸卺卿厂厄厅历厉压厌厍厕厘厚厝原厢厣厥厦厨厩厮厶去县叁参又叉及友双反发叔取受变叙叛叟叠口古句另叨 -叩只叫召叭叮可台叱史右叵叶号司叹叻叼叽吁吃各吆合吉吊同名后吏吐向吒吓吕吖吗君吝吞吟吠吡吣否吧吨吩含听吭吮启吱吲吴吵吸吹吻吼吾呀呃 -呆呈告呋呐呒呓呔呕呖呗员呙呛呜呢呤呦周呱呲味呵呶呷呸呻呼命咀咂咄咆咋和咎咏咐咒咔咕咖咙咚咛咝咣咤咦咧咨咩咪咫咬咭咯咱咳咴咸咻咽咿 -哀品哂哄哆哇哈哉哌响哎哏哐哑哒哓哔哕哗哙哚哜哝哞哟哥哦哧哨哩哪哭哮哲哳哺哼哽哿唁唆唇唉唏唐唑唔唛唠唢唣唤唧唪唬售唯唰唱唳唷唼唾唿 -啁啃啄商啉啊啐啕啖啜啡啤啥啦啧啪啬啭啮啵啶啷啸啻啼啾喀喁喂喃善喇喈喉喊喋喏喑喔喘喙喜喝喟喧喱喳喵喷喹喻喽喾嗄嗅嗉嗌嗍嗑嗒嗓嗔嗖嗜 -嗝嗟嗡嗣嗤嗥嗦嗨嗪嗫嗬嗯嗲嗳嗵嗷嗽嗾嘀嘁嘈嘉嘌嘎嘏嘘嘛嘞嘟嘣嘤嘧嘬嘭嘱嘲嘴嘶嘹嘻嘿噌噍噎噔噗噘噙噜噢噤器噩噪噫噬噱噶噻噼嚅嚆嚎嚏 -嚓嚣嚯嚷嚼囊囔囗囚四囝回囟因囡团囤囫园困囱围囵囹固国图囿圃圄圆圈圉圊圜土圣在圩圪圬圭圮圯地圳圹场圻圾址坂均坊坌坍坎坏坐坑块坚坛坜 -坝坞坟坠坡坤坦坨坩坪坫坭坯坳坶坷坻坼垂垃垄垅垆型垌垒垓垛垠垡垢垣垤垦垧垩垫垭垮垲垴垸埂埃埋城埏埒埔埕埘埙埚埝域埠埤埭埯埴埸培基埽 -堀堂堆堇堋堍堑堕堙堞堠堡堤堪堰堵塄塌塍塑塔塘塞塥填塬塾墀墁境墅墉墒墓墙墚增墟墨墩墼壁壅壑壕壤士壬壮声壳壶壹夂处备复夏夔夕外夙多夜 -够夤夥大天太夫夭央夯失头夷夸夹夺夼奁奂奄奇奈奉奋奎奏契奔奕奖套奘奚奠奢奥女奴奶奸她好妁如妃妄妆妇妈妊妍妒妓妖妗妙妞妣妤妥妨妩妪妫 -妮妯妲妹妻妾姆姊始姐姑姒姓委姗姘姚姜姝姣姥姨姬姹姻姿威娃娄娅娆娇娈娉娌娑娓娘娜娟娠娣娥娩娱娲娴娶娼婀婆婉婊婕婚婢婧婪婴婵婶婷婺婿 -媒媚媛媪媲媳媵媸媾嫁嫂嫉嫌嫒嫔嫖嫘嫜嫠嫡嫣嫦嫩嫫嫱嬉嬖嬗嬲嬴嬷孀子孑孓孔孕字存孙孚孛孜孝孟孢季孤孥学孩孪孬孰孱孳孵孺孽宀宁它宄宅 -宇守安宋完宏宓宕宗官宙定宛宜宝实宠审客宣室宥宦宪宫宰害宴宵家宸容宽宾宿寂寄寅密寇富寐寒寓寝寞察寡寤寥寨寮寰寸对寺寻导寿封射将尉尊 -小少尔尕尖尘尚尜尝尢尤尥尧尬就尴尸尹尺尻尼尽尾尿局屁层居屈屉届屋屎屏屐屑展屙属屠屡屣履屦屮屯山屹屺屿岁岂岈岌岍岐岑岔岖岗岘岙岚岛 -岜岢岣岩岫岬岭岱岳岵岷岸岽岿峁峄峋峒峙峡峤峥峦峨峪峭峰峻崂崃崆崇崎崔崖崛崞崤崦崧崩崭崮崴崽崾嵇嵊嵋嵌嵘嵛嵝嵩嵫嵬嵯嵴嶂嶙嶝嶷巅巍 -巛川州巡巢工左巧巨巩巫差巯己已巳巴巷巽巾币市布帅帆师希帏帐帑帔帕帖帘帙帚帛帜帝带帧席帮帱帷常帻帼帽幂幄幅幌幔幕幛幞幡幢干平年并幸 -幺幻幼幽广庀庄庆庇床庋序庐庑库应底庖店庙庚府庞废庠庥度座庭庳庵庶康庸庹庾廉廊廑廒廓廖廛廨廪廴延廷建廾廿开弁异弃弄弈弊弋式弑弓引弗 -弘弛弟张弥弦弧弩弪弭弯弱弹强弼彀彐归当录彖彗彘彝彡形彤彦彩彪彬彭彰影彳彷役彻彼往征徂径待徇很徉徊律後徐徒徕得徘徙徜御徨循徭微徵德 -徼徽心忄必忆忉忌忍忏忐忑忒忖志忘忙忝忠忡忤忧忪快忭忮忱念忸忻忽忾忿怀态怂怃怄怅怆怊怍怎怏怒怔怕怖怙怛怜思怠怡急怦性怨怩怪怫怯怵总 -怼怿恁恂恃恋恍恐恒恕恙恚恝恢恣恤恧恨恩恪恫恬恭息恰恳恶恸恹恺恻恼恽恿悃悄悉悌悍悒悔悖悚悛悝悟悠患悦您悫悬悭悯悱悲悴悸悻悼情惆惊惋 -惑惕惘惚惜惝惟惠惦惧惨惩惫惬惭惮惯惰想惴惶惹惺愀愁愆愈愉愍愎意愕愚感愠愣愤愦愧愫愿慈慊慌慎慑慕慝慢慧慨慰慵慷憋憎憔憝憧憨憩憬憷憾 -懂懈懊懋懑懒懔懦懵懿戆戈戊戋戌戍戎戏成我戒戕或戗战戚戛戟戡戢戤戥截戬戮戳戴户戽戾房所扁扃扇扈扉手扌才扎扑扒打扔托扛扣扦执扩扪扫扬 -扭扮扯扰扳扶批扼找承技抄抉把抑抒抓投抖抗折抚抛抟抠抡抢护报抨披抬抱抵抹抻押抽抿拂拄担拆拇拈拉拊拌拍拎拐拒拓拔拖拗拘拙拚招拜拟拢拣 -拥拦拧拨择括拭拮拯拱拳拴拶拷拼拽拾拿持挂指挈按挎挑挖挚挛挝挞挟挠挡挢挣挤挥挨挪挫振挲挹挺挽捂捃捅捆捉捋捌捍捎捏捐捕捞损捡换捣捧捩 -捭据捱捶捷捺捻掀掂掇授掉掊掌掎掏掐排掖掘掠探掣接控推掩措掬掭掮掰掳掴掷掸掺掼掾揄揆揉揍揎描提插揖揞揠握揣揩揪揭揲援揶揸揽揿搀搁搂 -搅搋搌搏搐搓搔搛搜搞搠搡搦搪搬搭搴携搽搿摁摄摅摆摇摈摊摒摔摘摞摧摩摭摸摹摺撂撄撅撇撑撒撕撖撙撞撤撩撬播撮撰撵撷撸撺撼擀擂擅操擎擐 -擒擗擘擞擢擤擦攀攉攒攘攥攫攮支攴攵收攸改攻放政故效敉敌敏救敕敖教敛敝敞敢散敦敫敬数敲整敷文斋斌斐斑斓斗料斛斜斟斡斤斥斧斩斫断斯新 -方於施旁旃旄旅旆旋旌旎族旒旖旗无既日旦旧旨早旬旭旮旯旰旱时旷旺昀昂昃昆昊昌明昏易昔昕昙昝星映春昧昨昭是昱昴昵昶昼显晁晃晋晌晏晒晓 -晔晕晖晗晚晟晡晤晦晨普景晰晴晶晷智晾暂暄暇暌暑暖暗暝暧暨暮暴暹暾曙曛曜曝曦曩曰曲曳更曷曹曼曾替最月有朊朋服朐朔朕朗望朝期朦木未末 -本札术朱朴朵机朽杀杂权杆杈杉杌李杏材村杓杖杜杞束杠条来杨杩杪杭杯杰杲杳杵杷杼松板极构枇枉枋析枕林枘枚果枝枞枢枣枥枧枨枪枫枭枯枰枳 -枵架枷枸柁柃柄柏某柑柒染柔柘柙柚柜柝柞柠柢查柩柬柯柰柱柳柴柽柿栀栅标栈栉栊栋栌栎栏树栓栖栗栝校栩株栲栳样核根格栽栾桀桁桂桃桄桅框 -案桉桊桌桎桐桑桓桔桕桠桡桢档桤桥桦桧桨桩桫桴桶桷梁梃梅梆梏梓梗梢梦梧梨梭梯械梳梵检棂棉棋棍棒棕棘棚棠棣森棰棱棵棹棺棼椁椅椋植椎椐 -椒椟椠椤椭椰椴椹椽椿楂楔楗楚楝楞楠楣楦楫楮楱楷楸楹楼榀概榄榆榇榈榉榍榔榕榘榛榜榧榨榫榭榱榴榷榻槁槊槌槎槐槔槛槟槠槭槲槽槿樊樗樘樟 -模樨横樯樱樵樽樾橄橇橐橘橙橛橡橥橱橹橼檀檄檎檐檑檗檠檩檫檬欠次欢欣欤欧欲欷欹欺款歃歆歇歉歌歙止正此步武歧歪歹死歼殁殂殃殄殆殇殉殊 -残殍殒殓殖殚殛殡殪殳殴段殷殿毁毂毅毋母每毒毓比毕毖毗毙毛毡毪毫毯毳毵毹毽氅氆氇氍氏氐民氓气氕氖氘氙氚氛氟氡氢氤氦氧氨氩氪氮氯氰氲 -水氵永氽汀汁求汆汇汉汊汐汔汕汗汛汜汝汞江池污汤汨汩汪汰汲汴汶汹汽汾沁沂沃沅沆沈沉沌沏沐沓沔沙沛沟没沣沤沥沦沧沩沪沫沭沮沱沲河沸油 -治沼沽沾沿泄泅泉泊泌泐泓泔法泖泗泛泞泠泡波泣泥注泪泫泮泯泰泱泳泵泶泷泸泺泻泼泽泾洁洄洇洋洌洎洒洗洙洚洛洞津洧洪洫洮洱洲洳洵洹活洼 -洽派流浃浅浆浇浈浊测浍济浏浑浒浓浔浙浚浜浞浠浣浦浩浪浮浯浴海浸浼涂涅消涉涌涎涑涓涔涕涛涝涞涟涠涡涣涤润涧涨涩涪涫涮涯液涵涸涿淀淄 -淅淆淇淋淌淑淖淘淙淝淞淠淡淤淦淫淬淮深淳混淹添淼清渊渌渍渎渐渑渔渖渗渚渝渠渡渣渤渥温渫渭港渲渴游渺湃湄湍湎湓湔湖湘湛湟湫湮湾湿溃 -溅溆溉溏源溘溜溟溢溥溧溪溯溱溲溴溶溷溺溻溽滁滂滇滋滏滑滓滔滕滗滚滞滟滠满滢滤滥滦滨滩滴滹漂漆漉漏漓演漕漠漤漩漪漫漭漯漱漳漶漾潆潇 -潋潍潘潜潞潢潦潭潮潲潴潸潺潼澄澈澉澌澍澎澜澡澧澳澶澹激濂濉濑濒濞濠濡濮濯瀑瀚瀛瀣瀵瀹灌灏灞火灬灭灯灰灵灶灸灼灾灿炀炅炉炊炎炒炔炕 -炖炙炜炝炫炬炭炮炯炱炳炷炸点炻炼炽烀烁烂烃烈烊烘烙烛烟烤烦烧烨烩烫烬热烯烷烹烽焉焊焐焓焕焖焘焙焚焦焯焰焱然煅煊煌煎煜煞煤煦照煨煮 -煲煳煸煺煽熄熊熏熔熘熙熟熠熨熬熳熵熹燃燎燔燕燠燥燧燮燹爆爝爨爪爬爰爱爵父爷爸爹爻爽爿片版牌牍牒牖牙牛牝牟牡牢牦牧物牮牯牲牵特牺牾 -牿犀犁犄犊犋犍犏犒犟犬犭犯犰犴状犷犸犹狁狂狃狄狈狍狎狐狒狗狙狞狠狡狨狩独狭狮狯狰狱狲狳狴狷狸狺狻狼猁猃猊猎猓猕猖猗猛猜猝猞猡猢猥 -猩猪猫猬献猱猴猷猸猹猾猿獍獐獒獗獠獬獭獯獾玄率玉王玎玑玖玛玟玢玩玫玮环现玲玳玷玺玻珀珂珈珉珊珍珏珐珑珙珞珠珥珧珩班珲球琅理琉琊琏 -琐琚琛琢琥琦琨琪琬琮琰琳琴琵琶琼瑁瑕瑗瑙瑚瑛瑜瑞瑟瑭瑰瑶瑷瑾璀璁璃璇璋璎璐璜璞璧璨璩璺瓒瓜瓞瓠瓢瓣瓤瓦瓮瓯瓴瓶瓷瓿甄甍甏甑甓甘甙 -甚甜生甥用甩甫甬甭甯田由甲申电男甸町画甾畀畅畈畋界畎畏畔留畚畛畜略畦番畲畴畸畹畿疃疆疋疏疑疒疔疖疗疙疚疝疟疠疡疣疤疥疫疬疮疯疰疱 -疲疳疴疵疸疹疼疽疾痂痃痄病症痈痉痊痍痒痔痕痖痘痛痞痢痣痤痦痧痨痪痫痰痱痴痹痼痿瘀瘁瘃瘅瘊瘌瘐瘕瘗瘘瘙瘛瘟瘠瘢瘤瘥瘦瘩瘪瘫瘭瘰瘳瘴 -瘵瘸瘼瘾瘿癀癃癌癍癔癖癜癞癣癫癯癸登白百皂的皆皇皈皋皎皑皓皖皙皤皮皱皲皴皿盂盅盆盈益盍盎盏盐监盒盔盖盗盘盛盟盥目盯盱盲直相盹盼盾 -省眄眇眈眉看眍眙眚真眠眢眦眨眩眭眯眵眶眷眸眺眼着睁睃睇睐睑睚睛睡睢督睥睦睨睫睬睹睽睾睿瞀瞄瞅瞌瞍瞎瞑瞒瞟瞠瞢瞥瞧瞩瞪瞬瞰瞳瞵瞻瞽 -瞿矍矗矛矜矢矣知矧矩矫矬短矮石矶矸矽矾矿砀码砂砉砌砍砑砒研砖砗砘砚砜砝砟砣砥砦砧砩砬砭砰破砷砸砹砺砻砼砾础硅硇硌硎硐硒硕硖硗硝硪 -硫硬硭确硷硼碇碉碌碍碎碑碓碗碘碚碛碜碟碡碣碥碧碰碱碲碳碴碹碾磁磅磉磊磋磐磔磕磙磨磬磲磴磷磺礁礅礓礞礤礴示礻礼社祀祁祆祈祉祓祖祗祚 -祛祜祝神祟祠祢祥祧票祭祯祷祸祺禀禁禄禅禊福禚禧禳禹禺离禽禾秀私秃秆秉秋种科秒秕秘租秣秤秦秧秩秫秭积称秸移秽稀稂稃稆程稍税稔稗稚稞 -稠稣稳稷稹稻稼稽稿穆穑穗穰穴究穷穸穹空穿窀突窃窄窆窈窍窑窒窕窖窗窘窜窝窟窠窥窦窨窬窭窳窿立竖站竞竟章竣童竦竭端竹竺竽竿笃笄笆笈笊 -笋笏笑笔笕笙笛笞笠笤笥符笨笪笫第笮笱笳笸笺笼笾筅筇等筋筌筏筐筑筒答策筘筚筛筝筠筢筮筱筲筵筷筹筻签简箅箍箐箔箕算箜箝管箢箦箧箨箩箪 -箫箬箭箱箴箸篁篆篇篌篑篓篙篚篝篡篥篦篪篮篱篷篼篾簇簋簌簏簖簟簦簧簪簸簿籀籁籍米籴类籼籽粉粑粒粕粗粘粜粝粞粟粢粤粥粪粮粱粲粳粹粼粽 -精糁糅糇糈糊糌糍糕糖糗糙糜糟糠糨糯糸系紊素索紧紫累絮絷綦綮縻繁繇纂纛纟纠纡红纣纤纥约级纨纩纪纫纬纭纯纰纱纲纳纵纶纷纸纹纺纽纾线绀 -绁绂练组绅细织终绉绊绋绌绍绎经绐绑绒结绔绕绗绘给绚绛络绝绞统绠绡绢绣绥绦继绨绩绪绫续绮绯绰绱绲绳维绵绶绷绸绺绻综绽绾绿缀缁缂缃缄 -缅缆缇缈缉缋缌缍缎缏缑缒缓缔缕编缗缘缙缚缛缜缝缟缠缡缢缣缤缥缦缧缨缩缪缫缬缭缮缯缰缱缲缳缴缵缶缸缺罂罄罅罐网罔罕罗罘罚罟罡罢罨罩 -罪置罱署罴罹罾羁羊羌美羔羚羝羞羟羡群羧羯羰羲羸羹羼羽羿翁翅翊翌翎翔翕翘翟翠翡翥翦翩翮翰翱翳翻翼耀老考耄者耆耋而耍耐耒耔耕耖耗耘耙 -耜耠耢耥耦耧耨耩耪耱耳耵耶耷耸耻耽耿聂聃聆聊聋职聍聒联聘聚聩聪聱聿肀肃肄肆肇肉肋肌肓肖肘肚肛肜肝肟肠股肢肤肥肩肪肫肭肮肯肱育肴肷 -肺肼肽肾肿胀胁胂胃胄胆背胍胎胖胗胙胚胛胜胝胞胡胤胥胧胨胩胪胫胬胭胯胰胱胲胳胴胶胸胺胼能脂脆脉脊脍脎脏脐脑脒脓脔脖脘脚脞脬脯脱脲脶 -脸脾腆腈腊腋腌腐腑腓腔腕腙腚腠腥腧腩腭腮腰腱腴腹腺腻腼腽腾腿膀膂膈膊膏膑膘膛膜膝膣膦膨膪膳膺膻臀臁臂臃臆臊臌臣臧自臬臭至致臻臼臾 -舀舁舂舄舅舆舌舍舐舒舔舛舜舞舟舡舢舣舨航舫般舭舯舰舱舳舴舵舶舷舸船舻舾艄艇艉艋艏艘艚艟艨艮良艰色艳艴艹艺艽艾艿节芄芈芊芋芍芎芏芑 -芒芗芘芙芜芝芟芡芤芥芦芨芩芪芫芬芭芮芯芰花芳芴芷芸芹芽芾苁苄苇苈苊苋苌苍苎苏苑苒苓苔苕苗苘苛苜苞苟苠苡苣苤若苦苫苯英苴苷苹苻茁茂 -范茄茅茆茇茈茉茌茎茏茑茔茕茗茚茛茜茧茨茫茬茭茯茱茳茴茵茶茸茹茺茼荀荃荆荇草荏荐荑荒荔荚荛荜荞荟荠荡荣荤荥荦荧荨荩荪荫荬荭荮药荷荸 -荻荼荽莅莆莉莎莒莓莘莛莜莞莠莨莩莪莫莰莱莲莳莴莶获莸莹莺莼莽菀菁菅菇菊菌菏菔菖菘菜菝菟菠菡菥菩菪菰菱菲菸菹菽萁萃萄萆萋萌萍萎萏萑 -萘萜萝萤营萦萧萨萱萸萼落葆葑著葙葚葛葜葡董葩葫葬葭葱葳葵葶葸葺蒂蒇蒈蒉蒋蒌蒎蒗蒙蒜蒡蒯蒲蒴蒸蒹蒺蒽蒿蓁蓄蓉蓊蓍蓐蓑蓓蓖蓝蓟蓠蓣蓥 -蓦蓬蓰蓼蓿蔌蔑蔓蔗蔚蔟蔡蔫蔬蔷蔸蔹蔺蔻蔼蔽蕃蕈蕉蕊蕖蕙蕞蕤蕨蕲蕴蕹蕺蕻蕾薄薅薇薏薛薜薤薨薪薮薯薰薷薹藁藉藏藐藓藕藜藤藩藻藿蘅蘑蘖 -蘧蘩蘸蘼虍虎虏虐虑虔虚虞虢虫虬虮虱虹虺虻虼虽虾虿蚀蚁蚂蚊蚋蚌蚍蚓蚕蚜蚝蚣蚤蚧蚨蚩蚪蚬蚯蚰蚱蚴蚵蚶蚺蛀蛄蛆蛇蛉蛊蛋蛎蛏蛐蛑蛔蛘蛙蛛 -蛞蛟蛤蛩蛭蛮蛰蛱蛲蛳蛴蛸蛹蛾蜀蜂蜃蜇蜈蜉蜊蜍蜒蜓蜕蜗蜘蜚蜜蜞蜡蜢蜣蜥蜩蜮蜱蜴蜷蜻蜾蜿蝇蝈蝉蝌蝎蝓蝗蝙蝠蝣蝤蝥蝮蝰蝴蝶蝻蝼蝽蝾螂螃 -螅螈螋融螓螗螟螨螫螬螭螯螳螵螺螽蟀蟆蟊蟋蟑蟒蟓蟛蟠蟥蟪蟮蟹蟾蠃蠊蠓蠕蠖蠛蠡蠢蠲蠹蠼血衄衅行衍衔街衙衡衢衣衤补表衩衫衬衮衰衲衷衽衾 -衿袁袂袄袅袈袋袍袒袖袜袢袤被袭袱袷袼裁裂装裆裉裎裒裔裕裘裙裟裢裣裤裥裨裰裱裳裴裸裹裼裾褂褊褐褒褓褙褚褛褡褥褪褫褰褴褶襁襄襞襟襦襻 -西要覃覆见观规觅视觇览觉觊觋觌觎觏觐觑角觖觚觜觞解觥触觫觯觳言訇訾詈詹誉誊誓謇謦警譬讠计订讣认讥讦讧讨让讪讫训议讯记讲讳讴讵讶讷 -许讹论讼讽设访诀证诂诃评诅识诈诉诊诋诌词诎诏译诒诓诔试诖诗诘诙诚诛诜话诞诟诠诡询诣诤该详诧诨诩诫诬语诮误诰诱诲诳说诵诶请诸诹诺读 -诼诽课诿谀谁谂调谄谅谆谇谈谊谋谌谍谎谏谐谑谒谓谔谕谖谗谘谙谚谛谜谝谟谠谡谢谣谤谥谦谧谨谩谪谫谬谭谮谯谰谱谲谳谴谵谶谷豁豆豇豉豌豕 -豚象豢豪豫豳豸豹豺貂貅貉貊貌貔貘贝贞负贡财责贤败账货质贩贪贫贬购贮贯贰贱贲贳贴贵贶贷贸费贺贻贼贽贾贿赀赁赂赃资赅赆赇赈赉赊赋赌赍 -赎赏赐赓赔赕赖赘赙赚赛赜赝赞赠赡赢赣赤赦赧赫赭走赳赴赵赶起趁趄超越趋趑趔趟趣趱足趴趵趸趺趼趾趿跃跄跆跋跌跎跏跑跖跗跚跛距跞跟跣跤 -跨跪跫跬路跳践跷跸跹跺跻跽踅踉踊踌踏踔踝踞踟踢踣踩踪踬踮踯踱踵踹踺踽蹀蹁蹂蹄蹇蹈蹉蹊蹋蹑蹒蹙蹦蹩蹬蹭蹯蹰蹲蹴蹶蹼蹿躁躅躇躏躐躔躜 -躞身躬躯躲躺軎车轧轨轩轫转轭轮软轰轱轲轳轴轵轶轷轸轹轺轻轼载轾轿辁辂较辄辅辆辇辈辉辊辋辍辎辏辐辑输辔辕辖辗辘辙辚辛辜辞辟辣辨辩辫 -辰辱辶边辽达迁迂迄迅过迈迎运近迓返迕还这进远违连迟迢迤迥迦迨迩迪迫迭迮述迳迷迸迹追退送适逃逄逅逆选逊逋逍透逐逑递途逖逗通逛逝逞速 -造逡逢逦逭逮逯逵逶逸逻逼逾遁遂遄遇遍遏遐遑遒道遗遘遛遢遣遥遨遭遮遴遵遽避邀邂邃邈邋邑邓邕邗邙邛邝邡邢那邦邪邬邮邯邰邱邳邴邵邶邸邹 -邺邻邾郁郄郅郇郊郎郏郐郑郓郗郛郜郝郡郢郦郧部郫郭郯郴郸都郾鄂鄄鄙鄞鄢鄣鄯鄱鄹酃酆酉酊酋酌配酎酏酐酒酗酚酝酞酡酢酣酤酥酩酪酬酮酯酰 -酱酲酴酵酶酷酸酹酽酾酿醅醇醉醋醌醍醐醑醒醚醛醢醣醪醭醮醯醴醵醺采釉释里重野量金釜鉴銎銮鋈錾鍪鎏鏊鏖鐾鑫钅钆钇针钉钊钋钌钍钎钏钐钒 -钓钔钕钗钙钚钛钜钝钞钟钠钡钢钣钤钥钦钧钨钩钪钫钬钭钮钯钰钱钲钳钴钵钶钷钸钹钺钻钼钽钾钿铀铁铂铃铄铅铆铈铉铊铋铌铍铎铐铑铒铕铖铗铘 -铙铛铜铝铞铟铠铡铢铣铤铥铧铨铩铪铫铬铭铮铯铰铱铲铳铴铵银铷铸铹铺铼铽链铿销锁锂锃锄锅锆锇锈锉锊锋锌锍锎锏锐锑锒锓锔锕锖锗锘错锚锛 -锝锞锟锡锢锣锤锥锦锨锩锪锫锬锭键锯锰锱锲锴锵锶锷锸锹锺锻锼锾锿镀镁镂镄镅镆镇镉镊镌镍镎镏镐镑镒镓镔镖镗镘镙镛镜镝镞镟镡镢镣镤镥镦 -镧镨镩镪镫镬镭镯镰镱镲镳镶长门闩闪闫闭问闯闰闱闲闳间闵闶闷闸闹闺闻闼闽闾阀阁阂阃阄阅阆阈阉阊阋阌阍阎阏阐阑阒阔阕阖阗阙阚阜阝队阡 -阢阪阮阱防阳阴阵阶阻阼阽阿陀陂附际陆陇陈陉陋陌降限陔陕陛陟陡院除陧陨险陪陬陲陴陵陶陷隅隆隈隋隍随隐隔隗隘隙障隧隰隳隶隹隼隽难雀雁 -雄雅集雇雉雌雍雎雏雒雕雠雨雩雪雯雳零雷雹雾需霁霄霆震霈霉霍霎霏霓霖霜霞霪霭霰露霸霹霾青靓靖静靛非靠靡面靥革靳靴靶靼鞅鞋鞍鞑鞒鞔鞘 -鞠鞣鞫鞭鞯鞲鞴韦韧韩韪韫韬韭音韵韶页顶顷顸项顺须顼顽顾顿颀颁颂颃预颅领颇颈颉颊颌颍颏颐频颓颔颖颗题颚颛颜额颞颟颠颡颢颤颥颦颧风飑 -飒飓飕飘飙飚飞食飧飨餍餐餮饔饕饣饥饧饨饩饪饫饬饭饮饯饰饱饲饴饵饶饷饺饼饽饿馀馁馄馅馆馇馈馊馋馍馏馐馑馒馓馔馕首馗馘香馥馨马驭驮驯 -驰驱驳驴驵驶驷驸驹驺驻驼驽驾驿骀骁骂骄骅骆骇骈骊骋验骏骐骑骒骓骖骗骘骚骛骜骝骞骟骠骡骢骣骤骥骧骨骰骱骶骷骸骺骼髀髁髂髅髋髌髑髓高 -髟髡髦髫髭髯髹髻鬃鬈鬏鬓鬟鬣鬯鬲鬻鬼魁魂魃魄魅魇魈魉魍魏魑魔鱼鱿鲁鲂鲅鲆鲇鲈鲋鲍鲎鲐鲑鲒鲔鲕鲚鲛鲜鲞鲟鲠鲡鲢鲣鲤鲥鲦鲧鲨鲩鲫鲭鲮 -鲰鲱鲲鲳鲴鲵鲶鲷鲸鲺鲻鲼鲽鳃鳄鳅鳆鳇鳊鳋鳌鳍鳎鳏鳐鳓鳔鳕鳖鳗鳘鳙鳜鳝鳞鳟鳢鸟鸠鸡鸢鸣鸥鸦鸨鸩鸪鸫鸬鸭鸯鸱鸲鸳鸵鸶鸷鸸鸹鸺鸽鸾鸿鹁 -鹂鹃鹄鹅鹆鹇鹈鹉鹊鹋鹌鹎鹏鹑鹕鹗鹘鹚鹛鹜鹞鹣鹤鹦鹧鹨鹩鹪鹫鹬鹭鹰鹱鹳鹾鹿麂麇麈麋麒麓麝麟麦麴麸麻麽麾黄黉黍黎黏黑黔默黛黜黝黟黠黢 -黥黧黩黪黯黹黻黼黾鼋鼍鼎鼐鼓鼗鼙鼠鼢鼬鼯鼷鼹鼻鼽鼾齄齐齑齿龀龃龄龅龆龇龈龉龊龋龌龙龚龛龟龠 diff --git a/packs/zh-Hans/fonts/zh-hans-cjk/manifest.ini b/packs/zh-Hans/fonts/zh-hans-cjk/manifest.ini deleted file mode 100644 index a4e9fdd4..00000000 --- a/packs/zh-Hans/fonts/zh-hans-cjk/manifest.ini +++ /dev/null @@ -1,8 +0,0 @@ -kind=font -id=zh-hans-cjk -display_name=Simplified Chinese CJK -usage=both -estimated_ram_bytes=476075 -source=binfont -file=font.bin -ranges=ranges.txt diff --git a/packs/zh-Hans/fonts/zh-hans-cjk/ranges.txt b/packs/zh-Hans/fonts/zh-hans-cjk/ranges.txt deleted file mode 100644 index 682b5711..00000000 --- a/packs/zh-Hans/fonts/zh-hans-cjk/ranges.txt +++ /dev/null @@ -1 +0,0 @@ -0xB0,0x3002,0x4E00-0x4E01,0x4E03,0x4E07-0x4E0E,0x4E10-0x4E11,0x4E13-0x4E16,0x4E18-0x4E1E,0x4E22,0x4E24-0x4E25,0x4E27-0x4E28,0x4E2A-0x4E2D,0x4E30,0x4E32,0x4E34,0x4E36,0x4E38-0x4E3B,0x4E3D-0x4E3F,0x4E43,0x4E45,0x4E47-0x4E49,0x4E4B-0x4E50,0x4E52-0x4E54,0x4E56,0x4E58-0x4E59,0x4E5C-0x4E61,0x4E66,0x4E69,0x4E70-0x4E71,0x4E73,0x4E7E,0x4E86,0x4E88-0x4E89,0x4E8B-0x4E8F,0x4E91-0x4E95,0x4E98,0x4E9A-0x4E9B,0x4E9F-0x4EA2,0x4EA4-0x4EA9,0x4EAB-0x4EAE,0x4EB2-0x4EB3,0x4EB5,0x4EBA-0x4EBB,0x4EBF-0x4EC7,0x4EC9-0x4ECB,0x4ECD-0x4ECE,0x4ED1,0x4ED3-0x4ED9,0x4EDD-0x4EDF,0x4EE1,0x4EE3-0x4EE5,0x4EE8,0x4EEA-0x4EEC,0x4EF0,0x4EF2-0x4EF3,0x4EF5-0x4EF7,0x4EFB,0x4EFD,0x4EFF,0x4F01,0x4F09-0x4F0A,0x4F0D-0x4F11,0x4F17-0x4F1B,0x4F1E-0x4F20,0x4F22,0x4F24-0x4F27,0x4F2A-0x4F2B,0x4F2F-0x4F30,0x4F32,0x4F34,0x4F36,0x4F38,0x4F3A,0x4F3C-0x4F3D,0x4F43,0x4F46,0x4F4D-0x4F51,0x4F53,0x4F55,0x4F57-0x4F60,0x4F63-0x4F65,0x4F67,0x4F69,0x4F6C,0x4F6F-0x4F70,0x4F73-0x4F74,0x4F76,0x4F7B-0x4F7C,0x4F7E-0x4F7F,0x4F83-0x4F84,0x4F88-0x4F89,0x4F8B,0x4F8D,0x4F8F,0x4F91,0x4F94,0x4F97,0x4F9B,0x4F9D,0x4FA0,0x4FA3,0x4FA5-0x4FAA,0x4FAC,0x4FAE-0x4FAF,0x4FB5,0x4FBF,0x4FC3-0x4FC5,0x4FCA,0x4FCE-0x4FD1,0x4FD7-0x4FD8,0x4FDA,0x4FDC-0x4FDF,0x4FE1,0x4FE3,0x4FE6,0x4FE8-0x4FEA,0x4FED-0x4FEF,0x4FF1,0x4FF3,0x4FF8,0x4FFA,0x4FFE,0x500C-0x500D,0x500F,0x5012,0x5014,0x5018-0x501A,0x501C,0x501F,0x5021,0x5025-0x5026,0x5028-0x502A,0x502C-0x502E,0x503A,0x503C,0x503E,0x5043,0x5047-0x5048,0x504C,0x504E-0x504F,0x5055,0x505A,0x505C,0x5065,0x506C,0x5076-0x5077,0x507B,0x507E-0x5080,0x5085,0x5088,0x508D,0x50A3,0x50A5,0x50A7-0x50A9,0x50AC,0x50B2,0x50BA-0x50BB,0x50CF,0x50D6,0x50DA,0x50E6-0x50E7,0x50EC-0x50EE,0x50F3,0x50F5,0x50FB,0x5106-0x5107,0x510B,0x5112,0x5121,0x513F-0x5141,0x5143-0x5146,0x5148-0x5149,0x514B,0x514D,0x5151,0x5154-0x5156,0x515A,0x515C,0x5162,0x5165,0x5168,0x516B-0x516E,0x5170-0x5171,0x5173-0x5179,0x517B-0x517D,0x5180-0x5182,0x5185,0x5188-0x5189,0x518C-0x518D,0x5192,0x5195-0x5197,0x5199,0x519B-0x519C,0x51A0,0x51A2,0x51A4-0x51A5,0x51AB-0x51AC,0x51AF-0x51B3,0x51B5-0x51B7,0x51BB-0x51BD,0x51C0,0x51C4,0x51C6-0x51C7,0x51C9,0x51CB-0x51CC,0x51CF,0x51D1,0x51DB,0x51DD,0x51E0-0x51E1,0x51E4,0x51EB,0x51ED,0x51EF-0x51F0,0x51F3,0x51F5-0x51F6,0x51F8-0x51FD,0x51FF-0x5203,0x5206-0x5208,0x520A,0x520D-0x520E,0x5211-0x5212,0x5216-0x521B,0x521D,0x5220,0x5224,0x5228-0x5229,0x522B,0x522D-0x522E,0x5230,0x5233,0x5236-0x523B,0x523D,0x523F-0x5243,0x524A,0x524C-0x524D,0x5250-0x5251,0x5254,0x5256,0x525C,0x525E,0x5261,0x5265,0x5267,0x5269-0x526A,0x526F,0x5272,0x527D,0x527F,0x5281-0x5282,0x5288,0x5290,0x5293,0x529B,0x529D-0x52A3,0x52A8-0x52AD,0x52B1-0x52B3,0x52BE-0x52BF,0x52C3,0x52C7,0x52C9,0x52CB,0x52D0,0x52D2,0x52D6,0x52D8,0x52DF,0x52E4,0x52F0,0x52F9-0x52FA,0x52FE-0x5300,0x5305-0x5306,0x5308,0x530D,0x530F-0x5310,0x5315-0x5317,0x5319-0x531A,0x531D,0x5320-0x5321,0x5323,0x5326,0x532A,0x532E,0x5339-0x533B,0x533E-0x533F,0x5341,0x5343,0x5345,0x5347-0x534A,0x534E-0x534F,0x5351-0x5353,0x5355-0x5357,0x535A,0x535C,0x535E-0x5364,0x5366-0x5367,0x5369,0x536B,0x536E-0x5371,0x5373-0x5375,0x5377-0x5378,0x537A,0x537F,0x5382,0x5384-0x5386,0x5389,0x538B-0x538D,0x5395,0x5398,0x539A,0x539D,0x539F,0x53A2-0x53A3,0x53A5-0x53A6,0x53A8-0x53A9,0x53AE,0x53B6,0x53BB,0x53BF,0x53C1-0x53C2,0x53C8-0x53CD,0x53D1,0x53D4,0x53D6-0x53D9,0x53DB,0x53DF-0x53E0,0x53E3-0x53E6,0x53E8-0x53F3,0x53F5-0x53F9,0x53FB-0x53FD,0x5401,0x5403-0x5404,0x5406,0x5408-0x540A,0x540C-0x5413,0x5415-0x5417,0x541B,0x541D-0x5421,0x5423,0x5426-0x5429,0x542B-0x542F,0x5431-0x5432,0x5434-0x5435,0x5438-0x5439,0x543B-0x543C,0x543E,0x5440,0x5443,0x5446,0x5448,0x544A-0x544B,0x5450,0x5452-0x5459,0x545B-0x545C,0x5462,0x5464,0x5466,0x5468,0x5471-0x5473,0x5475-0x5478,0x547B-0x547D,0x5480,0x5482,0x5484,0x5486,0x548B-0x548C,0x548E-0x5490,0x5492,0x5494-0x5496,0x5499-0x549B,0x549D,0x54A3-0x54A4,0x54A6-0x54AD,0x54AF,0x54B1,0x54B3-0x54B4,0x54B8,0x54BB,0x54BD,0x54BF-0x54C2,0x54C4,0x54C6-0x54C9,0x54CC-0x54D5,0x54D7,0x54D9-0x54DA,0x54DC-0x54DF,0x54E5-0x54EA,0x54ED-0x54EE,0x54F2-0x54F3,0x54FA,0x54FC-0x54FD,0x54FF,0x5501,0x5506-0x5507,0x5509,0x550F-0x5511,0x5514,0x551B,0x5520,0x5522-0x5524,0x5527,0x552A,0x552C,0x552E-0x5531,0x5533,0x5537,0x553C,0x553E-0x553F,0x5541,0x5543-0x5544,0x5546,0x5549-0x554A,0x5550,0x5555-0x5556,0x555C,0x5561,0x5564-0x5567,0x556A,0x556C-0x556E,0x5575-0x5578,0x557B-0x557C,0x557E,0x5580-0x5584,0x5587-0x558B,0x558F,0x5591,0x5594,0x5598-0x5599,0x559C-0x559D,0x559F,0x55A7,0x55B1,0x55B3,0x55B5,0x55B7,0x55B9,0x55BB,0x55BD-0x55BE,0x55C4-0x55C5,0x55C9,0x55CC-0x55CD,0x55D1-0x55D4,0x55D6,0x55DC-0x55DD,0x55DF,0x55E1,0x55E3-0x55E6,0x55E8,0x55EA-0x55EC,0x55EF,0x55F2-0x55F3,0x55F5,0x55F7,0x55FD-0x55FE,0x5600-0x5601,0x5608-0x5609,0x560C,0x560E-0x560F,0x5618,0x561B,0x561E-0x561F,0x5623-0x5624,0x5627,0x562C-0x562D,0x5631-0x5632,0x5634,0x5636,0x5639,0x563B,0x563F,0x564C-0x564E,0x5654,0x5657-0x5659,0x565C,0x5662,0x5664,0x5668-0x566C,0x5671,0x5676,0x567B-0x567C,0x5685-0x5686,0x568E-0x568F,0x5693,0x56A3,0x56AF,0x56B7,0x56BC,0x56CA,0x56D4,0x56D7,0x56DA-0x56DB,0x56DD-0x56E2,0x56E4,0x56EB,0x56ED,0x56F0-0x56F1,0x56F4-0x56F5,0x56F9-0x56FA,0x56FD-0x56FF,0x5703-0x5704,0x5706,0x5708-0x570A,0x571C,0x571F,0x5723,0x5728-0x572A,0x572C-0x5730,0x5733,0x5739-0x573B,0x573E,0x5740,0x5742,0x5747,0x574A,0x574C-0x5751,0x5757,0x575A-0x5761,0x5764,0x5766,0x5768-0x576B,0x576D,0x576F,0x5773,0x5776-0x5777,0x577B-0x577C,0x5782-0x5786,0x578B-0x578C,0x5792-0x5793,0x579B,0x57A0-0x57A4,0x57A6-0x57A7,0x57A9,0x57AB,0x57AD-0x57AE,0x57B2,0x57B4,0x57B8,0x57C2-0x57C3,0x57CB,0x57CE-0x57CF,0x57D2,0x57D4-0x57D5,0x57D8-0x57DA,0x57DD,0x57DF-0x57E0,0x57E4,0x57ED,0x57EF,0x57F4,0x57F8-0x57FA,0x57FD,0x5800,0x5802,0x5806-0x5807,0x580B,0x580D,0x5811,0x5815,0x5819,0x581E,0x5820-0x5821,0x5824,0x582A,0x5830,0x5835,0x5844,0x584C-0x584D,0x5851,0x5854,0x5858,0x585E,0x5865,0x586B-0x586C,0x587E,0x5880-0x5881,0x5883,0x5885,0x5889,0x5892-0x5893,0x5899-0x589A,0x589E-0x589F,0x58A8-0x58A9,0x58BC,0x58C1,0x58C5,0x58D1,0x58D5,0x58E4,0x58EB-0x58EC,0x58EE,0x58F0,0x58F3,0x58F6,0x58F9,0x5902,0x5904,0x5907,0x590D,0x590F,0x5914-0x5916,0x5919-0x591A,0x591C,0x591F,0x5924-0x5925,0x5927,0x5929-0x592B,0x592D-0x592F,0x5931,0x5934,0x5937-0x593A,0x593C,0x5941-0x5942,0x5944,0x5947-0x5949,0x594B,0x594E-0x594F,0x5951,0x5954-0x5958,0x595A,0x5960,0x5962,0x5965,0x5973-0x5974,0x5976,0x5978-0x5979,0x597D,0x5981-0x5984,0x5986-0x5988,0x598A,0x598D,0x5992-0x5993,0x5996-0x5997,0x5999,0x599E,0x59A3-0x59A5,0x59A8-0x59AB,0x59AE-0x59AF,0x59B2,0x59B9,0x59BB,0x59BE,0x59C6,0x59CA-0x59CB,0x59D0-0x59D4,0x59D7-0x59D8,0x59DA,0x59DC-0x59DD,0x59E3,0x59E5,0x59E8,0x59EC,0x59F9,0x59FB,0x59FF,0x5A01,0x5A03-0x5A09,0x5A0C,0x5A11,0x5A13,0x5A18,0x5A1C,0x5A1F-0x5A20,0x5A23,0x5A25,0x5A29,0x5A31-0x5A32,0x5A34,0x5A36,0x5A3C,0x5A40,0x5A46,0x5A49-0x5A4A,0x5A55,0x5A5A,0x5A62,0x5A67,0x5A6A,0x5A74-0x5A77,0x5A7A,0x5A7F,0x5A92,0x5A9A-0x5A9B,0x5AAA,0x5AB2-0x5AB3,0x5AB5,0x5AB8,0x5ABE,0x5AC1-0x5AC2,0x5AC9,0x5ACC,0x5AD2,0x5AD4,0x5AD6,0x5AD8,0x5ADC,0x5AE0-0x5AE1,0x5AE3,0x5AE6,0x5AE9,0x5AEB,0x5AF1,0x5B09,0x5B16-0x5B17,0x5B32,0x5B34,0x5B37,0x5B40,0x5B50-0x5B51,0x5B53-0x5B55,0x5B57-0x5B5D,0x5B5F,0x5B62-0x5B66,0x5B69-0x5B6A,0x5B6C,0x5B70-0x5B71,0x5B73,0x5B75,0x5B7A,0x5B7D,0x5B80-0x5B81,0x5B83-0x5B85,0x5B87-0x5B89,0x5B8B-0x5B8C,0x5B8F,0x5B93,0x5B95,0x5B97-0x5B9E,0x5BA0-0x5BA6,0x5BAA-0x5BAB,0x5BB0,0x5BB3-0x5BB6,0x5BB8-0x5BB9,0x5BBD-0x5BBF,0x5BC2,0x5BC4-0x5BC7,0x5BCC,0x5BD0,0x5BD2-0x5BD3,0x5BDD-0x5BDF,0x5BE1,0x5BE4-0x5BE5,0x5BE8,0x5BEE,0x5BF0,0x5BF8-0x5BFC,0x5BFF,0x5C01,0x5C04,0x5C06,0x5C09-0x5C0A,0x5C0F,0x5C11,0x5C14-0x5C16,0x5C18,0x5C1A,0x5C1C-0x5C1D,0x5C22,0x5C24-0x5C25,0x5C27,0x5C2C,0x5C31,0x5C34,0x5C38-0x5C42,0x5C45,0x5C48-0x5C4B,0x5C4E-0x5C51,0x5C55,0x5C59,0x5C5E,0x5C60-0x5C61,0x5C63,0x5C65-0x5C66,0x5C6E-0x5C6F,0x5C71,0x5C79-0x5C7A,0x5C7F,0x5C81-0x5C82,0x5C88,0x5C8C-0x5C8D,0x5C90-0x5C91,0x5C94,0x5C96-0x5C9C,0x5CA2-0x5CA3,0x5CA9,0x5CAB-0x5CAD,0x5CB1,0x5CB3,0x5CB5,0x5CB7-0x5CB8,0x5CBD,0x5CBF,0x5CC1,0x5CC4,0x5CCB,0x5CD2,0x5CD9,0x5CE1,0x5CE4-0x5CE6,0x5CE8,0x5CEA,0x5CED,0x5CF0,0x5CFB,0x5D02-0x5D03,0x5D06-0x5D07,0x5D0E,0x5D14,0x5D16,0x5D1B,0x5D1E,0x5D24,0x5D26-0x5D27,0x5D29,0x5D2D-0x5D2E,0x5D34,0x5D3D-0x5D3E,0x5D47,0x5D4A-0x5D4C,0x5D58,0x5D5B,0x5D5D,0x5D69,0x5D6B-0x5D6C,0x5D6F,0x5D74,0x5D82,0x5D99,0x5D9D,0x5DB7,0x5DC5,0x5DCD,0x5DDB,0x5DDD-0x5DDE,0x5DE1-0x5DE2,0x5DE5-0x5DE9,0x5DEB,0x5DEE-0x5DEF,0x5DF1-0x5DF4,0x5DF7,0x5DFD-0x5DFE,0x5E01-0x5E03,0x5E05-0x5E06,0x5E08,0x5E0C,0x5E0F-0x5E11,0x5E14-0x5E16,0x5E18-0x5E1D,0x5E26-0x5E27,0x5E2D-0x5E2E,0x5E31,0x5E37-0x5E38,0x5E3B-0x5E3D,0x5E42,0x5E44-0x5E45,0x5E4C,0x5E54-0x5E55,0x5E5B,0x5E5E,0x5E61-0x5E62,0x5E72-0x5E74,0x5E76,0x5E78,0x5E7A-0x5E7D,0x5E7F-0x5E80,0x5E84,0x5E86-0x5E87,0x5E8A-0x5E8B,0x5E8F-0x5E91,0x5E93-0x5E97,0x5E99-0x5E9A,0x5E9C,0x5E9E-0x5EA0,0x5EA5-0x5EA7,0x5EAD,0x5EB3,0x5EB5-0x5EB9,0x5EBE,0x5EC9-0x5ECA,0x5ED1-0x5ED3,0x5ED6,0x5EDB,0x5EE8,0x5EEA,0x5EF4,0x5EF6-0x5EF7,0x5EFA,0x5EFE-0x5F04,0x5F08,0x5F0A-0x5F0B,0x5F0F,0x5F11,0x5F13,0x5F15,0x5F17-0x5F18,0x5F1B,0x5F1F-0x5F20,0x5F25-0x5F27,0x5F29-0x5F2A,0x5F2D,0x5F2F,0x5F31,0x5F39-0x5F3A,0x5F3C,0x5F40,0x5F50,0x5F52-0x5F53,0x5F55-0x5F58,0x5F5D,0x5F61-0x5F62,0x5F64,0x5F66,0x5F69-0x5F6A,0x5F6C-0x5F6D,0x5F70-0x5F71,0x5F73,0x5F77,0x5F79,0x5F7B-0x5F7C,0x5F80-0x5F82,0x5F84-0x5F85,0x5F87-0x5F8C,0x5F90,0x5F92,0x5F95,0x5F97-0x5F99,0x5F9C,0x5FA1,0x5FA8,0x5FAA,0x5FAD-0x5FAE,0x5FB5,0x5FB7,0x5FBC-0x5FBD,0x5FC3-0x5FC6,0x5FC9,0x5FCC-0x5FCD,0x5FCF-0x5FD2,0x5FD6-0x5FD9,0x5FDD,0x5FE0-0x5FE1,0x5FE4,0x5FE7,0x5FEA-0x5FEB,0x5FED-0x5FEE,0x5FF1,0x5FF5,0x5FF8,0x5FFB,0x5FFD-0x6006,0x600A,0x600D-0x600F,0x6012,0x6014-0x6016,0x6019,0x601B-0x601D,0x6020-0x6021,0x6025-0x602B,0x602F,0x6035,0x603B-0x603C,0x603F,0x6041-0x6043,0x604B,0x604D,0x6050,0x6052,0x6055,0x6059-0x605A,0x605D,0x6062-0x6064,0x6067-0x606D,0x606F-0x6070,0x6073,0x6076,0x6078-0x607D,0x607F,0x6083-0x6084,0x6089,0x608C-0x608D,0x6092,0x6094,0x6096,0x609A-0x609B,0x609D,0x609F-0x60A0,0x60A3,0x60A6,0x60A8,0x60AB-0x60AD,0x60AF,0x60B1-0x60B2,0x60B4,0x60B8,0x60BB-0x60BC,0x60C5-0x60C6,0x60CA-0x60CB,0x60D1,0x60D5,0x60D8,0x60DA,0x60DC-0x60DD,0x60DF-0x60E0,0x60E6-0x60E9,0x60EB-0x60F0,0x60F3-0x60F4,0x60F6,0x60F9-0x60FA,0x6100-0x6101,0x6106,0x6108-0x6109,0x610D-0x610F,0x6115,0x611A,0x611F-0x6120,0x6123-0x6124,0x6126-0x6127,0x612B,0x613F,0x6148,0x614A,0x614C,0x614E,0x6151,0x6155,0x615D,0x6162,0x6167-0x6168,0x6170,0x6175,0x6177,0x618B,0x618E,0x6194,0x619D,0x61A7-0x61A9,0x61AC,0x61B7,0x61BE,0x61C2,0x61C8,0x61CA-0x61CB,0x61D1-0x61D2,0x61D4,0x61E6,0x61F5,0x61FF,0x6206,0x6208,0x620A-0x6212,0x6215-0x6218,0x621A-0x621B,0x621F,0x6221-0x6222,0x6224-0x6225,0x622A,0x622C,0x622E,0x6233-0x6234,0x6237,0x623D-0x6241,0x6243,0x6247-0x6249,0x624B-0x624E,0x6251-0x6254,0x6258,0x625B,0x6263,0x6266-0x6267,0x6269-0x6270,0x6273,0x6276,0x6279,0x627C,0x627E-0x6280,0x6284,0x6289-0x628A,0x6291-0x6293,0x6295-0x6298,0x629A-0x629B,0x629F-0x62A2,0x62A4-0x62A5,0x62A8,0x62AB-0x62AC,0x62B1,0x62B5,0x62B9,0x62BB-0x62BD,0x62BF,0x62C2,0x62C4-0x62CA,0x62CC-0x62CE,0x62D0,0x62D2-0x62D4,0x62D6-0x62DC,0x62DF,0x62E2-0x62E3,0x62E5-0x62E9,0x62EC-0x62EF,0x62F1,0x62F3-0x62F4,0x62F6-0x62F7,0x62FC-0x62FF,0x6301-0x6302,0x6307-0x6309,0x630E,0x6311,0x6316,0x631A-0x631B,0x631D-0x6325,0x6328,0x632A-0x632B,0x632F,0x6332,0x6339-0x633A,0x633D,0x6342-0x6343,0x6345-0x6346,0x6349,0x634B-0x6350,0x6355,0x635E-0x635F,0x6361-0x6363,0x6367,0x6369,0x636D-0x636E,0x6371,0x6376-0x6377,0x637A-0x637B,0x6380,0x6382,0x6387-0x638A,0x638C,0x638E-0x6390,0x6392,0x6396,0x6398,0x63A0,0x63A2-0x63A3,0x63A5,0x63A7-0x63AA,0x63AC-0x63AE,0x63B0,0x63B3-0x63B4,0x63B7-0x63B8,0x63BA,0x63BC,0x63BE,0x63C4,0x63C6,0x63C9,0x63CD-0x63D0,0x63D2,0x63D6,0x63DE,0x63E0-0x63E1,0x63E3,0x63E9-0x63EA,0x63ED,0x63F2,0x63F4,0x63F6,0x63F8,0x63FD,0x63FF-0x6402,0x6405,0x640B-0x640C,0x640F-0x6410,0x6413-0x6414,0x641B-0x641C,0x641E,0x6420-0x6421,0x6426,0x642A,0x642C-0x642D,0x6434,0x643A,0x643D,0x643F,0x6441,0x6444-0x6448,0x644A,0x6452,0x6454,0x6458,0x645E,0x6467,0x6469,0x646D,0x6478-0x647A,0x6482,0x6484-0x6485,0x6487,0x6491-0x6492,0x6495-0x6496,0x6499,0x649E,0x64A4,0x64A9,0x64AC-0x64AE,0x64B0,0x64B5,0x64B7-0x64B8,0x64BA,0x64BC,0x64C0,0x64C2,0x64C5,0x64CD-0x64CE,0x64D0,0x64D2,0x64D7-0x64D8,0x64DE,0x64E2,0x64E4,0x64E6,0x6500,0x6509,0x6512,0x6518,0x6525,0x652B,0x652E-0x652F,0x6534-0x6536,0x6538-0x6539,0x653B,0x653E-0x653F,0x6545,0x6548-0x6549,0x654C,0x654F,0x6551,0x6555-0x6556,0x6559,0x655B,0x655D-0x655E,0x6562-0x6563,0x6566,0x656B-0x656C,0x6570,0x6572,0x6574,0x6577,0x6587,0x658B-0x658C,0x6590-0x6591,0x6593,0x6597,0x6599,0x659B-0x659C,0x659F,0x65A1,0x65A4-0x65A5,0x65A7,0x65A9,0x65AB,0x65AD,0x65AF-0x65B0,0x65B9,0x65BC-0x65BD,0x65C1,0x65C3-0x65C6,0x65CB-0x65CC,0x65CE-0x65CF,0x65D2,0x65D6-0x65D7,0x65E0,0x65E2,0x65E5-0x65E9,0x65EC-0x65F1,0x65F6-0x65F7,0x65FA,0x6600,0x6602-0x6603,0x6606,0x660A,0x660C,0x660E-0x660F,0x6613-0x6615,0x6619,0x661D,0x661F-0x6620,0x6625,0x6627-0x6628,0x662D,0x662F,0x6631,0x6634-0x6636,0x663C,0x663E,0x6641,0x6643,0x664B-0x664C,0x664F,0x6652-0x6657,0x665A,0x665F,0x6661,0x6664,0x6666,0x6668,0x666E-0x6670,0x6674,0x6676-0x6677,0x667A,0x667E,0x6682,0x6684,0x6687,0x668C,0x6691,0x6696-0x6697,0x669D,0x66A7-0x66A8,0x66AE,0x66B4,0x66B9,0x66BE,0x66D9,0x66DB-0x66DD,0x66E6,0x66E9,0x66F0,0x66F2-0x66F4,0x66F7,0x66F9,0x66FC,0x66FE-0x6700,0x6708-0x670B,0x670D,0x6710,0x6714-0x6715,0x6717,0x671B,0x671D,0x671F,0x6726,0x6728,0x672A-0x672D,0x672F,0x6731,0x6734-0x6735,0x673A,0x673D,0x6740,0x6742-0x6743,0x6746,0x6748-0x6749,0x674C,0x674E-0x6751,0x6753,0x6756,0x675C,0x675E-0x6761,0x6765,0x6768-0x676A,0x676D,0x676F-0x6770,0x6772-0x6773,0x6775,0x6777,0x677C,0x677E-0x677F,0x6781,0x6784,0x6787,0x6789,0x678B,0x6790,0x6795,0x6797-0x6798,0x679A,0x679C-0x679E,0x67A2-0x67A3,0x67A5,0x67A7-0x67A8,0x67AA-0x67AB,0x67AD,0x67AF-0x67B0,0x67B3,0x67B5-0x67B8,0x67C1,0x67C3-0x67C4,0x67CF-0x67D4,0x67D8-0x67DA,0x67DC-0x67DE,0x67E0,0x67E2,0x67E5,0x67E9,0x67EC,0x67EF-0x67F1,0x67F3-0x67F4,0x67FD,0x67FF-0x6800,0x6805,0x6807-0x680C,0x680E-0x680F,0x6811,0x6813,0x6816-0x6817,0x681D,0x6821,0x6829-0x682A,0x6832-0x6833,0x6837-0x6839,0x683C-0x683E,0x6840-0x6846,0x6848-0x684A,0x684C,0x684E,0x6850-0x6851,0x6853-0x6855,0x6860-0x6869,0x686B,0x6874,0x6876-0x6877,0x6881,0x6883,0x6885-0x6886,0x688F,0x6893,0x6897,0x68A2,0x68A6-0x68A8,0x68AD,0x68AF-0x68B0,0x68B3,0x68B5,0x68C0,0x68C2,0x68C9,0x68CB,0x68CD,0x68D2,0x68D5,0x68D8,0x68DA,0x68E0,0x68E3,0x68EE,0x68F0-0x68F1,0x68F5,0x68F9-0x68FA,0x68FC,0x6901,0x6905,0x690B,0x690D-0x690E,0x6910,0x6912,0x691F-0x6920,0x6924,0x692D,0x6930,0x6934,0x6939,0x693D,0x693F,0x6942,0x6954,0x6957,0x695A,0x695D-0x695E,0x6960,0x6963,0x6966,0x696B,0x696E,0x6971,0x6977-0x6979,0x697C,0x6980,0x6982,0x6984,0x6986-0x6989,0x698D,0x6994-0x6995,0x6998,0x699B-0x699C,0x69A7-0x69A8,0x69AB,0x69AD,0x69B1,0x69B4,0x69B7,0x69BB,0x69C1,0x69CA,0x69CC,0x69CE,0x69D0,0x69D4,0x69DB,0x69DF-0x69E0,0x69ED,0x69F2,0x69FD,0x69FF,0x6A0A,0x6A17-0x6A18,0x6A1F,0x6A21,0x6A28,0x6A2A,0x6A2F,0x6A31,0x6A35,0x6A3D-0x6A3E,0x6A44,0x6A47,0x6A50,0x6A58-0x6A59,0x6A5B,0x6A61,0x6A65,0x6A71,0x6A79,0x6A7C,0x6A80,0x6A84,0x6A8E,0x6A90-0x6A91,0x6A97,0x6AA0,0x6AA9,0x6AAB-0x6AAC,0x6B20-0x6B24,0x6B27,0x6B32,0x6B37,0x6B39-0x6B3A,0x6B3E,0x6B43,0x6B46-0x6B47,0x6B49,0x6B4C,0x6B59,0x6B62-0x6B67,0x6B6A,0x6B79,0x6B7B-0x6B7C,0x6B81-0x6B84,0x6B86-0x6B87,0x6B89-0x6B8B,0x6B8D,0x6B92-0x6B93,0x6B96,0x6B9A-0x6B9B,0x6BA1,0x6BAA,0x6BB3-0x6BB5,0x6BB7,0x6BBF,0x6BC1-0x6BC2,0x6BC5,0x6BCB,0x6BCD,0x6BCF,0x6BD2-0x6BD7,0x6BD9,0x6BDB,0x6BE1,0x6BEA-0x6BEB,0x6BEF,0x6BF3,0x6BF5,0x6BF9,0x6BFD,0x6C05-0x6C07,0x6C0D,0x6C0F-0x6C11,0x6C13-0x6C16,0x6C18-0x6C1B,0x6C1F,0x6C21-0x6C22,0x6C24,0x6C26-0x6C2A,0x6C2E-0x6C30,0x6C32,0x6C34-0x6C35,0x6C38,0x6C3D,0x6C40-0x6C42,0x6C46-0x6C47,0x6C49-0x6C4A,0x6C50,0x6C54-0x6C55,0x6C57,0x6C5B-0x6C61,0x6C64,0x6C68-0x6C6A,0x6C70,0x6C72,0x6C74,0x6C76,0x6C79,0x6C7D-0x6C7E,0x6C81-0x6C83,0x6C85-0x6C86,0x6C88-0x6C89,0x6C8C,0x6C8F-0x6C90,0x6C93-0x6C94,0x6C99,0x6C9B,0x6C9F,0x6CA1,0x6CA3-0x6CA7,0x6CA9-0x6CAB,0x6CAD-0x6CAE,0x6CB1-0x6CB3,0x6CB8-0x6CB9,0x6CBB-0x6CBF,0x6CC4-0x6CC5,0x6CC9-0x6CCA,0x6CCC,0x6CD0,0x6CD3-0x6CD7,0x6CDB,0x6CDE,0x6CE0-0x6CE3,0x6CE5,0x6CE8,0x6CEA-0x6CEB,0x6CEE-0x6CF1,0x6CF3,0x6CF5-0x6CF8,0x6CFA-0x6CFE,0x6D01,0x6D04,0x6D07,0x6D0B-0x6D0C,0x6D0E,0x6D12,0x6D17,0x6D19-0x6D1B,0x6D1E,0x6D25,0x6D27,0x6D2A-0x6D2B,0x6D2E,0x6D31-0x6D33,0x6D35,0x6D39,0x6D3B-0x6D3E,0x6D41,0x6D43,0x6D45-0x6D48,0x6D4A-0x6D4B,0x6D4D-0x6D4F,0x6D51-0x6D54,0x6D59-0x6D5A,0x6D5C,0x6D5E,0x6D60,0x6D63,0x6D66,0x6D69-0x6D6A,0x6D6E-0x6D6F,0x6D74,0x6D77-0x6D78,0x6D7C,0x6D82,0x6D85,0x6D88-0x6D89,0x6D8C,0x6D8E,0x6D91,0x6D93-0x6D95,0x6D9B,0x6D9D-0x6DA1,0x6DA3-0x6DA4,0x6DA6-0x6DAB,0x6DAE-0x6DAF,0x6DB2,0x6DB5,0x6DB8,0x6DBF-0x6DC0,0x6DC4-0x6DC7,0x6DCB-0x6DCC,0x6DD1,0x6DD6,0x6DD8-0x6DD9,0x6DDD-0x6DDE,0x6DE0-0x6DE1,0x6DE4,0x6DE6,0x6DEB-0x6DEC,0x6DEE,0x6DF1,0x6DF3,0x6DF7,0x6DF9,0x6DFB-0x6DFC,0x6E05,0x6E0A,0x6E0C-0x6E0E,0x6E10-0x6E11,0x6E14,0x6E16-0x6E17,0x6E1A,0x6E1D,0x6E20-0x6E21,0x6E23-0x6E25,0x6E29,0x6E2B,0x6E2D,0x6E2F,0x6E32,0x6E34,0x6E38,0x6E3A,0x6E43-0x6E44,0x6E4D-0x6E4E,0x6E53-0x6E54,0x6E56,0x6E58,0x6E5B,0x6E5F,0x6E6B,0x6E6E,0x6E7E-0x6E7F,0x6E83,0x6E85-0x6E86,0x6E89,0x6E8F-0x6E90,0x6E98,0x6E9C,0x6E9F,0x6EA2,0x6EA5,0x6EA7,0x6EAA,0x6EAF,0x6EB1-0x6EB2,0x6EB4,0x6EB6-0x6EB7,0x6EBA-0x6EBB,0x6EBD,0x6EC1-0x6EC2,0x6EC7,0x6ECB,0x6ECF,0x6ED1,0x6ED3-0x6ED5,0x6ED7,0x6EDA,0x6EDE-0x6EE2,0x6EE4-0x6EE6,0x6EE8-0x6EE9,0x6EF4,0x6EF9,0x6F02,0x6F06,0x6F09,0x6F0F,0x6F13-0x6F15,0x6F20,0x6F24,0x6F29-0x6F2B,0x6F2D,0x6F2F,0x6F31,0x6F33,0x6F36,0x6F3E,0x6F46-0x6F47,0x6F4B,0x6F4D,0x6F58,0x6F5C,0x6F5E,0x6F62,0x6F66,0x6F6D-0x6F6E,0x6F72,0x6F74,0x6F78,0x6F7A,0x6F7C,0x6F84,0x6F88-0x6F89,0x6F8C-0x6F8E,0x6F9C,0x6FA1,0x6FA7,0x6FB3,0x6FB6,0x6FB9,0x6FC0,0x6FC2,0x6FC9,0x6FD1-0x6FD2,0x6FDE,0x6FE0-0x6FE1,0x6FEE-0x6FEF,0x7011,0x701A-0x701B,0x7023,0x7035,0x7039,0x704C,0x704F,0x705E,0x706B-0x706D,0x706F-0x7070,0x7075-0x7076,0x7078,0x707C,0x707E-0x7080,0x7085,0x7089-0x708A,0x708E,0x7092,0x7094-0x7096,0x7099,0x709C-0x709D,0x70AB-0x70AF,0x70B1,0x70B3,0x70B7-0x70B9,0x70BB-0x70BD,0x70C0-0x70C3,0x70C8,0x70CA,0x70D8-0x70D9,0x70DB,0x70DF,0x70E4,0x70E6-0x70E9,0x70EB-0x70ED,0x70EF,0x70F7,0x70F9,0x70FD,0x7109-0x710A,0x7110,0x7113,0x7115-0x7116,0x7118-0x711A,0x7126,0x712F-0x7131,0x7136,0x7145,0x714A,0x714C,0x714E,0x715C,0x715E,0x7164,0x7166-0x7168,0x716E,0x7172-0x7173,0x7178,0x717A,0x717D,0x7184,0x718A,0x718F,0x7194,0x7198-0x7199,0x719F-0x71A0,0x71A8,0x71AC,0x71B3,0x71B5,0x71B9,0x71C3,0x71CE,0x71D4-0x71D5,0x71E0,0x71E5,0x71E7,0x71EE,0x71F9,0x7206,0x721D,0x7228,0x722A,0x722C,0x7230-0x7231,0x7235-0x7239,0x723B,0x723D,0x723F,0x7247-0x7248,0x724C-0x724D,0x7252,0x7256,0x7259,0x725B,0x725D,0x725F,0x7261-0x7262,0x7266-0x7267,0x7269,0x726E-0x726F,0x7272,0x7275,0x7279-0x727A,0x727E-0x7281,0x7284,0x728A-0x728B,0x728D,0x728F,0x7292,0x729F,0x72AC-0x72AD,0x72AF-0x72B0,0x72B4,0x72B6-0x72B9,0x72C1-0x72C4,0x72C8,0x72CD-0x72CE,0x72D0,0x72D2,0x72D7,0x72D9,0x72DE,0x72E0-0x72E1,0x72E8-0x72E9,0x72EC-0x72F4,0x72F7-0x72F8,0x72FA-0x72FC,0x7301,0x7303,0x730A,0x730E,0x7313,0x7315-0x7317,0x731B-0x731E,0x7321-0x7322,0x7325,0x7329-0x732C,0x732E,0x7331,0x7334,0x7337-0x7339,0x733E-0x733F,0x734D,0x7350,0x7352,0x7357,0x7360,0x736C-0x736D,0x736F,0x737E,0x7384,0x7387,0x7389,0x738B,0x738E,0x7391,0x7396,0x739B,0x739F,0x73A2,0x73A9,0x73AB,0x73AE-0x73B0,0x73B2-0x73B3,0x73B7,0x73BA-0x73BB,0x73C0,0x73C2,0x73C8-0x73CA,0x73CD,0x73CF-0x73D1,0x73D9,0x73DE,0x73E0,0x73E5,0x73E7,0x73E9,0x73ED,0x73F2,0x7403,0x7405-0x7406,0x7409-0x740A,0x740F-0x7410,0x741A-0x741B,0x7422,0x7425-0x7426,0x7428,0x742A,0x742C,0x742E,0x7430,0x7433-0x7436,0x743C,0x7441,0x7455,0x7457,0x7459-0x745C,0x745E-0x745F,0x746D,0x7470,0x7476-0x7477,0x747E,0x7480-0x7481,0x7483,0x7487,0x748B,0x748E,0x7490,0x749C,0x749E,0x74A7-0x74A9,0x74BA,0x74D2,0x74DC,0x74DE,0x74E0,0x74E2-0x74E4,0x74E6,0x74EE-0x74EF,0x74F4,0x74F6-0x74F7,0x74FF,0x7504,0x750D,0x750F,0x7511,0x7513,0x7518-0x751A,0x751C,0x751F,0x7525,0x7528-0x7529,0x752B-0x752D,0x752F-0x7533,0x7535,0x7537-0x7538,0x753A-0x753B,0x753E,0x7540,0x7545,0x7548,0x754B-0x754C,0x754E-0x754F,0x7554,0x7559-0x755C,0x7565-0x7566,0x756A,0x7572,0x7574,0x7578-0x7579,0x757F,0x7583,0x7586,0x758B,0x758F,0x7591-0x7592,0x7594,0x7596-0x7597,0x7599-0x759A,0x759D,0x759F-0x75A1,0x75A3-0x75A5,0x75AB-0x75AC,0x75AE-0x75B5,0x75B8-0x75B9,0x75BC-0x75BE,0x75C2-0x75C5,0x75C7-0x75CA,0x75CD,0x75D2,0x75D4-0x75D6,0x75D8,0x75DB,0x75DE,0x75E2-0x75E4,0x75E6-0x75E8,0x75EA-0x75EB,0x75F0-0x75F1,0x75F4,0x75F9,0x75FC,0x75FF-0x7601,0x7603,0x7605,0x760A,0x760C,0x7610,0x7615,0x7617-0x7619,0x761B,0x761F-0x7620,0x7622,0x7624-0x7626,0x7629-0x762B,0x762D,0x7630,0x7633-0x7635,0x7638,0x763C,0x763E-0x7640,0x7643,0x764C-0x764D,0x7654,0x7656,0x765C,0x765E,0x7663,0x766B,0x766F,0x7678,0x767B,0x767D-0x767E,0x7682,0x7684,0x7686-0x7688,0x768B,0x768E,0x7691,0x7693,0x7696,0x7699,0x76A4,0x76AE,0x76B1-0x76B2,0x76B4,0x76BF,0x76C2,0x76C5-0x76C6,0x76C8,0x76CA,0x76CD-0x76D2,0x76D4,0x76D6-0x76D8,0x76DB,0x76DF,0x76E5,0x76EE-0x76EF,0x76F1-0x76F2,0x76F4,0x76F8-0x76F9,0x76FC,0x76FE,0x7701,0x7704,0x7707-0x7709,0x770B,0x770D,0x7719-0x771A,0x771F-0x7720,0x7722,0x7726,0x7728-0x7729,0x772D,0x772F,0x7735-0x7738,0x773A,0x773C,0x7740-0x7741,0x7743,0x7747,0x7750-0x7751,0x775A-0x775B,0x7761-0x7763,0x7765-0x7766,0x7768,0x776B-0x776C,0x7779,0x777D-0x7780,0x7784-0x7785,0x778C-0x778E,0x7791-0x7792,0x779F-0x77A0,0x77A2,0x77A5,0x77A7,0x77A9-0x77AA,0x77AC,0x77B0,0x77B3,0x77B5,0x77BB,0x77BD,0x77BF,0x77CD,0x77D7,0x77DB-0x77DC,0x77E2-0x77E3,0x77E5,0x77E7,0x77E9,0x77EB-0x77EE,0x77F3,0x77F6,0x77F8,0x77FD-0x7802,0x7809,0x780C-0x780D,0x7811-0x7812,0x7814,0x7816-0x7818,0x781A,0x781C-0x781D,0x781F,0x7823,0x7825-0x7827,0x7829,0x782C-0x782D,0x7830,0x7834,0x7837-0x783C,0x783E,0x7840,0x7845,0x7847,0x784C,0x784E,0x7850,0x7852,0x7855-0x7857,0x785D,0x786A-0x786E,0x7877,0x787C,0x7887,0x7889,0x788C-0x788E,0x7891,0x7893,0x7897-0x7898,0x789A-0x789C,0x789F,0x78A1,0x78A3,0x78A5,0x78A7,0x78B0-0x78B4,0x78B9,0x78BE,0x78C1,0x78C5,0x78C9-0x78CB,0x78D0,0x78D4-0x78D5,0x78D9,0x78E8,0x78EC,0x78F2,0x78F4,0x78F7,0x78FA,0x7901,0x7905,0x7913,0x791E,0x7924,0x7934,0x793A-0x793C,0x793E,0x7940-0x7941,0x7946,0x7948-0x7949,0x7953,0x7956-0x7957,0x795A-0x7960,0x7962,0x7965,0x7967-0x7968,0x796D,0x796F,0x7977-0x7978,0x797A,0x7980-0x7981,0x7984-0x7985,0x798A,0x798F,0x799A,0x79A7,0x79B3,0x79B9-0x79BB,0x79BD-0x79BE,0x79C0-0x79C1,0x79C3,0x79C6,0x79C9,0x79CB,0x79CD,0x79D1-0x79D2,0x79D5,0x79D8,0x79DF,0x79E3-0x79E4,0x79E6-0x79E7,0x79E9,0x79EB,0x79ED,0x79EF-0x79F0,0x79F8,0x79FB,0x79FD,0x7A00,0x7A02-0x7A03,0x7A06,0x7A0B,0x7A0D-0x7A0E,0x7A14,0x7A17,0x7A1A,0x7A1E,0x7A20,0x7A23,0x7A33,0x7A37,0x7A39,0x7A3B-0x7A3D,0x7A3F,0x7A46,0x7A51,0x7A57,0x7A70,0x7A74,0x7A76-0x7A7A,0x7A7F-0x7A81,0x7A83-0x7A84,0x7A86,0x7A88,0x7A8D,0x7A91-0x7A92,0x7A95-0x7A98,0x7A9C-0x7A9D,0x7A9F-0x7AA0,0x7AA5-0x7AA6,0x7AA8,0x7AAC-0x7AAD,0x7AB3,0x7ABF,0x7ACB,0x7AD6,0x7AD9,0x7ADE-0x7AE0,0x7AE3,0x7AE5-0x7AE6,0x7AED,0x7AEF,0x7AF9-0x7AFA,0x7AFD,0x7AFF,0x7B03-0x7B04,0x7B06,0x7B08,0x7B0A-0x7B0B,0x7B0F,0x7B11,0x7B14-0x7B15,0x7B19,0x7B1B,0x7B1E,0x7B20,0x7B24-0x7B26,0x7B28,0x7B2A-0x7B2C,0x7B2E,0x7B31,0x7B33,0x7B38,0x7B3A,0x7B3C,0x7B3E,0x7B45,0x7B47,0x7B49,0x7B4B-0x7B4C,0x7B4F-0x7B52,0x7B54,0x7B56,0x7B58,0x7B5A-0x7B5B,0x7B5D,0x7B60,0x7B62,0x7B6E,0x7B71-0x7B72,0x7B75,0x7B77,0x7B79,0x7B7B,0x7B7E,0x7B80,0x7B85,0x7B8D,0x7B90,0x7B94-0x7B95,0x7B97,0x7B9C-0x7B9D,0x7BA1-0x7BA2,0x7BA6-0x7BAD,0x7BB1,0x7BB4,0x7BB8,0x7BC1,0x7BC6-0x7BC7,0x7BCC,0x7BD1,0x7BD3,0x7BD9-0x7BDA,0x7BDD,0x7BE1,0x7BE5-0x7BE6,0x7BEA,0x7BEE,0x7BF1,0x7BF7,0x7BFC,0x7BFE,0x7C07,0x7C0B-0x7C0C,0x7C0F,0x7C16,0x7C1F,0x7C26-0x7C27,0x7C2A,0x7C38,0x7C3F-0x7C41,0x7C4D,0x7C73-0x7C74,0x7C7B-0x7C7D,0x7C89,0x7C91-0x7C92,0x7C95,0x7C97-0x7C98,0x7C9C-0x7C9F,0x7CA2,0x7CA4-0x7CA5,0x7CAA,0x7CAE,0x7CB1-0x7CB3,0x7CB9,0x7CBC-0x7CBE,0x7CC1,0x7CC5,0x7CC7-0x7CC8,0x7CCA,0x7CCC-0x7CCD,0x7CD5-0x7CD7,0x7CD9,0x7CDC,0x7CDF-0x7CE0,0x7CE8,0x7CEF,0x7CF8,0x7CFB,0x7D0A,0x7D20,0x7D22,0x7D27,0x7D2B,0x7D2F,0x7D6E,0x7D77,0x7DA6,0x7DAE,0x7E3B,0x7E41,0x7E47,0x7E82,0x7E9B,0x7E9F-0x7EAD,0x7EAF-0x7EB3,0x7EB5-0x7EBA,0x7EBD-0x7ED5,0x7ED7-0x7EE3,0x7EE5-0x7EEB,0x7EED-0x7EF8,0x7EFA-0x7F09,0x7F0B-0x7F0F,0x7F11-0x7F1D,0x7F1F-0x7F36,0x7F38,0x7F3A,0x7F42,0x7F44-0x7F45,0x7F50-0x7F51,0x7F54-0x7F55,0x7F57-0x7F58,0x7F5A,0x7F5F,0x7F61-0x7F62,0x7F68-0x7F6A,0x7F6E,0x7F71-0x7F72,0x7F74,0x7F79,0x7F7E,0x7F81,0x7F8A,0x7F8C,0x7F8E,0x7F94,0x7F9A,0x7F9D-0x7F9F,0x7FA1,0x7FA4,0x7FA7,0x7FAF-0x7FB0,0x7FB2,0x7FB8-0x7FB9,0x7FBC-0x7FBD,0x7FBF,0x7FC1,0x7FC5,0x7FCA,0x7FCC,0x7FCE,0x7FD4-0x7FD5,0x7FD8,0x7FDF-0x7FE1,0x7FE5-0x7FE6,0x7FE9,0x7FEE,0x7FF0-0x7FF1,0x7FF3,0x7FFB-0x7FFC,0x8000-0x8001,0x8003-0x8006,0x800B-0x800D,0x8010,0x8012,0x8014-0x8019,0x801C,0x8020,0x8022,0x8025-0x802A,0x8031,0x8033,0x8035-0x8038,0x803B,0x803D,0x803F,0x8042-0x8043,0x8046,0x804A-0x804D,0x8052,0x8054,0x8058,0x805A,0x8069-0x806A,0x8071,0x807F-0x8080,0x8083-0x8084,0x8086-0x8087,0x8089,0x808B-0x808C,0x8093,0x8096,0x8098,0x809A-0x809D,0x809F-0x80A2,0x80A4-0x80A5,0x80A9-0x80AB,0x80AD-0x80AF,0x80B1-0x80B2,0x80B4,0x80B7,0x80BA,0x80BC-0x80C4,0x80C6,0x80CC-0x80CE,0x80D6-0x80D7,0x80D9-0x80DE,0x80E1,0x80E4-0x80E5,0x80E7-0x80ED,0x80EF-0x80F4,0x80F6,0x80F8,0x80FA,0x80FC-0x80FD,0x8102,0x8106,0x8109-0x810A,0x810D-0x8114,0x8116,0x8118,0x811A,0x811E,0x812C,0x812F,0x8131-0x8132,0x8136,0x8138,0x813E,0x8146,0x8148,0x814A-0x814C,0x8150-0x8151,0x8153-0x8155,0x8159-0x815A,0x8160,0x8165,0x8167,0x8169,0x816D-0x816E,0x8170-0x8171,0x8174,0x8179-0x8180,0x8182,0x8188,0x818A,0x818F,0x8191,0x8198,0x819B-0x819D,0x81A3,0x81A6,0x81A8,0x81AA,0x81B3,0x81BA-0x81BB,0x81C0-0x81C3,0x81C6,0x81CA,0x81CC,0x81E3,0x81E7,0x81EA,0x81EC-0x81ED,0x81F3-0x81F4,0x81FB-0x81FC,0x81FE,0x8200-0x8202,0x8204-0x8206,0x820C-0x820D,0x8210,0x8212,0x8214,0x821B-0x821C,0x821E-0x821F,0x8221-0x8223,0x8228,0x822A-0x822D,0x822F-0x8231,0x8233-0x8239,0x823B,0x823E,0x8244,0x8247,0x8249,0x824B,0x824F,0x8258,0x825A,0x825F,0x8268,0x826E-0x8270,0x8272-0x8274,0x8279-0x827A,0x827D-0x827F,0x8282,0x8284,0x8288,0x828A-0x828B,0x828D-0x828F,0x8291-0x8292,0x8297-0x8299,0x829C-0x829D,0x829F,0x82A1,0x82A4-0x82A6,0x82A8-0x82B1,0x82B3-0x82B4,0x82B7-0x82B9,0x82BD-0x82BE,0x82C1,0x82C4,0x82C7-0x82C8,0x82CA-0x82CF,0x82D1-0x82D5,0x82D7-0x82D8,0x82DB-0x82DC,0x82DE-0x82E1,0x82E3-0x82E6,0x82EB,0x82EF,0x82F1,0x82F4,0x82F7,0x82F9,0x82FB,0x8301-0x8309,0x830C,0x830E-0x830F,0x8311,0x8314-0x8315,0x8317,0x831A-0x831C,0x8327-0x8328,0x832B-0x832D,0x832F,0x8331,0x8333-0x8336,0x8338-0x833A,0x833C,0x8340,0x8343,0x8346-0x8347,0x8349,0x834F-0x8352,0x8354,0x835A-0x835C,0x835E-0x8361,0x8363-0x836F,0x8377-0x8378,0x837B-0x837D,0x8385-0x8386,0x8389,0x838E,0x8392-0x8393,0x8398,0x839B-0x839C,0x839E,0x83A0,0x83A8-0x83AB,0x83B0-0x83B4,0x83B6-0x83BA,0x83BC-0x83BD,0x83C0-0x83C1,0x83C5,0x83C7,0x83CA,0x83CC,0x83CF,0x83D4,0x83D6,0x83D8,0x83DC-0x83DD,0x83DF-0x83E1,0x83E5,0x83E9-0x83EA,0x83F0-0x83F2,0x83F8-0x83F9,0x83FD,0x8401,0x8403-0x8404,0x8406,0x840B-0x840F,0x8411,0x8418,0x841C-0x841D,0x8424-0x8428,0x8431,0x8438,0x843C-0x843D,0x8446,0x8451,0x8457,0x8459-0x845C,0x8461,0x8463,0x8469,0x846B-0x846D,0x8471,0x8473,0x8475-0x8476,0x8478,0x847A,0x8482,0x8487-0x8489,0x848B-0x848C,0x848E,0x8497,0x8499,0x849C,0x84A1,0x84AF,0x84B2,0x84B4,0x84B8-0x84BA,0x84BD,0x84BF,0x84C1,0x84C4,0x84C9-0x84CA,0x84CD,0x84D0-0x84D1,0x84D3,0x84D6,0x84DD,0x84DF-0x84E0,0x84E3,0x84E5-0x84E6,0x84EC,0x84F0,0x84FC,0x84FF,0x850C,0x8511,0x8513,0x8517,0x851A,0x851F,0x8521,0x852B-0x852C,0x8537-0x853D,0x8543,0x8548-0x854A,0x8556,0x8559,0x855E,0x8564,0x8568,0x8572,0x8574,0x8579-0x857B,0x857E,0x8584-0x8585,0x8587,0x858F,0x859B-0x859C,0x85A4,0x85A8,0x85AA,0x85AE-0x85B0,0x85B7,0x85B9,0x85C1,0x85C9,0x85CF-0x85D0,0x85D3,0x85D5,0x85DC,0x85E4,0x85E9,0x85FB,0x85FF,0x8605,0x8611,0x8616,0x8627,0x8629,0x8638,0x863C,0x864D-0x8651,0x8654,0x865A,0x865E,0x8662,0x866B-0x866C,0x866E,0x8671,0x8679-0x8682,0x868A-0x868D,0x8693,0x8695,0x869C-0x869D,0x86A3-0x86A4,0x86A7-0x86AA,0x86AC,0x86AF-0x86B1,0x86B4-0x86B6,0x86BA,0x86C0,0x86C4,0x86C6-0x86C7,0x86C9-0x86CB,0x86CE-0x86D1,0x86D4,0x86D8-0x86D9,0x86DB,0x86DE-0x86DF,0x86E4,0x86E9,0x86ED-0x86EE,0x86F0-0x86F4,0x86F8-0x86F9,0x86FE,0x8700,0x8702-0x8703,0x8707-0x870A,0x870D,0x8712-0x8713,0x8715,0x8717-0x8718,0x871A,0x871C,0x871E,0x8721-0x8723,0x8725,0x8729,0x872E,0x8731,0x8734,0x8737,0x873B,0x873E-0x873F,0x8747-0x8749,0x874C,0x874E,0x8753,0x8757,0x8759,0x8760,0x8763-0x8765,0x876E,0x8770,0x8774,0x8776,0x877B-0x877E,0x8782-0x8783,0x8785,0x8788,0x878B,0x878D,0x8793,0x8797,0x879F,0x87A8,0x87AB-0x87AD,0x87AF,0x87B3,0x87B5,0x87BA,0x87BD,0x87C0,0x87C6,0x87CA-0x87CB,0x87D1-0x87D3,0x87DB,0x87E0,0x87E5,0x87EA,0x87EE,0x87F9,0x87FE,0x8803,0x880A,0x8813,0x8815-0x8816,0x881B,0x8821-0x8822,0x8832,0x8839,0x883C,0x8840,0x8844-0x8845,0x884C-0x884D,0x8854,0x8857,0x8859,0x8861-0x8865,0x8868-0x8869,0x886B-0x886C,0x886E,0x8870,0x8872,0x8877,0x887D-0x887F,0x8881-0x8882,0x8884-0x8885,0x8888,0x888B,0x888D,0x8892,0x8896,0x889C,0x88A2,0x88A4,0x88AB,0x88AD,0x88B1,0x88B7,0x88BC,0x88C1-0x88C2,0x88C5-0x88C6,0x88C9,0x88CE,0x88D2,0x88D4-0x88D5,0x88D8-0x88D9,0x88DF,0x88E2-0x88E5,0x88E8,0x88F0-0x88F1,0x88F3-0x88F4,0x88F8-0x88F9,0x88FC,0x88FE,0x8902,0x890A,0x8910,0x8912-0x8913,0x8919-0x891B,0x8921,0x8925,0x892A-0x892B,0x8930,0x8934,0x8936,0x8941,0x8944,0x895E-0x895F,0x8966,0x897B,0x897F,0x8981,0x8983,0x8986,0x89C1-0x89C2,0x89C4-0x89CC,0x89CE-0x89D2,0x89D6,0x89DA,0x89DC,0x89DE,0x89E3,0x89E5-0x89E6,0x89EB,0x89EF,0x89F3,0x8A00,0x8A07,0x8A3E,0x8A48,0x8A79,0x8A89-0x8A8A,0x8A93,0x8B07,0x8B26,0x8B66,0x8B6C,0x8BA0-0x8BAB,0x8BAD-0x8BB0,0x8BB2-0x8BBA,0x8BBC-0x8BC6,0x8BC8-0x8BCF,0x8BD1-0x8BE9,0x8BEB-0x8C08,0x8C0A-0x8C1D,0x8C1F-0x8C37,0x8C41,0x8C46-0x8C47,0x8C49,0x8C4C,0x8C55,0x8C5A,0x8C61-0x8C62,0x8C6A-0x8C6B,0x8C73,0x8C78-0x8C7A,0x8C82,0x8C85,0x8C89-0x8C8A,0x8C8C,0x8C94,0x8C98,0x8D1D-0x8D1F,0x8D21-0x8D50,0x8D53-0x8D56,0x8D58-0x8D5E,0x8D60-0x8D64,0x8D66-0x8D67,0x8D6B,0x8D6D,0x8D70,0x8D73-0x8D77,0x8D81,0x8D84-0x8D85,0x8D8A-0x8D8B,0x8D91,0x8D94,0x8D9F,0x8DA3,0x8DB1,0x8DB3-0x8DB5,0x8DB8,0x8DBA,0x8DBC,0x8DBE-0x8DBF,0x8DC3-0x8DC4,0x8DC6,0x8DCB-0x8DCC,0x8DCE-0x8DCF,0x8DD1,0x8DD6-0x8DD7,0x8DDA-0x8DDB,0x8DDD-0x8DDF,0x8DE3-0x8DE4,0x8DE8,0x8DEA-0x8DEC,0x8DEF,0x8DF3,0x8DF5,0x8DF7-0x8DFB,0x8DFD,0x8E05,0x8E09-0x8E0A,0x8E0C,0x8E0F,0x8E14,0x8E1D-0x8E1F,0x8E22-0x8E23,0x8E29-0x8E2A,0x8E2C,0x8E2E-0x8E2F,0x8E31,0x8E35,0x8E39-0x8E3A,0x8E3D,0x8E40-0x8E42,0x8E44,0x8E47-0x8E4B,0x8E51-0x8E52,0x8E59,0x8E66,0x8E69,0x8E6C-0x8E6D,0x8E6F-0x8E70,0x8E72,0x8E74,0x8E76,0x8E7C,0x8E7F,0x8E81,0x8E85,0x8E87,0x8E8F-0x8E90,0x8E94,0x8E9C,0x8E9E,0x8EAB-0x8EAC,0x8EAF,0x8EB2,0x8EBA,0x8ECE,0x8F66-0x8F69,0x8F6B-0x8F7F,0x8F81-0x8F8B,0x8F8D-0x8F91,0x8F93-0x8F9C,0x8F9E-0x8F9F,0x8FA3,0x8FA8-0x8FA9,0x8FAB,0x8FB0-0x8FB1,0x8FB6,0x8FB9,0x8FBD-0x8FBE,0x8FC1-0x8FC2,0x8FC4-0x8FC5,0x8FC7-0x8FC8,0x8FCE,0x8FD0-0x8FD1,0x8FD3-0x8FD5,0x8FD8-0x8FD9,0x8FDB-0x8FDF,0x8FE2,0x8FE4-0x8FE6,0x8FE8-0x8FEB,0x8FED-0x8FEE,0x8FF0,0x8FF3,0x8FF7-0x8FF9,0x8FFD,0x9000-0x9006,0x9009-0x900B,0x900D,0x900F-0x9012,0x9014,0x9016-0x9017,0x901A-0x901B,0x901D-0x9022,0x9026,0x902D-0x902F,0x9035-0x9036,0x9038,0x903B-0x903C,0x903E,0x9041-0x9042,0x9044,0x9047,0x904D,0x904F-0x9053,0x9057-0x9058,0x905B,0x9062-0x9063,0x9065,0x9068,0x906D-0x906E,0x9074-0x9075,0x907D,0x907F-0x9080,0x9082-0x9083,0x9088,0x908B,0x9091,0x9093,0x9095,0x9097,0x9099,0x909B,0x909D,0x90A1-0x90A3,0x90A6,0x90AA,0x90AC,0x90AE-0x90B1,0x90B3-0x90B6,0x90B8-0x90BB,0x90BE,0x90C1,0x90C4-0x90C5,0x90C7,0x90CA,0x90CE-0x90D1,0x90D3,0x90D7,0x90DB-0x90DD,0x90E1-0x90E2,0x90E6-0x90E8,0x90EB,0x90ED,0x90EF,0x90F4,0x90F8,0x90FD-0x90FE,0x9102,0x9104,0x9119,0x911E,0x9122-0x9123,0x912F,0x9131,0x9139,0x9143,0x9146,0x9149-0x9150,0x9152,0x9157,0x915A,0x915D-0x915E,0x9161-0x9165,0x9169-0x916A,0x916C,0x916E-0x9172,0x9174-0x9179,0x917D-0x917F,0x9185,0x9187,0x9189,0x918B-0x918D,0x9190-0x9192,0x919A-0x919B,0x91A2-0x91A3,0x91AA,0x91AD-0x91AF,0x91B4-0x91B5,0x91BA,0x91C7,0x91C9-0x91CA,0x91CC-0x91CF,0x91D1,0x91DC,0x9274,0x928E,0x92AE,0x92C8,0x933E,0x936A,0x938F,0x93CA,0x93D6,0x943E,0x946B,0x9485-0x9490,0x9492-0x9495,0x9497,0x9499-0x94C6,0x94C8-0x94CE,0x94D0-0x94D2,0x94D5-0x94D9,0x94DB-0x94E5,0x94E7-0x94FA,0x94FC-0x951B,0x951D-0x951F,0x9521-0x9526,0x9528-0x9532,0x9534-0x953C,0x953E-0x9542,0x9544-0x9547,0x9549-0x954A,0x954C-0x9554,0x9556-0x9559,0x955B-0x955F,0x9561-0x956D,0x956F-0x9573,0x9576,0x957F,0x95E8-0x95EB,0x95ED-0x95FE,0x9600-0x9606,0x9608-0x9612,0x9614-0x9617,0x9619-0x961A,0x961C-0x961D,0x961F,0x9621-0x9622,0x962A,0x962E,0x9631-0x9636,0x963B-0x963D,0x963F-0x9640,0x9642,0x9644-0x9649,0x964B-0x964D,0x9650,0x9654-0x9655,0x965B,0x965F,0x9661-0x9662,0x9664,0x9667-0x966A,0x966C,0x9672,0x9674-0x9677,0x9685-0x9686,0x9688,0x968B,0x968D,0x968F-0x9690,0x9694,0x9697-0x9699,0x969C,0x96A7,0x96B0,0x96B3,0x96B6,0x96B9,0x96BC-0x96BE,0x96C0-0x96C1,0x96C4-0x96C7,0x96C9,0x96CC-0x96CF,0x96D2,0x96D5,0x96E0,0x96E8-0x96EA,0x96EF,0x96F3,0x96F6-0x96F7,0x96F9,0x96FE,0x9700-0x9701,0x9704,0x9706-0x9709,0x970D-0x970F,0x9713,0x9716,0x971C,0x971E,0x972A,0x972D,0x9730,0x9732,0x9738-0x9739,0x973E,0x9752-0x9753,0x9756,0x9759,0x975B,0x975E,0x9760-0x9762,0x9765,0x9769,0x9773-0x9774,0x9776,0x977C,0x9785,0x978B,0x978D,0x9791-0x9792,0x9794,0x9798,0x97A0,0x97A3,0x97AB,0x97AD,0x97AF,0x97B2,0x97B4,0x97E6-0x97E7,0x97E9-0x97ED,0x97F3,0x97F5-0x97F6,0x9875-0x988A,0x988C-0x988D,0x988F-0x9891,0x9893-0x9894,0x9896-0x9898,0x989A-0x98A2,0x98A4-0x98A7,0x98CE,0x98D1-0x98D3,0x98D5,0x98D8-0x98DA,0x98DE-0x98DF,0x98E7-0x98E8,0x990D,0x9910,0x992E,0x9954-0x9955,0x9963,0x9965,0x9967-0x9972,0x9974-0x9977,0x997A,0x997C-0x997D,0x997F-0x9981,0x9984-0x9988,0x998A-0x998B,0x998D,0x998F-0x9999,0x99A5,0x99A8,0x9A6C-0x9A71,0x9A73-0x9A82,0x9A84-0x9A88,0x9A8A-0x9A8C,0x9A8F-0x9A93,0x9A96-0x9A98,0x9A9A-0x9AA5,0x9AA7-0x9AA8,0x9AB0-0x9AB1,0x9AB6-0x9AB8,0x9ABA,0x9ABC,0x9AC0-0x9AC2,0x9AC5,0x9ACB-0x9ACC,0x9AD1,0x9AD3,0x9AD8,0x9ADF,0x9AE1,0x9AE6,0x9AEB,0x9AED,0x9AEF,0x9AF9,0x9AFB,0x9B03,0x9B08,0x9B0F,0x9B13,0x9B1F,0x9B23,0x9B2F,0x9B32,0x9B3B-0x9B3C,0x9B41-0x9B45,0x9B47-0x9B49,0x9B4D,0x9B4F,0x9B51,0x9B54,0x9C7C,0x9C7F,0x9C81-0x9C82,0x9C85-0x9C88,0x9C8B,0x9C8D-0x9C8E,0x9C90-0x9C92,0x9C94-0x9C95,0x9C9A-0x9C9C,0x9C9E-0x9CA9,0x9CAB,0x9CAD-0x9CAE,0x9CB0-0x9CB8,0x9CBA-0x9CBD,0x9CC3-0x9CC7,0x9CCA-0x9CD0,0x9CD3-0x9CD9,0x9CDC-0x9CDF,0x9CE2,0x9E1F-0x9E23,0x9E25-0x9E26,0x9E28-0x9E2D,0x9E2F,0x9E31-0x9E33,0x9E35-0x9E3A,0x9E3D-0x9E3F,0x9E41-0x9E4C,0x9E4E-0x9E4F,0x9E51,0x9E55,0x9E57-0x9E58,0x9E5A-0x9E5C,0x9E5E,0x9E63-0x9E64,0x9E66-0x9E6D,0x9E70-0x9E71,0x9E73,0x9E7E-0x9E7F,0x9E82,0x9E87-0x9E88,0x9E8B,0x9E92-0x9E93,0x9E9D,0x9E9F,0x9EA6,0x9EB4,0x9EB8,0x9EBB,0x9EBD-0x9EBE,0x9EC4,0x9EC9,0x9ECD-0x9ECF,0x9ED1,0x9ED4,0x9ED8,0x9EDB-0x9EDD,0x9EDF-0x9EE0,0x9EE2,0x9EE5,0x9EE7,0x9EE9-0x9EEA,0x9EEF,0x9EF9,0x9EFB-0x9EFC,0x9EFE,0x9F0B,0x9F0D-0x9F0E,0x9F10,0x9F13,0x9F17,0x9F19,0x9F20,0x9F22,0x9F2C,0x9F2F,0x9F37,0x9F39,0x9F3B,0x9F3D-0x9F3E,0x9F44,0x9F50-0x9F51,0x9F7F-0x9F80,0x9F83-0x9F8C,0x9F99-0x9F9B,0x9F9F-0x9FA0 diff --git a/packs/zh-Hans/fonts/zh-hans-cjk/.gitignore b/packs/zh-Hans/fonts/zh-hans-core/.gitignore similarity index 100% rename from packs/zh-Hans/fonts/zh-hans-cjk/.gitignore rename to packs/zh-Hans/fonts/zh-hans-core/.gitignore diff --git a/packs/zh-Hans/fonts/zh-hans-cjk/build.ini b/packs/zh-Hans/fonts/zh-hans-core/build.ini similarity index 51% rename from packs/zh-Hans/fonts/zh-hans-cjk/build.ini rename to packs/zh-Hans/fonts/zh-hans-core/build.ini index d0889975..c7d628c4 100644 --- a/packs/zh-Hans/fonts/zh-hans-cjk/build.ini +++ b/packs/zh-Hans/fonts/zh-hans-core/build.ini @@ -2,3 +2,5 @@ font=tools/fonts/NotoSansCJKsc-Regular.otf size=16 bpp=2 no_compress=true +ranked_chars_file=tools/pinyin_ranked_chars.txt +ranked_char_limit=3072 diff --git a/packs/zh-Hans/fonts/zh-hans-core/charset.txt b/packs/zh-Hans/fonts/zh-hans-core/charset.txt new file mode 100644 index 00000000..5a90e82c --- /dev/null +++ b/packs/zh-Hans/fonts/zh-hans-core/charset.txt @@ -0,0 +1,50 @@ +°。一丁七万丈三上下丌不与丑专且丘丙业丛东丞丢两严丧个中丰串临丹为主举丿乃久乇么义之乍乎乏乐乖乘乙乜九也书买乱乾了予争事二于亏云 +五亘亚些亟亡亢交亥产亨享京亭亮亲人什仁仂仅仆仇今介仍从仑仓仔他仡代令以们仰仳件价任份仿伉伍伎伐休众会伞传伤伦伧伯伴伺似伽佃但位低 +住体何佗余佚佛作佝你佧佩佬佰佳佴佻佼使侉例侏侔侗供侠侥侧侬侯侵便促俄俊俏俗保俞俟信俩修俸俺俾倍倒倘候倚倜倦倩倪倭债值假偈偌偏偕做 +停偬偶偷偻傀傍储催傲傻像僚僧僭僮儋儿允元兄充先光克免兑兔党入全八公六兰共关兴兵其具典兹养内冈冉册再冒写军农冠冥冬冯冰冲决况冷冻冼 +净准凑凝几凡凤凭凯凳凵凶凹出击凿刀分切刊划列刘则刚创初删判刨利别刮到刳制刷券刹刺刻削前剖剡剥剩副剽剿劐力劝办功加务劣动助努劲劳劾 +势勇勉勒勖勘募勤勺勾勿匀包匆匕化北匙匝匡匪匮匹区匿十千卅升半华协卑卒卓单卖南卜卞卟占卡卤卦卧卫卯印危即却卵卷厂厅压厕厘厚厝原厦厶 +去县叁参又及友双反发取受变叟叠口古句另叨叩只叫召叭可台叱右叶号司叹叻叽吁吃各合同名后向吓吖吗君吞吟吡否吧吨吩含听吭吮启吱吲吴吵吹 +吾呀呃呆呈告呐呒呔呕呗员呢周呱呲味呵呶呷呼命咀咋和咎咔咖咣咦咩咪咬咭咯咱咳咴咸咻咽哀品哆哇哈哌响哏哐哕哝哟哦哧哨哩哪哭哮哲哺哼哽 +唆唇唏唐唑唔唛唤唧唪唬售唰唷唼啁啃啄商啉啊啐啜啡啥啦啻喀喁喃善喇喈喉喊喋喏喔喘喙喜喝喟喳喷喽嗄嗌嗍嗑嗒嗓嗔嗖嗟嗡嗨嗯嗲嗽嘀嘁嘎嘏 +嘘嘞嘬嘲嘴嘿噌噍噎噢器噪噫噱噶噻嚓嚣嚯嚷嚼囊囔囗囚四囝回因囡团囤园困囱固国图圈圜土圣在圩圪地圳场圻圾均坎坏坐坑块坠坡坤坦坨坫坯坳 +坶坷坻垂垄垌垒垠垦垧垩垮垸埃埋城埏埔埝域埤埯培埽堂堆堇堋堕堡堤堪堵塄塌塔塘塞填境墅墙增墨壅壑壤壬壮声壳壹夂处备复夏夕外多夜够大天 +太夫夭央夯失头夸夹夺奇奈奉奋奏契奔奖套奘奠奥女奴奶奸她好妁如妃妆妈妖妗妙妞妮妯妹妾姆始姐姓姚姣姥姬娃娆娉娘娜娩娶婆婕婚婺媪媲媵嫂 +嫔嫖嫩嬗嬲嬷孀子孔字存孙孛孟学孩孱孽宁它宅守安宋完宓宕宗官定宛宝实客宣宪宰害家容宽宾宿密寇寒察寡寨寰寸对寺寻导封射将尉尊小少尔尚 +尝尢尥尬就尹尺尼尽尾尿层居屈屎屏展属屮屯山屹岁岂岈岑岗岛岸峒峙峤峦崆崇崎崔崛崤崩崴嵇嵊嵌嵯嶷巛川州巡巢工左巧巨差己已巳巴巷巽币市 +布帅希帐帑帔帕帖帘帝带帧帮帱常幅幕幢干平年并幸幺幼广庄庇床库应底店庙庚府庞废度座庭庳庵庶康廊廑廓廖延廷建开弁弄式引弘弟张弥弩弱弹 +强彀归当录彖彗彡形彦彩彪彬彭影彳彷彻往待很徊律後徒得徙御循徵德徼心必忍忏忐忑忒忖志忙忠忪快忮忱念忽忾怀态怍怎怒怕怙怛怜思怠急性怨 +怪怫怵总怼恁恂恃恍恐恒恝恢恨恩恫息恰恳恶恼恿悄悛悝患您悬悯悲情惆惊惝惠惨惭惰想惴惹愀愁愉愍意感愠愣愤愧愿慊慌慎慝慢慨慷憋憎憧憾懂 +懊懒懔戆戌戎戏成我戕或战戚戛戡戳戴户房所扁扃扇手才扎扑扒打扔托扛扣执扩扪扫扭扮扰扳扶批找承技抄把抓投抖抗折抛抟抠抡抢护报抨抬抱抵 +抹抻押抽拂担拆拈拉拊拌拍拎拐拓拔拖拗拘拚招拜拟拢拥拦拧择括拮拱拴拶拷拼拽拾拿持挂指挈按挎挑挖挛挝挟挠挡挥挪挫振挲挺捆捉捋捌捍捎捏 +捐损换捧捩捭据捶捷捻掀掇授掉掊掌掎排掘掠探接控推措掴掸掺掾揄揉揍描提插揖揞握揣揩揭揲援搂搋搓搛搜搞搡搬搭摁摇摔摧摩摺撅撇撒撕撖撙 +撞撤撩播撮撰撺擂操擐擒擗擘擞擦攉攒攘攥攮支收改攻放政故效敌敏救敕敖教敞敢散敦敫数整文斌斗料斜斡斥斩斫断斯新方於施旁旄旋族无既日旦 +旧早旬旮旰时昂昆昌明昏昔昕昙星映春昧昨是昵显晁晃晒晚晟晨普景暂暇暖暗暧暨暴曝曩曰曲更曷曹曼曾最月有朊朋服朐朔朗望朝期朦木未末本札 +术朱朴朵机杀杂权杉杌李材村杓杜杠条来杨杭杷杼松板构枇枉枋析枕林枘果枝枞枪枯架枸柁柏某柑染柔柙柚柜柞柠柢查柳柴柽栅标栎栏树栓栖栗栝 +校栩样核根格栾桁桂桃桅案桊桌桐桑桔桡档桥桧梁梅梏梗梢梦梧梭棉棋棍棒棣森棰棱棵棹椎椹椿楂楚楞楠楮楱楷楼概榜槁槌槐槛槟槭槽槿樘模横樽 +橐橙檀檐檗檠檫次欢欣欧欹款歃歇歙止正此步武歪歹死殁残殍殖殡段殷殿毁毋母每毒比毕毛毫毳毹氏氐民氓气氕氤水氵永氽汀汁求汇汉汕汗汝江池 +汤汩汪汶汽汾沂沃沆沈沉沌沏沓沙沟没沦沧沮沱河沸治沾泄泅泉泊泌泐泔法泖泛泞波泣泥注泪泫泯泰泵泷泺泽洁洇洋洒洗洚洛洞洪洫洮洲洵活洼洽 +派流浅测浍浑浒浓浚浜浩浪海浸涂涅消涉涌涎涑涓涔涞涡涣润涩涪涮液淋淌淑淖淙淠淡淦淫淬淮深淳混添清渑渠渥温渫港渴游湃湍湓湔湛湟湫湮湾 +溃溉溘溟溥溪溯溱溲溴溶溺滂滇滋滑滕滚满滨漂漆漏漕漫漯潘潜潢潦潭潮潼澄澉澍澡澳澶澹激濂濞濡濯瀑瀹灌火灬灭灯灰灵灾灿炅炊炎炔炕炖炮炯 +炸点烁烂烈烙烛烟烤烧热焉焖焘焦焯焱然煦照煨熄熊熙熟熨熬燃燔燠燥燹爆爝爨爪爬爱爷爸爹爻爽爿片版牌牙牛牟牢物特犄犍犒犯犴状狂狃狄狗狠 +狡独狻狼猎猓猗猛猫猴獠獬獾玄率王玟玢玩环现珍珞珩班珲球琅理琢琨琳琴琼瑗瑙瑞瑟瓒瓜瓠瓤瓦瓮瓶瓿甄甘甚甜生用甩甫甬甭田由甲电男甸町甾 +界留畚畜略番畸畹疋疑疒疔疗疙疟疮疴疵疸疹疼病痕痛痦痪瘕瘟瘥瘳瘵癌癞癸登白百的皇皋皓皖皤皮皴皿盅盆盍盎监盒盖盘盛盟目盯盲直相盹盼盾 +省眈看眙真眠眩眭眷眸眼着睃睇睡睢督睫睽睾睿瞀瞑瞠瞢瞥瞧瞪瞬瞵瞿矛矜矣知短石矸矿码砉砌砍研砖砝砟砥砩砬砰破砸硅硌硎硐硕硝硪硫硬确碌 +碎碟碡碣碰碱磁磅磉磷磺礤示社祁祈祓祖祝神祠祢票祭禁禅禳离秀私秋种科秒秘租秤秦积称秸移程稍税稞稠稷稹稽稿穑穰穴究穷穹空穿窀突窃窒窖 +窗窘窜窝窥窨窬立站竟章童端竺笋笏笑笤符笨第笮笼等筋筒答策筛筠筷筹简箐算管箢箬箴箸篇篡篦篾簇簪簿籁籍米籴类粉粗粘粢粥粮粹精糁糅糖糜 +糟糸系素索紧累絮綮繁繇纂纛红纤纥约级纯纱纲纳纵纶纷纽线练组细终绍经结绕给络绝统绢绣绪续绰绲绵综缀缉缎缏缓编缗缠缩缪缯缲缴缵缶缺网 +罗罚罢罪置罱美羞羡群羧羸羹羽翁翟翠翮翻老考者耆而耍耐耕耗耙耨耳耶耷耸聊聒联聘聪聱肃肄肆肉肋肜股肢肥肩肫肭肮肯育肷肺胂胆背胍胖胗胜 +胝胞胡胩胯胱胲胳胶胸胺能脉脏脑脓脔脘脚脞脯脱脸脾腊腌腔腧腮腱腾腿膀膊膘膦膪膻臂臣臧自臭至致臾舂舄舌舍舒舔舜舡航般舱舳船艘艟艮良色 +艴艽艾艿节芋芍芎芒芘芟芤芥芦芩芪芫芭芮花芳芴芾苍苏苑苒苓苕苗苛苞苣苤若苦苫苯英苴苹苻茁范茄茇茈茑茛茜茧茫茬茭茶荃草荑荒荛荠荡荣荤 +荥荨药荼荽莆莉莎莘莜莞莠莨莩莫莱获莽菀菅菌菏菜菥菩菲菸菹菽萁萆萌萑营萨落著葚葜葡董葬葭葱葶蒋蒙蒜蒡蒯蒲蒽蒿蓁蓉蓊蓑蓝蓼蓿蔑蔓蔚蔟 +蔡蔫蔽蕃蕈蕉蕊蕞蕹蕺薄薛薜藉藏藐藤藿蘖蘧虐虑虫虹虽虾蚌蚕蚝蚣蚤蚰蚴蚵蚺蛆蛇蛑蛙蛞蛤蛩蛮蛸蛾蜍蜒蜓蜕蜚蜡蜩蜮蜱蜴蜷蜻蜾蝎蝙蝤蝥蝶螃 +螅融螫蟀蟆蟊蟒蟠蠃蠖蠛蠡蠢蠼血行衙衡补表衮衰衿袂袅袍袒袖袜袢袤被袷袼裁裂装裒裙裢裨裳裴裼褊褚褥褪褶西要覃见观规视览觉角觖觜解觳言 +訇詹誊计订认讨让训议讯记讲讷许论讼设访证评识诈诉词诏试诘话该语误诰说诵诶请诹诺读课谁调谆谈谋谍谑谜谠谢谬谮谱谷豁豆豉豚象豪豫豳豸 +豺貉貊貌贝财责败贫购贰贲贴贵贸费贼贾赃资赉赏赖赚赛赞赠赦赫走赶起趁趄超越趑趟趣足趵趼趿跃跋跌跑跛距跞跟跣跤跨跫跬路跳踅踉踔踢踣踩 +踪踱踹蹂蹄蹊蹦蹭蹲蹴蹶蹿躁躅躇躔身躲躺车轧轨转轮软轰轴载较辇辍辏辑输辗辛辞辟辣辨辩辰边辽达迁迅过迎运近返还这进远连迟迤迥迦迩迫迭 +迮述迷迹追退送适逃逄逆选逊透逐途逗通逛逞速造逡逢逮逯逾遁遂遇遍道遗遣遭遵遽邋邑邓邛邢那邦邪邹邺邻郄郅郇郎郗郝郡郢部郭郴都鄱鄹配酐 +酒酡酢酪酬酮酷酸酾酿醇醉醋醒醛醮采里重野量金銮鏖鑫针钏钔钗钞钟钢钥钦钭钮钯钱钻钿铁铅铊铛铣铤铥铪铫铭银铺铽链铿销锁锊锐锕错锤锬键 +锻镇镐镖镡镦长门闩闪闭问闯闰闲间闵闷闹闻闽阏阔阙阚队阢阮防阳阵阻阽阿陀陂附陆陇陈陋降限陕陟院除险陪陬陴陵陶隆隋随隐隔隗隘隧隰隶隹 +隼隽难雀雄雅集雇雉雩雪零雷需震霍霜霰露霸霾青靓静非靠靡面革鞋鞔鞘鞠鞣鞫鞴韩音页顶顺须顿颂预领颇颈颉颌频颗题额颠颡颤风飒飘飞食飧餐 +餮饧饭饶饿馁馆馇馈馓馕首馗馘馥马驮骀骂骇验骗骚骠骰骱骸髁髂髋高髟髯髻鬓鬲鬻鬼魁魂魄鲁鲅鲑鲧鲭鳃鸟鸣鸾鸿鹄鹏鹘麇麟麦麻麽黄黑黝黧黹 +黾鼎齐龈龙龟 diff --git a/packs/zh-Hans/fonts/zh-hans-core/manifest.ini b/packs/zh-Hans/fonts/zh-hans-core/manifest.ini new file mode 100644 index 00000000..3fac3787 --- /dev/null +++ b/packs/zh-Hans/fonts/zh-hans-core/manifest.ini @@ -0,0 +1,8 @@ +kind=font +id=zh-hans-core +display_name=Simplified Chinese Core +usage=both +estimated_ram_bytes=217456 +source=binfont +file=font.bin +ranges=ranges.txt diff --git a/packs/zh-Hans/fonts/zh-hans-core/ranges.txt b/packs/zh-Hans/fonts/zh-hans-core/ranges.txt new file mode 100644 index 00000000..f8bd4ceb --- /dev/null +++ b/packs/zh-Hans/fonts/zh-hans-core/ranges.txt @@ -0,0 +1 @@ +0xB0,0x3002,0x4E00-0x4E01,0x4E03,0x4E07-0x4E0E,0x4E11,0x4E13-0x4E14,0x4E18-0x4E1C,0x4E1E,0x4E22,0x4E24-0x4E25,0x4E27,0x4E2A,0x4E2D,0x4E30,0x4E32,0x4E34,0x4E39-0x4E3B,0x4E3E-0x4E3F,0x4E43,0x4E45,0x4E47-0x4E49,0x4E4B,0x4E4D-0x4E50,0x4E56,0x4E58-0x4E59,0x4E5C-0x4E5D,0x4E5F,0x4E66,0x4E70-0x4E71,0x4E7E,0x4E86,0x4E88-0x4E89,0x4E8B-0x4E8C,0x4E8E-0x4E8F,0x4E91,0x4E94,0x4E98,0x4E9A-0x4E9B,0x4E9F,0x4EA1-0x4EA2,0x4EA4-0x4EA5,0x4EA7-0x4EA8,0x4EAB-0x4EAE,0x4EB2,0x4EBA,0x4EC0-0x4EC2,0x4EC5-0x4EC7,0x4ECA-0x4ECB,0x4ECD-0x4ECE,0x4ED1,0x4ED3-0x4ED4,0x4ED6,0x4EE1,0x4EE3-0x4EE5,0x4EEC,0x4EF0,0x4EF3,0x4EF6-0x4EF7,0x4EFB,0x4EFD,0x4EFF,0x4F09,0x4F0D-0x4F0E,0x4F10-0x4F11,0x4F17,0x4F1A,0x4F1E,0x4F20,0x4F24,0x4F26-0x4F27,0x4F2F,0x4F34,0x4F3A,0x4F3C-0x4F3D,0x4F43,0x4F46,0x4F4D-0x4F4F,0x4F53,0x4F55,0x4F57,0x4F59-0x4F5D,0x4F60,0x4F67,0x4F69,0x4F6C,0x4F70,0x4F73-0x4F74,0x4F7B-0x4F7C,0x4F7F,0x4F89,0x4F8B,0x4F8F,0x4F94,0x4F97,0x4F9B,0x4FA0,0x4FA5,0x4FA7,0x4FAC,0x4FAF,0x4FB5,0x4FBF,0x4FC3-0x4FC4,0x4FCA,0x4FCF,0x4FD7,0x4FDD-0x4FDF,0x4FE1,0x4FE9,0x4FEE,0x4FF8,0x4FFA,0x4FFE,0x500D,0x5012,0x5018-0x501A,0x501C,0x5026,0x5029-0x502A,0x502D,0x503A,0x503C,0x5047-0x5048,0x504C,0x504F,0x5055,0x505A,0x505C,0x506C,0x5076-0x5077,0x507B,0x5080,0x508D,0x50A8,0x50AC,0x50B2,0x50BB,0x50CF,0x50DA,0x50E7,0x50ED-0x50EE,0x510B,0x513F,0x5141,0x5143-0x5145,0x5148-0x5149,0x514B,0x514D,0x5151,0x5154,0x515A,0x5165,0x5168,0x516B-0x516D,0x5170-0x5171,0x5173-0x5179,0x517B,0x5185,0x5188-0x5189,0x518C-0x518D,0x5192,0x5199,0x519B-0x519C,0x51A0,0x51A5,0x51AC,0x51AF-0x51B0,0x51B2-0x51B3,0x51B5,0x51B7,0x51BB-0x51BC,0x51C0,0x51C6,0x51D1,0x51DD,0x51E0-0x51E1,0x51E4,0x51ED,0x51EF,0x51F3,0x51F5-0x51F6,0x51F9-0x51FB,0x51FF-0x5200,0x5206-0x5207,0x520A,0x5212,0x5217-0x521B,0x521D,0x5220,0x5224,0x5228-0x5229,0x522B,0x522E,0x5230,0x5233,0x5236-0x523B,0x524A,0x524D,0x5256,0x5261,0x5265,0x5269,0x526F,0x527D,0x527F,0x5290,0x529B,0x529D-0x52A1,0x52A3,0x52A8-0x52AA,0x52B2-0x52B3,0x52BE-0x52BF,0x52C7,0x52C9,0x52D2,0x52D6,0x52D8,0x52DF,0x52E4,0x52FA,0x52FE-0x5300,0x5305-0x5306,0x5315-0x5317,0x5319,0x531D,0x5321,0x532A,0x532E,0x5339-0x533A,0x533F,0x5341,0x5343,0x5345,0x5347,0x534A,0x534E-0x534F,0x5351-0x5353,0x5355-0x5357,0x535C,0x535E-0x5361,0x5364,0x5366-0x5367,0x536B,0x536F-0x5371,0x5373-0x5375,0x5377,0x5382,0x5385,0x538B,0x5395,0x5398,0x539A,0x539D,0x539F,0x53A6,0x53B6,0x53BB,0x53BF,0x53C1-0x53C2,0x53C8,0x53CA-0x53CD,0x53D1,0x53D6-0x53D8,0x53DF-0x53E0,0x53E3-0x53E6,0x53E8-0x53ED,0x53EF-0x53F1,0x53F3,0x53F6-0x53F9,0x53FB,0x53FD,0x5401,0x5403-0x5404,0x5408,0x540C-0x540E,0x5411,0x5413,0x5416-0x5417,0x541B,0x541E-0x541F,0x5421,0x5426-0x5429,0x542B-0x542F,0x5431-0x5432,0x5434-0x5435,0x5439,0x543E,0x5440,0x5443,0x5446,0x5448,0x544A,0x5450,0x5452,0x5454-0x5455,0x5457-0x5458,0x5462,0x5468,0x5471-0x5473,0x5475-0x5477,0x547C-0x547D,0x5480,0x548B-0x548C,0x548E,0x5494,0x5496,0x54A3,0x54A6,0x54A9-0x54AA,0x54AC-0x54AD,0x54AF,0x54B1,0x54B3-0x54B4,0x54B8,0x54BB,0x54BD,0x54C0-0x54C1,0x54C6-0x54C8,0x54CC-0x54CD,0x54CF-0x54D0,0x54D5,0x54DD,0x54DF,0x54E6-0x54EA,0x54ED-0x54EE,0x54F2,0x54FA,0x54FC-0x54FD,0x5506-0x5507,0x550F-0x5511,0x5514,0x551B,0x5524,0x5527,0x552A,0x552C,0x552E,0x5530,0x5537,0x553C,0x5541,0x5543-0x5544,0x5546,0x5549-0x554A,0x5550,0x555C,0x5561,0x5565-0x5566,0x557B,0x5580-0x5581,0x5583-0x5584,0x5587-0x558B,0x558F,0x5594,0x5598-0x5599,0x559C-0x559D,0x559F,0x55B3,0x55B7,0x55BD,0x55C4,0x55CC-0x55CD,0x55D1-0x55D4,0x55D6,0x55DF,0x55E1,0x55E8,0x55EF,0x55F2,0x55FD,0x5600-0x5601,0x560E-0x560F,0x5618,0x561E,0x562C,0x5632,0x5634,0x563F,0x564C-0x564E,0x5662,0x5668,0x566A-0x566B,0x5671,0x5676,0x567B,0x5693,0x56A3,0x56AF,0x56B7,0x56BC,0x56CA,0x56D4,0x56D7,0x56DA-0x56DB,0x56DD-0x56DE,0x56E0-0x56E2,0x56E4,0x56ED,0x56F0-0x56F1,0x56FA,0x56FD-0x56FE,0x5708,0x571C,0x571F,0x5723,0x5728-0x572A,0x5730,0x5733,0x573A-0x573B,0x573E,0x5747,0x574E-0x5751,0x5757,0x5760-0x5761,0x5764,0x5766,0x5768,0x576B,0x576F,0x5773,0x5776-0x5777,0x577B,0x5782,0x5784,0x578C,0x5792,0x57A0,0x57A6-0x57A7,0x57A9,0x57AE,0x57B8,0x57C3,0x57CB,0x57CE-0x57CF,0x57D4,0x57DD,0x57DF,0x57E4,0x57EF,0x57F9,0x57FD,0x5802,0x5806-0x5807,0x580B,0x5815,0x5821,0x5824,0x582A,0x5835,0x5844,0x584C,0x5854,0x5858,0x585E,0x586B,0x5883,0x5885,0x5899,0x589E,0x58A8,0x58C5,0x58D1,0x58E4,0x58EC,0x58EE,0x58F0,0x58F3,0x58F9,0x5902,0x5904,0x5907,0x590D,0x590F,0x5915-0x5916,0x591A,0x591C,0x591F,0x5927,0x5929-0x592B,0x592D-0x592F,0x5931,0x5934,0x5938-0x593A,0x5947-0x5949,0x594B,0x594F,0x5951,0x5954,0x5956-0x5958,0x5960,0x5965,0x5973-0x5974,0x5976,0x5978-0x5979,0x597D,0x5981-0x5983,0x5986,0x5988,0x5996-0x5997,0x5999,0x599E,0x59AE-0x59AF,0x59B9,0x59BE,0x59C6,0x59CB,0x59D0,0x59D3,0x59DA,0x59E3,0x59E5,0x59EC,0x5A03,0x5A06,0x5A09,0x5A18,0x5A1C,0x5A29,0x5A36,0x5A46,0x5A55,0x5A5A,0x5A7A,0x5AAA,0x5AB2,0x5AB5,0x5AC2,0x5AD4,0x5AD6,0x5AE9,0x5B17,0x5B32,0x5B37,0x5B40,0x5B50,0x5B54,0x5B57-0x5B59,0x5B5B,0x5B5F,0x5B66,0x5B69,0x5B71,0x5B7D,0x5B81,0x5B83,0x5B85,0x5B88-0x5B89,0x5B8B-0x5B8C,0x5B93,0x5B95,0x5B97-0x5B98,0x5B9A-0x5B9B,0x5B9D-0x5B9E,0x5BA2-0x5BA3,0x5BAA,0x5BB0,0x5BB3,0x5BB6,0x5BB9,0x5BBD-0x5BBF,0x5BC6-0x5BC7,0x5BD2,0x5BDF,0x5BE1,0x5BE8,0x5BF0,0x5BF8-0x5BFC,0x5C01,0x5C04,0x5C06,0x5C09-0x5C0A,0x5C0F,0x5C11,0x5C14,0x5C1A,0x5C1D,0x5C22,0x5C25,0x5C2C,0x5C31,0x5C39-0x5C3A,0x5C3C-0x5C3F,0x5C42,0x5C45,0x5C48,0x5C4E-0x5C4F,0x5C55,0x5C5E,0x5C6E-0x5C6F,0x5C71,0x5C79,0x5C81-0x5C82,0x5C88,0x5C91,0x5C97,0x5C9B,0x5CB8,0x5CD2,0x5CD9,0x5CE4,0x5CE6,0x5D06-0x5D07,0x5D0E,0x5D14,0x5D1B,0x5D24,0x5D29,0x5D34,0x5D47,0x5D4A,0x5D4C,0x5D6F,0x5DB7,0x5DDB,0x5DDD-0x5DDE,0x5DE1-0x5DE2,0x5DE5-0x5DE8,0x5DEE,0x5DF1-0x5DF4,0x5DF7,0x5DFD,0x5E01-0x5E03,0x5E05,0x5E0C,0x5E10-0x5E11,0x5E14-0x5E16,0x5E18,0x5E1D,0x5E26-0x5E27,0x5E2E,0x5E31,0x5E38,0x5E45,0x5E55,0x5E62,0x5E72-0x5E74,0x5E76,0x5E78,0x5E7A,0x5E7C,0x5E7F,0x5E84,0x5E87,0x5E8A,0x5E93-0x5E95,0x5E97,0x5E99-0x5E9A,0x5E9C,0x5E9E-0x5E9F,0x5EA6-0x5EA7,0x5EAD,0x5EB3,0x5EB5-0x5EB7,0x5ECA,0x5ED1,0x5ED3,0x5ED6,0x5EF6-0x5EF7,0x5EFA,0x5F00-0x5F01,0x5F04,0x5F0F,0x5F15,0x5F18,0x5F1F-0x5F20,0x5F25,0x5F29,0x5F31,0x5F39-0x5F3A,0x5F40,0x5F52-0x5F53,0x5F55-0x5F57,0x5F61-0x5F62,0x5F66,0x5F69-0x5F6A,0x5F6C-0x5F6D,0x5F71,0x5F73,0x5F77,0x5F7B,0x5F80,0x5F85,0x5F88,0x5F8A-0x5F8C,0x5F92,0x5F97,0x5F99,0x5FA1,0x5FAA,0x5FB5,0x5FB7,0x5FBC,0x5FC3,0x5FC5,0x5FCD,0x5FCF-0x5FD2,0x5FD6-0x5FD7,0x5FD9,0x5FE0,0x5FEA-0x5FEB,0x5FEE,0x5FF1,0x5FF5,0x5FFD-0x5FFE,0x6000-0x6001,0x600D-0x600E,0x6012,0x6015,0x6019,0x601B-0x601D,0x6020,0x6025,0x6027-0x6028,0x602A-0x602B,0x6035,0x603B-0x603C,0x6041-0x6043,0x604D,0x6050,0x6052,0x605D,0x6062,0x6068-0x6069,0x606B,0x606F-0x6070,0x6073,0x6076,0x607C,0x607F,0x6084,0x609B,0x609D,0x60A3,0x60A8,0x60AC,0x60AF,0x60B2,0x60C5-0x60C6,0x60CA,0x60DD,0x60E0,0x60E8,0x60ED,0x60F0,0x60F3-0x60F4,0x60F9,0x6100-0x6101,0x6109,0x610D,0x610F,0x611F-0x6120,0x6123-0x6124,0x6127,0x613F,0x614A,0x614C,0x614E,0x615D,0x6162,0x6168,0x6177,0x618B,0x618E,0x61A7,0x61BE,0x61C2,0x61CA,0x61D2,0x61D4,0x6206,0x620C,0x620E-0x6211,0x6215-0x6216,0x6218,0x621A-0x621B,0x6221,0x6233-0x6234,0x6237,0x623F-0x6241,0x6243,0x6247,0x624B,0x624D-0x624E,0x6251-0x6254,0x6258,0x625B,0x6263,0x6267,0x6269-0x626B,0x626D-0x626E,0x6270,0x6273,0x6276,0x6279,0x627E-0x6280,0x6284,0x628A,0x6293,0x6295-0x6298,0x629B,0x629F-0x62A2,0x62A4-0x62A5,0x62A8,0x62AC,0x62B1,0x62B5,0x62B9,0x62BB-0x62BD,0x62C2,0x62C5-0x62C6,0x62C8-0x62CA,0x62CC-0x62CE,0x62D0,0x62D3-0x62D4,0x62D6-0x62D8,0x62DA-0x62DC,0x62DF,0x62E2,0x62E5-0x62E7,0x62E9,0x62EC,0x62EE,0x62F1,0x62F4,0x62F6-0x62F7,0x62FC-0x62FF,0x6301-0x6302,0x6307-0x6309,0x630E,0x6311,0x6316,0x631B,0x631D,0x631F-0x6321,0x6325,0x632A-0x632B,0x632F,0x6332,0x633A,0x6346,0x6349,0x634B-0x6350,0x635F,0x6362,0x6367,0x6369,0x636D-0x636E,0x6376-0x6377,0x637B,0x6380,0x6387-0x638A,0x638C,0x638E,0x6392,0x6398,0x63A0,0x63A2,0x63A5,0x63A7-0x63A8,0x63AA,0x63B4,0x63B8,0x63BA,0x63BE,0x63C4,0x63C9,0x63CD,0x63CF-0x63D0,0x63D2,0x63D6,0x63DE,0x63E1,0x63E3,0x63E9,0x63ED,0x63F2,0x63F4,0x6402,0x640B,0x6413,0x641B-0x641C,0x641E,0x6421,0x642C-0x642D,0x6441,0x6447,0x6454,0x6467,0x6469,0x647A,0x6485,0x6487,0x6492,0x6495-0x6496,0x6499,0x649E,0x64A4,0x64A9,0x64AD-0x64AE,0x64B0,0x64BA,0x64C2,0x64CD,0x64D0,0x64D2,0x64D7-0x64D8,0x64DE,0x64E6,0x6509,0x6512,0x6518,0x6525,0x652E-0x652F,0x6536,0x6539,0x653B,0x653E-0x653F,0x6545,0x6548,0x654C,0x654F,0x6551,0x6555-0x6556,0x6559,0x655E,0x6562-0x6563,0x6566,0x656B,0x6570,0x6574,0x6587,0x658C,0x6597,0x6599,0x659C,0x65A1,0x65A5,0x65A9,0x65AB,0x65AD,0x65AF-0x65B0,0x65B9,0x65BC-0x65BD,0x65C1,0x65C4,0x65CB,0x65CF,0x65E0,0x65E2,0x65E5-0x65E7,0x65E9,0x65EC,0x65EE,0x65F0,0x65F6,0x6602,0x6606,0x660C,0x660E-0x660F,0x6614-0x6615,0x6619,0x661F-0x6620,0x6625,0x6627-0x6628,0x662F,0x6635,0x663E,0x6641,0x6643,0x6652,0x665A,0x665F,0x6668,0x666E-0x666F,0x6682,0x6687,0x6696-0x6697,0x66A7-0x66A8,0x66B4,0x66DD,0x66E9,0x66F0,0x66F2,0x66F4,0x66F7,0x66F9,0x66FC,0x66FE,0x6700,0x6708-0x670B,0x670D,0x6710,0x6714,0x6717,0x671B,0x671D,0x671F,0x6726,0x6728,0x672A-0x672D,0x672F,0x6731,0x6734-0x6735,0x673A,0x6740,0x6742-0x6743,0x6749,0x674C,0x674E,0x6750-0x6751,0x6753,0x675C,0x6760-0x6761,0x6765,0x6768,0x676D,0x6777,0x677C,0x677E-0x677F,0x6784,0x6787,0x6789,0x678B,0x6790,0x6795,0x6797-0x6798,0x679C-0x679E,0x67AA,0x67AF,0x67B6,0x67B8,0x67C1,0x67CF-0x67D1,0x67D3-0x67D4,0x67D9-0x67DA,0x67DC,0x67DE,0x67E0,0x67E2,0x67E5,0x67F3-0x67F4,0x67FD,0x6805,0x6807,0x680E-0x680F,0x6811,0x6813,0x6816-0x6817,0x681D,0x6821,0x6829,0x6837-0x6839,0x683C,0x683E,0x6841-0x6843,0x6845,0x6848,0x684A,0x684C,0x6850-0x6851,0x6854,0x6861,0x6863,0x6865,0x6867,0x6881,0x6885,0x688F,0x6897,0x68A2,0x68A6-0x68A7,0x68AD,0x68C9,0x68CB,0x68CD,0x68D2,0x68E3,0x68EE,0x68F0-0x68F1,0x68F5,0x68F9,0x690E,0x6939,0x693F,0x6942,0x695A,0x695E,0x6960,0x696E,0x6971,0x6977,0x697C,0x6982,0x699C,0x69C1,0x69CC,0x69D0,0x69DB,0x69DF,0x69ED,0x69FD,0x69FF,0x6A18,0x6A21,0x6A2A,0x6A3D,0x6A50,0x6A59,0x6A80,0x6A90,0x6A97,0x6AA0,0x6AAB,0x6B21-0x6B23,0x6B27,0x6B39,0x6B3E,0x6B43,0x6B47,0x6B59,0x6B62-0x6B66,0x6B6A,0x6B79,0x6B7B,0x6B81,0x6B8B,0x6B8D,0x6B96,0x6BA1,0x6BB5,0x6BB7,0x6BBF,0x6BC1,0x6BCB,0x6BCD,0x6BCF,0x6BD2,0x6BD4-0x6BD5,0x6BDB,0x6BEB,0x6BF3,0x6BF9,0x6C0F-0x6C11,0x6C13-0x6C15,0x6C24,0x6C34-0x6C35,0x6C38,0x6C3D,0x6C40-0x6C42,0x6C47,0x6C49,0x6C55,0x6C57,0x6C5D,0x6C5F-0x6C60,0x6C64,0x6C69-0x6C6A,0x6C76,0x6C7D-0x6C7E,0x6C82-0x6C83,0x6C86,0x6C88-0x6C89,0x6C8C,0x6C8F,0x6C93,0x6C99,0x6C9F,0x6CA1,0x6CA6-0x6CA7,0x6CAE,0x6CB1,0x6CB3,0x6CB8,0x6CBB,0x6CBE,0x6CC4-0x6CC5,0x6CC9-0x6CCA,0x6CCC,0x6CD0,0x6CD4-0x6CD6,0x6CDB,0x6CDE,0x6CE2-0x6CE3,0x6CE5,0x6CE8,0x6CEA-0x6CEB,0x6CEF-0x6CF0,0x6CF5,0x6CF7,0x6CFA,0x6CFD,0x6D01,0x6D07,0x6D0B,0x6D12,0x6D17,0x6D1A-0x6D1B,0x6D1E,0x6D2A-0x6D2B,0x6D2E,0x6D32,0x6D35,0x6D3B-0x6D3E,0x6D41,0x6D45,0x6D4B,0x6D4D,0x6D51-0x6D53,0x6D5A,0x6D5C,0x6D69-0x6D6A,0x6D77-0x6D78,0x6D82,0x6D85,0x6D88-0x6D89,0x6D8C,0x6D8E,0x6D91,0x6D93-0x6D94,0x6D9E,0x6DA1,0x6DA3,0x6DA6,0x6DA9-0x6DAA,0x6DAE,0x6DB2,0x6DCB-0x6DCC,0x6DD1,0x6DD6,0x6DD9,0x6DE0-0x6DE1,0x6DE6,0x6DEB-0x6DEC,0x6DEE,0x6DF1,0x6DF3,0x6DF7,0x6DFB,0x6E05,0x6E11,0x6E20,0x6E25,0x6E29,0x6E2B,0x6E2F,0x6E34,0x6E38,0x6E43,0x6E4D,0x6E53-0x6E54,0x6E5B,0x6E5F,0x6E6B,0x6E6E,0x6E7E,0x6E83,0x6E89,0x6E98,0x6E9F,0x6EA5,0x6EAA,0x6EAF,0x6EB1-0x6EB2,0x6EB4,0x6EB6,0x6EBA,0x6EC2,0x6EC7,0x6ECB,0x6ED1,0x6ED5,0x6EDA,0x6EE1,0x6EE8,0x6F02,0x6F06,0x6F0F,0x6F15,0x6F2B,0x6F2F,0x6F58,0x6F5C,0x6F62,0x6F66,0x6F6D-0x6F6E,0x6F7C,0x6F84,0x6F89,0x6F8D,0x6FA1,0x6FB3,0x6FB6,0x6FB9,0x6FC0,0x6FC2,0x6FDE,0x6FE1,0x6FEF,0x7011,0x7039,0x704C,0x706B-0x706D,0x706F-0x7070,0x7075,0x707E-0x707F,0x7085,0x708A,0x708E,0x7094-0x7096,0x70AE-0x70AF,0x70B8-0x70B9,0x70C1-0x70C2,0x70C8,0x70D9,0x70DB,0x70DF,0x70E4,0x70E7,0x70ED,0x7109,0x7116,0x7118,0x7126,0x712F,0x7131,0x7136,0x7166-0x7168,0x7184,0x718A,0x7199,0x719F,0x71A8,0x71AC,0x71C3,0x71D4,0x71E0,0x71E5,0x71F9,0x7206,0x721D,0x7228,0x722A,0x722C,0x7231,0x7237-0x7239,0x723B,0x723D,0x723F,0x7247-0x7248,0x724C,0x7259,0x725B,0x725F,0x7262,0x7269,0x7279,0x7284,0x728D,0x7292,0x72AF,0x72B4,0x72B6,0x72C2-0x72C4,0x72D7,0x72E0-0x72E1,0x72EC,0x72FB-0x72FC,0x730E,0x7313,0x7317,0x731B,0x732B,0x7334,0x7360,0x736C,0x737E,0x7384,0x7387,0x738B,0x739F,0x73A2,0x73A9,0x73AF-0x73B0,0x73CD,0x73DE,0x73E9,0x73ED,0x73F2,0x7403,0x7405-0x7406,0x7422,0x7428,0x7433-0x7434,0x743C,0x7457,0x7459,0x745E-0x745F,0x74D2,0x74DC,0x74E0,0x74E4,0x74E6,0x74EE,0x74F6,0x74FF,0x7504,0x7518,0x751A,0x751C,0x751F,0x7528-0x7529,0x752B-0x752D,0x7530-0x7532,0x7535,0x7537-0x7538,0x753A,0x753E,0x754C,0x7559-0x755A,0x755C,0x7565,0x756A,0x7578-0x7579,0x758B,0x7591-0x7592,0x7594,0x7597,0x7599,0x759F,0x75AE,0x75B4-0x75B5,0x75B8-0x75B9,0x75BC,0x75C5,0x75D5,0x75DB,0x75E6,0x75EA,0x7615,0x761F,0x7625,0x7633,0x7635,0x764C,0x765E,0x7678,0x767B,0x767D-0x767E,0x7684,0x7687,0x768B,0x7693,0x7696,0x76A4,0x76AE,0x76B4,0x76BF,0x76C5-0x76C6,0x76CD-0x76CE,0x76D1-0x76D2,0x76D6,0x76D8,0x76DB,0x76DF,0x76EE-0x76EF,0x76F2,0x76F4,0x76F8-0x76F9,0x76FC,0x76FE,0x7701,0x7708,0x770B,0x7719,0x771F-0x7720,0x7729,0x772D,0x7737-0x7738,0x773C,0x7740,0x7743,0x7747,0x7761-0x7763,0x776B,0x777D-0x7780,0x7791,0x77A0,0x77A2,0x77A5,0x77A7,0x77AA,0x77AC,0x77B5,0x77BF,0x77DB-0x77DC,0x77E3,0x77E5,0x77ED,0x77F3,0x77F8,0x77FF,0x7801,0x7809,0x780C-0x780D,0x7814,0x7816,0x781D,0x781F,0x7825,0x7829,0x782C,0x7830,0x7834,0x7838,0x7845,0x784C,0x784E,0x7850,0x7855,0x785D,0x786A-0x786C,0x786E,0x788C,0x788E,0x789F,0x78A1,0x78A3,0x78B0-0x78B1,0x78C1,0x78C5,0x78C9,0x78F7,0x78FA,0x7924,0x793A,0x793E,0x7941,0x7948,0x7953,0x7956,0x795D-0x795E,0x7960,0x7962,0x7968,0x796D,0x7981,0x7985,0x79B3,0x79BB,0x79C0-0x79C1,0x79CB,0x79CD,0x79D1-0x79D2,0x79D8,0x79DF,0x79E4,0x79E6,0x79EF-0x79F0,0x79F8,0x79FB,0x7A0B,0x7A0D-0x7A0E,0x7A1E,0x7A20,0x7A37,0x7A39,0x7A3D,0x7A3F,0x7A51,0x7A70,0x7A74,0x7A76-0x7A77,0x7A79-0x7A7A,0x7A7F-0x7A81,0x7A83,0x7A92,0x7A96-0x7A98,0x7A9C-0x7A9D,0x7AA5,0x7AA8,0x7AAC,0x7ACB,0x7AD9,0x7ADF-0x7AE0,0x7AE5,0x7AEF,0x7AFA,0x7B0B,0x7B0F,0x7B11,0x7B24,0x7B26,0x7B28,0x7B2C,0x7B2E,0x7B3C,0x7B49,0x7B4B,0x7B52,0x7B54,0x7B56,0x7B5B,0x7B60,0x7B77,0x7B79,0x7B80,0x7B90,0x7B97,0x7BA1-0x7BA2,0x7BAC,0x7BB4,0x7BB8,0x7BC7,0x7BE1,0x7BE6,0x7BFE,0x7C07,0x7C2A,0x7C3F,0x7C41,0x7C4D,0x7C73-0x7C74,0x7C7B,0x7C89,0x7C97-0x7C98,0x7CA2,0x7CA5,0x7CAE,0x7CB9,0x7CBE,0x7CC1,0x7CC5,0x7CD6,0x7CDC,0x7CDF,0x7CF8,0x7CFB,0x7D20,0x7D22,0x7D27,0x7D2F,0x7D6E,0x7DAE,0x7E41,0x7E47,0x7E82,0x7E9B,0x7EA2,0x7EA4-0x7EA7,0x7EAF,0x7EB1-0x7EB3,0x7EB5-0x7EB7,0x7EBD,0x7EBF,0x7EC3-0x7EC4,0x7EC6,0x7EC8,0x7ECD,0x7ECF,0x7ED3,0x7ED5,0x7ED9,0x7EDC-0x7EDD,0x7EDF,0x7EE2-0x7EE3,0x7EEA,0x7EED,0x7EF0,0x7EF2,0x7EF5,0x7EFC,0x7F00,0x7F09,0x7F0E-0x7F0F,0x7F13,0x7F16-0x7F17,0x7F20,0x7F29-0x7F2A,0x7F2F,0x7F32,0x7F34-0x7F36,0x7F3A,0x7F51,0x7F57,0x7F5A,0x7F62,0x7F6A,0x7F6E,0x7F71,0x7F8E,0x7F9E,0x7FA1,0x7FA4,0x7FA7,0x7FB8-0x7FB9,0x7FBD,0x7FC1,0x7FDF-0x7FE0,0x7FEE,0x7FFB,0x8001,0x8003,0x8005-0x8006,0x800C-0x800D,0x8010,0x8015,0x8017,0x8019,0x8028,0x8033,0x8036-0x8038,0x804A,0x8052,0x8054,0x8058,0x806A,0x8071,0x8083-0x8084,0x8086,0x8089,0x808B,0x809C,0x80A1-0x80A2,0x80A5,0x80A9,0x80AB,0x80AD-0x80AF,0x80B2,0x80B7,0x80BA,0x80C2,0x80C6,0x80CC-0x80CD,0x80D6-0x80D7,0x80DC-0x80DE,0x80E1,0x80E9,0x80EF,0x80F1-0x80F3,0x80F6,0x80F8,0x80FA,0x80FD,0x8109,0x810F,0x8111,0x8113-0x8114,0x8118,0x811A,0x811E,0x812F,0x8131,0x8138,0x813E,0x814A,0x814C,0x8154,0x8167,0x816E,0x8171,0x817E-0x8180,0x818A,0x8198,0x81A6,0x81AA,0x81BB,0x81C2,0x81E3,0x81E7,0x81EA,0x81ED,0x81F3-0x81F4,0x81FE,0x8202,0x8204,0x820C-0x820D,0x8212,0x8214,0x821C,0x8221,0x822A,0x822C,0x8231,0x8233,0x8239,0x8258,0x825F,0x826E-0x826F,0x8272,0x8274,0x827D-0x827F,0x8282,0x828B,0x828D-0x828E,0x8292,0x8298,0x829F,0x82A4-0x82A6,0x82A9-0x82AB,0x82AD-0x82AE,0x82B1,0x82B3-0x82B4,0x82BE,0x82CD,0x82CF,0x82D1-0x82D3,0x82D5,0x82D7,0x82DB,0x82DE,0x82E3-0x82E6,0x82EB,0x82EF,0x82F1,0x82F4,0x82F9,0x82FB,0x8301,0x8303-0x8304,0x8307-0x8308,0x8311,0x831B-0x831C,0x8327,0x832B-0x832D,0x8336,0x8343,0x8349,0x8351-0x8352,0x835B,0x8360-0x8361,0x8363-0x8365,0x8368,0x836F,0x837C-0x837D,0x8386,0x8389,0x838E,0x8398,0x839C,0x839E,0x83A0,0x83A8-0x83A9,0x83AB,0x83B1,0x83B7,0x83BD,0x83C0,0x83C5,0x83CC,0x83CF,0x83DC,0x83E5,0x83E9,0x83F2,0x83F8-0x83F9,0x83FD,0x8401,0x8406,0x840C,0x8411,0x8425,0x8428,0x843D,0x8457,0x845A,0x845C,0x8461,0x8463,0x846C-0x846D,0x8471,0x8476,0x848B,0x8499,0x849C,0x84A1,0x84AF,0x84B2,0x84BD,0x84BF,0x84C1,0x84C9-0x84CA,0x84D1,0x84DD,0x84FC,0x84FF,0x8511,0x8513,0x851A,0x851F,0x8521,0x852B,0x853D,0x8543,0x8548-0x854A,0x855E,0x8579-0x857A,0x8584,0x859B-0x859C,0x85C9,0x85CF-0x85D0,0x85E4,0x85FF,0x8616,0x8627,0x8650-0x8651,0x866B,0x8679,0x867D-0x867E,0x868C,0x8695,0x869D,0x86A3-0x86A4,0x86B0,0x86B4-0x86B5,0x86BA,0x86C6-0x86C7,0x86D1,0x86D9,0x86DE,0x86E4,0x86E9,0x86EE,0x86F8,0x86FE,0x870D,0x8712-0x8713,0x8715,0x871A,0x8721,0x8729,0x872E,0x8731,0x8734,0x8737,0x873B,0x873E,0x874E,0x8759,0x8764-0x8765,0x8776,0x8783,0x8785,0x878D,0x87AB,0x87C0,0x87C6,0x87CA,0x87D2,0x87E0,0x8803,0x8816,0x881B,0x8821-0x8822,0x883C,0x8840,0x884C,0x8859,0x8861,0x8865,0x8868,0x886E,0x8870,0x887F,0x8882,0x8885,0x888D,0x8892,0x8896,0x889C,0x88A2,0x88A4,0x88AB,0x88B7,0x88BC,0x88C1-0x88C2,0x88C5,0x88D2,0x88D9,0x88E2,0x88E8,0x88F3-0x88F4,0x88FC,0x890A,0x891A,0x8925,0x892A,0x8936,0x897F,0x8981,0x8983,0x89C1-0x89C2,0x89C4,0x89C6,0x89C8-0x89C9,0x89D2,0x89D6,0x89DC,0x89E3,0x89F3,0x8A00,0x8A07,0x8A79,0x8A8A,0x8BA1-0x8BA2,0x8BA4,0x8BA8-0x8BA9,0x8BAD-0x8BB0,0x8BB2,0x8BB7-0x8BB8,0x8BBA,0x8BBC,0x8BBE-0x8BBF,0x8BC1,0x8BC4,0x8BC6,0x8BC8-0x8BC9,0x8BCD,0x8BCF,0x8BD5,0x8BD8,0x8BDD,0x8BE5,0x8BED,0x8BEF-0x8BF0,0x8BF4-0x8BF7,0x8BF9-0x8BFB,0x8BFE,0x8C01,0x8C03,0x8C06,0x8C08,0x8C0B,0x8C0D,0x8C11,0x8C1C,0x8C20,0x8C22,0x8C2C,0x8C2E,0x8C31,0x8C37,0x8C41,0x8C46,0x8C49,0x8C5A,0x8C61,0x8C6A-0x8C6B,0x8C73,0x8C78,0x8C7A,0x8C89-0x8C8A,0x8C8C,0x8D1D,0x8D22-0x8D23,0x8D25,0x8D2B,0x8D2D,0x8D30,0x8D32,0x8D34-0x8D35,0x8D38-0x8D39,0x8D3C,0x8D3E,0x8D43-0x8D44,0x8D49,0x8D4F,0x8D56,0x8D5A-0x8D5B,0x8D5E,0x8D60,0x8D66,0x8D6B,0x8D70,0x8D76-0x8D77,0x8D81,0x8D84-0x8D85,0x8D8A,0x8D91,0x8D9F,0x8DA3,0x8DB3,0x8DB5,0x8DBC,0x8DBF,0x8DC3,0x8DCB-0x8DCC,0x8DD1,0x8DDB,0x8DDD-0x8DDF,0x8DE3-0x8DE4,0x8DE8,0x8DEB-0x8DEC,0x8DEF,0x8DF3,0x8E05,0x8E09,0x8E14,0x8E22-0x8E23,0x8E29-0x8E2A,0x8E31,0x8E39,0x8E42,0x8E44,0x8E4A,0x8E66,0x8E6D,0x8E72,0x8E74,0x8E76,0x8E7F,0x8E81,0x8E85,0x8E87,0x8E94,0x8EAB,0x8EB2,0x8EBA,0x8F66-0x8F68,0x8F6C,0x8F6E-0x8F70,0x8F74,0x8F7D,0x8F83,0x8F87,0x8F8D,0x8F8F,0x8F91,0x8F93,0x8F97,0x8F9B,0x8F9E-0x8F9F,0x8FA3,0x8FA8-0x8FA9,0x8FB0,0x8FB9,0x8FBD-0x8FBE,0x8FC1,0x8FC5,0x8FC7,0x8FCE,0x8FD0-0x8FD1,0x8FD4,0x8FD8-0x8FD9,0x8FDB-0x8FDC,0x8FDE-0x8FDF,0x8FE4-0x8FE6,0x8FE9,0x8FEB,0x8FED-0x8FEE,0x8FF0,0x8FF7,0x8FF9,0x8FFD,0x9000-0x9004,0x9006,0x9009-0x900A,0x900F-0x9010,0x9014,0x9017,0x901A-0x901B,0x901E-0x9022,0x902E-0x902F,0x903E,0x9041-0x9042,0x9047,0x904D,0x9053,0x9057,0x9063,0x906D,0x9075,0x907D,0x908B,0x9091,0x9093,0x909B,0x90A2-0x90A3,0x90A6,0x90AA,0x90B9-0x90BB,0x90C4-0x90C5,0x90C7,0x90CE,0x90D7,0x90DD,0x90E1-0x90E2,0x90E8,0x90ED,0x90F4,0x90FD,0x9131,0x9139,0x914D,0x9150,0x9152,0x9161-0x9162,0x916A,0x916C,0x916E,0x9177-0x9178,0x917E-0x917F,0x9187,0x9189,0x918B,0x9192,0x919B,0x91AE,0x91C7,0x91CC-0x91CF,0x91D1,0x92AE,0x93D6,0x946B,0x9488,0x948F,0x9494,0x9497,0x949E-0x949F,0x94A2,0x94A5-0x94A6,0x94AD-0x94AF,0x94B1,0x94BB,0x94BF,0x94C1,0x94C5,0x94CA,0x94DB,0x94E3-0x94E5,0x94EA-0x94EB,0x94ED,0x94F6,0x94FA,0x94FD-0x9501,0x950A,0x9510,0x9515,0x9519,0x9524,0x952C,0x952E,0x953B,0x9547,0x9550,0x9556,0x9561,0x9566,0x957F,0x95E8-0x95EA,0x95ED-0x95F0,0x95F2,0x95F4-0x95F5,0x95F7,0x95F9,0x95FB,0x95FD,0x960F,0x9614,0x9619-0x961A,0x961F,0x9622,0x962E,0x9632-0x9633,0x9635,0x963B,0x963D,0x963F-0x9640,0x9642,0x9644,0x9646-0x9648,0x964B,0x964D,0x9650,0x9655,0x965F,0x9662,0x9664,0x9669-0x966A,0x966C,0x9674-0x9676,0x9686,0x968B,0x968F-0x9690,0x9694,0x9697-0x9698,0x96A7,0x96B0,0x96B6,0x96B9,0x96BC-0x96BE,0x96C0,0x96C4-0x96C7,0x96C9,0x96E9-0x96EA,0x96F6-0x96F7,0x9700,0x9707,0x970D,0x971C,0x9730,0x9732,0x9738,0x973E,0x9752-0x9753,0x9759,0x975E,0x9760-0x9762,0x9769,0x978B,0x9794,0x9798,0x97A0,0x97A3,0x97AB,0x97B4,0x97E9,0x97F3,0x9875-0x9876,0x987A-0x987B,0x987F,0x9882,0x9884,0x9886-0x9889,0x988C,0x9891,0x9897-0x9898,0x989D,0x98A0-0x98A1,0x98A4,0x98CE,0x98D2,0x98D8,0x98DE-0x98DF,0x98E7,0x9910,0x992E,0x9967,0x996D,0x9976,0x997F,0x9981,0x9986-0x9988,0x9993,0x9995-0x9998,0x99A5,0x9A6C,0x9A6E,0x9A80,0x9A82,0x9A87,0x9A8C,0x9A97,0x9A9A,0x9AA0,0x9AB0-0x9AB1,0x9AB8,0x9AC1-0x9AC2,0x9ACB,0x9AD8,0x9ADF,0x9AEF,0x9AFB,0x9B13,0x9B32,0x9B3B-0x9B3C,0x9B41-0x9B42,0x9B44,0x9C81,0x9C85,0x9C91,0x9CA7,0x9CAD,0x9CC3,0x9E1F,0x9E23,0x9E3E-0x9E3F,0x9E44,0x9E4F,0x9E58,0x9E87,0x9E9F,0x9EA6,0x9EBB,0x9EBD,0x9EC4,0x9ED1,0x9EDD,0x9EE7,0x9EF9,0x9EFE,0x9F0E,0x9F50,0x9F88,0x9F99,0x9F9F diff --git a/packs/zh-Hans/fonts/zh-hans-ext/.gitignore b/packs/zh-Hans/fonts/zh-hans-ext/.gitignore new file mode 100644 index 00000000..2224454d --- /dev/null +++ b/packs/zh-Hans/fonts/zh-hans-ext/.gitignore @@ -0,0 +1 @@ +font.bin diff --git a/packs/zh-Hans/fonts/zh-hans-ext/build.ini b/packs/zh-Hans/fonts/zh-hans-ext/build.ini new file mode 100644 index 00000000..c28850de --- /dev/null +++ b/packs/zh-Hans/fonts/zh-hans-ext/build.ini @@ -0,0 +1,8 @@ +font=tools/fonts/NotoSansCJKsc-Regular.otf +size=16 +bpp=2 +no_compress=true +include_manifests=false +include_locales=false +seed_charset_file=tools/pinyin_chars.txt +exclude_charset_file=fonts/zh-hans-core/charset.txt diff --git a/packs/zh-Hans/fonts/zh-hans-ext/charset.txt b/packs/zh-Hans/fonts/zh-hans-ext/charset.txt new file mode 100644 index 00000000..d3fe36aa --- /dev/null +++ b/packs/zh-Hans/fonts/zh-hans-ext/charset.txt @@ -0,0 +1,57 @@ +丐丕世丝丨丫丬丶丸丽乌乒乓乔乞习乡乩乳亍互亓井亠亦亩亳亵亻亿仃仄仉仕仗付仙仝仞仟仨仪仫仲仵企伊伏优伙伛伟伢伥伪伫估伲伶伸佐佑佘佞 +佟佣佤佥佯佶佾侃侄侈侍侑依侣侦侨侩侪侮俅俎俐俑俘俚俜俣俦俨俪俭俯俱俳倌倏倔借倡倥倨倬倮倾偃偎健偾偿傅傈傣傥傧傩傺僖僦僬僳僵僻儆儇 +儒儡兀兆兕兖兜兢兮兼兽冀冁冂冕冖冗冢冤冫冱冶冽凄凇凉凋凌减凛凫凰凸凼函刁刂刃刈刍刎刑刖刭刽刿剀剁剂剃剌剐剑剔剜剞剧剪割劁劂劈劓劢 +劫劬劭励勃勋勐勰勹匈匍匏匐匚匠匣匦医匾午卉博卢卣卩卮卸卺卿厄历厉厌厍厢厣厥厨厩厮叉叔叙叛叮史叵叼吆吉吊吏吐吒吕吝吠吣吸吻吼呋呓呖 +呙呛呜呤呦呸呻咂咄咆咏咐咒咕咙咚咛咝咤咧咨咫咿哂哄哉哎哑哒哓哔哗哙哚哜哞哥哳哿唁唉唠唢唣唯唱唳唾唿啕啖啤啧啪啬啭啮啵啶啷啸啼啾喂 +喑喧喱喵喹喻喾嗅嗉嗜嗝嗣嗤嗥嗦嗪嗫嗬嗳嗵嗷嗾嘈嘉嘌嘛嘟嘣嘤嘧嘭嘱嘶嘹嘻噔噗噘噙噜噤噩噬噼嚅嚆嚎嚏囟囫围囵囹囿圃圄圆圉圊圬圭圮圯圹 +址坂坊坌坍坚坛坜坝坞坟坩坪坭坼垃垅垆型垓垛垡垢垣垤垫垭垲垴埂埒埕埘埙埚埠埭埴埸基堀堍堑堙堞堠堰塍塑塥塬塾墀墁墉墒墓墚墟墩墼壁壕士 +壶夔夙夤夥夷夼奁奂奄奎奕奚奢妄妇妊妍妒妓妣妤妥妨妩妪妫妲妻姊姑姒委姗姘姜姝姨姹姻姿威娄娅娇娈娌娑娓娟娠娣娥娱娲娴娼婀婉婊婢婧婪婴 +婵婶婷婿媒媚媛媳媸媾嫁嫉嫌嫒嫘嫜嫠嫡嫣嫦嫫嫱嬉嬖嬴孑孓孕孚孜孝孢季孤孥孪孬孰孳孵孺宀宄宇宏宙宜宠审室宥宦宫宴宵宸寂寄寅富寐寓寝寞 +寤寥寮寿尕尖尘尜尤尧尴尸尻局屁屉届屋屐屑屙屠屡屣履屦屺屿岌岍岐岔岖岘岙岚岜岢岣岩岫岬岭岱岳岵岷岽岿峁峄峋峡峥峨峪峭峰峻崂崃崖崞崦 +崧崭崮崽崾嵋嵘嵛嵝嵩嵫嵬嵴嶂嶙嶝巅巍巩巫巯巾帆师帏帙帚帛帜席帷帻帼帽幂幄幌幔幛幞幡幻幽庀庆庋序庐庑庖庠庥庸庹庾廉廒廛廨廪廴廾廿异 +弃弈弊弋弑弓弗弛弦弧弪弭弯弼彐彘彝彤彰役彼征徂径徇徉徐徕徘徜徨徭微徽忄忆忉忌忘忝忡忤忧忭忸忻忿怂怃怄怅怆怊怏怔怖怡怦怩怯怿恋恕恙 +恚恣恤恧恪恬恭恸恹恺恻恽悃悉悌悍悒悔悖悚悟悠悦悫悭悱悴悸悻悼惋惑惕惘惚惜惟惦惧惩惫惬惮惯惶惺愆愈愎愕愚愦愫慈慑慕慧慰慵憔憝憨憩憬 +憷懈懋懑懦懵懿戈戊戋戍戒戗戟戢戤戥截戬戮戽戾扈扉扌扦扬扯扼抉抑抒抚披抿拄拇拒拙拣拨拭拯拳挚挞挢挣挤挨挹挽捂捃捅捕捞捡捣捱捺掂掏掐 +掖掣掩掬掭掮掰掳掷掼揆揎揠揪揶揸揽揿搀搁搅搌搏搐搔搠搦搪搴携搽搿摄摅摆摈摊摒摘摞摭摸摹撂撄撑撬撵撷撸撼擀擅擎擢擤攀攫攴攵攸敉敛敝 +敬敲敷斋斐斑斓斛斟斤斧旃旅旆旌旎旒旖旗旨旭旯旱旷旺昀昃昊易昝昭昱昴昶昼晋晌晏晓晔晕晖晗晡晤晦晰晴晶晷智晾暄暌暑暝暮暹暾曙曛曜曦曳 +替朕朽杆杈杏杖杞束杩杪杯杰杲杳杵极枚枢枣枥枧枨枫枭枰枳枵枷柃柄柒柘柝柩柬柯柰柱柿栀栈栉栊栋栌株栲栳栽桀桄框桉桎桓桕桠桢桤桦桨桩桫 +桴桶桷梃梆梓梨梯械梳梵检棂棕棘棚棠棺棼椁椅椋植椐椒椟椠椤椭椰椴椽楔楗楝楣楦楫楸楹榀榄榆榇榈榉榍榔榕榘榛榧榨榫榭榱榴榷榻槊槎槔槠槲 +樊樗樟樨樯樱樵樾橄橇橘橛橡橥橱橹橼檄檎檑檩檬欠欤欲欷欺歆歉歌歧歼殂殃殄殆殇殉殊殒殓殚殛殪殳殴毂毅毓毖毗毙毡毪毯毵毽氅氆氇氍氖氘氙 +氚氛氟氡氢氦氧氨氩氪氮氯氰氲汆汊汐汔汛汜汞污汨汰汲汴汹沁沅沐沔沛沣沤沥沩沪沫沭沲油沼沽沿泓泗泠泡泮泱泳泶泸泻泼泾洄洌洎洙津洧洱洳 +洹浃浆浇浈浊济浏浔浙浞浠浣浦浮浯浴浼涕涛涝涟涠涤涧涨涫涯涵涸涿淀淄淅淆淇淘淝淞淤淹淼渊渌渍渎渐渔渖渗渚渝渡渣渤渭渲渺湄湎湖湘湿溅 +溆溏源溜溢溧溷溻溽滁滏滓滔滗滞滟滠滢滤滥滦滩滴滹漉漓演漠漤漩漪漭漱漳漶漾潆潇潋潍潞潲潴潸潺澈澌澎澜澧濉濑濒濠濮瀚瀛瀣瀵灏灞灶灸灼 +炀炉炒炙炜炝炫炬炭炱炳炷炻炼炽烀烃烊烘烦烨烩烫烬烯烷烹烽焊焐焓焕焙焚焰煅煊煌煎煜煞煤煮煲煳煸煺煽熏熔熘熠熳熵熹燎燕燧燮爰爵父牍牒 +牖牝牡牦牧牮牯牲牵牺牾牿犀犁犊犋犏犟犬犭犰犷犸犹狁狈狍狎狐狒狙狞狨狩狭狮狯狰狱狲狳狴狷狸狺猁猃猊猕猖猜猝猞猡猢猥猩猪猬献猱猷猸猹 +猾猿獍獐獒獗獭獯玉玎玑玖玛玫玮玲玳玷玺玻珀珂珈珉珊珏珐珑珙珠珥珧琉琊琏琐琚琛琥琦琪琬琮琰琵琶瑁瑕瑚瑛瑜瑭瑰瑶瑷瑾璀璁璃璇璋璎璐璜 +璞璧璨璩璺瓞瓢瓣瓯瓴瓷甍甏甑甓甙甥甯申画畀畅畈畋畎畏畔畛畦畲畴畿疃疆疏疖疚疝疠疡疣疤疥疫疬疯疰疱疲疳疽疾痂痃痄症痈痉痊痍痒痔痖痘 +痞痢痣痤痧痨痫痰痱痴痹痼痿瘀瘁瘃瘅瘊瘌瘐瘗瘘瘙瘛瘠瘢瘤瘦瘩瘪瘫瘭瘰瘴瘸瘼瘾瘿癀癃癍癔癖癜癣癫癯皂皆皈皎皑皙皱皲盂盈益盏盐盔盗盥盱 +眄眇眉眍眚眢眦眨眯眵眶眺睁睐睑睚睛睥睦睨睬睹瞄瞅瞌瞍瞎瞒瞟瞩瞰瞳瞻瞽矍矗矢矧矩矫矬矮矶矽矾砀砂砑砒砗砘砚砜砣砦砧砭砷砹砺砻砼砾础 +硇硒硖硗硭硷硼碇碉碍碑碓碗碘碚碛碜碥碧碲碳碴碹碾磊磋磐磔磕磙磨磬磲磴礁礅礓礞礴礻礼祀祆祉祗祚祛祜祟祥祧祯祷祸祺禀禄禊福禚禧禹禺禽 +禾秃秆秉秕秣秧秩秫秭秽稀稂稃稆稔稗稚稣稳稻稼穆穗穸窄窆窈窍窑窕窟窠窦窭窳窿竖竞竣竦竭竹竽竿笃笄笆笈笊笔笕笙笛笞笠笥笪笫笱笳笸笺笾 +筅筇筌筏筐筑筘筚筝筢筮筱筲筵筻签箅箍箔箕箜箝箦箧箨箩箪箫箭箱篁篆篌篑篓篙篚篝篥篪篮篱篷篼簋簌簏簖簟簦簧簸籀籼籽粑粒粕粜粝粞粟粤粪 +粱粲粳粼粽糇糈糊糌糍糕糗糙糠糨糯紊紫絷綦縻纟纠纡纣纨纩纪纫纬纭纰纸纹纺纾绀绁绂绅织绉绊绋绌绎绐绑绒绔绗绘绚绛绞绠绡绥绦继绨绩绫绮 +绯绱绳维绶绷绸绺绻绽绾绿缁缂缃缄缅缆缇缈缋缌缍缑缒缔缕缘缙缚缛缜缝缟缡缢缣缤缥缦缧缨缫缬缭缮缰缱缳缸罂罄罅罐罔罕罘罟罡罨罩署罴罹 +罾羁羊羌羔羚羝羟羯羰羲羼羿翅翊翌翎翔翕翘翡翥翦翩翰翱翳翼耀耄耋耒耔耖耘耜耠耢耥耦耧耩耪耱耵耻耽耿聂聃聆聋职聍聚聩聿肀肇肌肓肖肘肚 +肛肝肟肠肤肪肱肴肼肽肾肿胀胁胃胄胎胙胚胛胤胥胧胨胪胫胬胭胰胴胼脂脆脊脍脎脐脒脖脬脲脶腆腈腋腐腑腓腕腙腚腠腥腩腭腰腴腹腺腻腼腽膂膈 +膏膑膛膜膝膣膨膳膺臀臁臃臆臊臌臬臻臼舀舁舅舆舐舛舞舟舢舣舨舫舭舯舰舴舵舶舷舸舻舾艄艇艉艋艏艚艨艰艳艹艺芄芈芊芏芑芗芙芜芝芡芨芬芯 +芰芷芸芹芽苁苄苇苈苊苋苌苎苔苘苜苟苠苡苷茂茅茆茉茌茎茏茔茕茗茚茨茯茱茳茴茵茸茹茺茼荀荆荇荏荐荔荚荜荞荟荦荧荩荪荫荬荭荮荷荸荻莅莒 +莓莛莪莰莲莳莴莶莸莹莺莼菁菇菊菔菖菘菝菟菠菡菪菰菱萃萄萋萍萎萏萘萜萝萤萦萧萱萸萼葆葑葙葛葩葫葳葵葸葺蒂蒇蒈蒉蒌蒎蒗蒴蒸蒹蒺蓄蓍蓐 +蓓蓖蓟蓠蓣蓥蓦蓬蓰蔌蔗蔬蔷蔸蔹蔺蔻蔼蕖蕙蕤蕨蕲蕴蕻蕾薅薇薏薤薨薪薮薯薰薷薹藁藓藕藜藩藻蘅蘑蘩蘸蘼虍虎虏虔虚虞虢虬虮虱虺虻虼虿蚀蚁 +蚂蚊蚋蚍蚓蚜蚧蚨蚩蚪蚬蚯蚱蚶蛀蛄蛉蛊蛋蛎蛏蛐蛔蛘蛛蛟蛭蛰蛱蛲蛳蛴蛹蜀蜂蜃蜇蜈蜉蜊蜗蜘蜜蜞蜢蜣蜥蜿蝇蝈蝉蝌蝓蝗蝠蝣蝮蝰蝴蝻蝼蝽蝾螂 +螈螋螓螗螟螨螬螭螯螳螵螺螽蟋蟑蟓蟛蟥蟪蟮蟹蟾蠊蠓蠕蠲蠹衄衅衍衔街衢衣衤衩衫衬衲衷衽衾袁袄袈袋袭袱裆裉裎裔裕裘裟裣裤裥裰裱裸裹裾褂 +褐褒褓褙褛褡褫褰褴襁襄襞襟襦襻覆觅觇觊觋觌觎觏觐觑觚觞觥触觫觯訾詈誉誓謇謦警譬讠讣讥讦讧讪讫讳讴讵讶讹讽诀诂诃诅诊诋诌诎译诒诓诔 +诖诗诙诚诛诜诞诟诠诡询诣诤详诧诨诩诫诬诮诱诲诳诸诼诽诿谀谂谄谅谇谊谌谎谏谐谒谓谔谕谖谗谘谙谚谛谝谟谡谣谤谥谦谧谨谩谪谫谭谯谰谲谳 +谴谵谶豇豌豕豢豹貂貅貔貘贞负贡贤账货质贩贪贬贮贯贱贳贶贷贺贻贽贿赀赁赂赅赆赇赈赊赋赌赍赎赐赓赔赕赘赙赜赝赡赢赣赤赧赭赳赴赵趋趔趱 +趴趸趺趾跄跆跎跏跖跗跚跪践跷跸跹跺跻跽踊踌踏踝踞踟踬踮踯踵踺踽蹀蹁蹇蹈蹉蹋蹑蹒蹙蹩蹬蹯蹰蹼躏躐躜躞躬躯軎轩轫轭轱轲轳轵轶轷轸轹轺 +轻轼轾轿辁辂辄辅辆辈辉辊辋辎辐辔辕辖辘辙辚辜辫辱辶迂迄迈迓迕违迢迨迪迳迸逅逋逍逑递逖逝逦逭逵逶逸逻逼遄遏遐遑遒遘遛遢遥遨遮遴避邀 +邂邃邈邕邗邙邝邡邬邮邯邰邱邳邴邵邶邸邾郁郊郏郐郑郓郛郜郦郧郫郯郸郾鄂鄄鄙鄞鄢鄣鄯酃酆酉酊酋酌酎酏酗酚酝酞酣酤酥酩酯酰酱酲酴酵酶酹 +酽醅醌醍醐醑醚醢醣醪醭醯醴醵醺釉释釜鉴銎鋈錾鍪鎏鏊鐾钅钆钇钉钊钋钌钍钎钐钒钓钕钙钚钛钜钝钠钡钣钤钧钨钩钪钫钬钰钲钳钴钵钶钷钸钹钺 +钼钽钾铀铂铃铄铆铈铉铋铌铍铎铐铑铒铕铖铗铘铙铜铝铞铟铠铡铢铧铨铩铬铮铯铰铱铲铳铴铵铷铸铹铼锂锃锄锅锆锇锈锉锋锌锍锎锏锑锒锓锔锖锗 +锘锚锛锝锞锟锡锢锣锥锦锨锩锪锫锭锯锰锱锲锴锵锶锷锸锹锺锼锾锿镀镁镂镄镅镆镉镊镌镍镎镏镑镒镓镔镗镘镙镛镜镝镞镟镢镣镤镥镧镨镩镪镫镬 +镭镯镰镱镲镳镶闫闱闳闶闸闺闼闾阀阁阂阃阄阅阆阈阉阊阋阌阍阎阐阑阒阕阖阗阜阝阡阪阱阴阶阼际陉陌陔陛陡陧陨陲陷隅隈隍隙障隳雁雌雍雎雏 +雒雕雠雨雯雳雹雾霁霄霆霈霉霎霏霓霖霞霪霭霹靖靛靥靳靴靶靼鞅鞍鞑鞒鞭鞯鞲韦韧韪韫韬韭韵韶顷顸项顼顽顾颀颁颃颅颊颍颏颐颓颔颖颚颛颜颞 +颟颢颥颦颧飑飓飕飙飚飨餍饔饕饣饥饨饩饪饫饬饮饯饰饱饲饴饵饷饺饼饽馀馄馅馊馋馍馏馐馑馒馔香馨驭驯驰驱驳驴驵驶驷驸驹驺驻驼驽驾驿骁骄 +骅骆骈骊骋骏骐骑骒骓骖骘骛骜骝骞骟骡骢骣骤骥骧骨骶骷骺骼髀髅髌髑髓髡髦髫髭髹鬃鬈鬏鬟鬣鬯魃魅魇魈魉魍魏魑魔鱼鱿鲂鲆鲇鲈鲋鲍鲎鲐鲒 +鲔鲕鲚鲛鲜鲞鲟鲠鲡鲢鲣鲤鲥鲦鲨鲩鲫鲮鲰鲱鲲鲳鲴鲵鲶鲷鲸鲺鲻鲼鲽鳄鳅鳆鳇鳊鳋鳌鳍鳎鳏鳐鳓鳔鳕鳖鳗鳘鳙鳜鳝鳞鳟鳢鸠鸡鸢鸥鸦鸨鸩鸪鸫鸬 +鸭鸯鸱鸲鸳鸵鸶鸷鸸鸹鸺鸽鹁鹂鹃鹅鹆鹇鹈鹉鹊鹋鹌鹎鹑鹕鹗鹚鹛鹜鹞鹣鹤鹦鹧鹨鹩鹪鹫鹬鹭鹰鹱鹳鹾鹿麂麈麋麒麓麝麴麸麾黉黍黎黏黔默黛黜黟 +黠黢黥黩黪黯黻黼鼋鼍鼐鼓鼗鼙鼠鼢鼬鼯鼷鼹鼻鼽鼾齄齑齿龀龃龄龅龆龇龉龊龋龌龚龛龠 diff --git a/packs/zh-Hans/fonts/zh-hans-ext/manifest.ini b/packs/zh-Hans/fonts/zh-hans-ext/manifest.ini new file mode 100644 index 00000000..2cbbfd01 --- /dev/null +++ b/packs/zh-Hans/fonts/zh-hans-ext/manifest.ini @@ -0,0 +1,8 @@ +kind=font +id=zh-hans-ext +display_name=Simplified Chinese Extension +usage=content +estimated_ram_bytes=248636 +source=binfont +file=font.bin +ranges=ranges.txt diff --git a/packs/zh-Hans/fonts/zh-hans-ext/ranges.txt b/packs/zh-Hans/fonts/zh-hans-ext/ranges.txt new file mode 100644 index 00000000..b5cf33f7 --- /dev/null +++ b/packs/zh-Hans/fonts/zh-hans-ext/ranges.txt @@ -0,0 +1 @@ +0x4E10,0x4E15-0x4E16,0x4E1D,0x4E28,0x4E2B-0x4E2C,0x4E36,0x4E38,0x4E3D,0x4E4C,0x4E52-0x4E54,0x4E5E,0x4E60-0x4E61,0x4E69,0x4E73,0x4E8D,0x4E92-0x4E93,0x4E95,0x4EA0,0x4EA6,0x4EA9,0x4EB3,0x4EB5,0x4EBB,0x4EBF,0x4EC3-0x4EC4,0x4EC9,0x4ED5,0x4ED7-0x4ED9,0x4EDD-0x4EDF,0x4EE8,0x4EEA-0x4EEB,0x4EF2,0x4EF5,0x4F01,0x4F0A,0x4F0F,0x4F18-0x4F19,0x4F1B,0x4F1F,0x4F22,0x4F25,0x4F2A-0x4F2B,0x4F30,0x4F32,0x4F36,0x4F38,0x4F50-0x4F51,0x4F58,0x4F5E-0x4F5F,0x4F63-0x4F65,0x4F6F,0x4F76,0x4F7E,0x4F83-0x4F84,0x4F88,0x4F8D,0x4F91,0x4F9D,0x4FA3,0x4FA6,0x4FA8-0x4FAA,0x4FAE,0x4FC5,0x4FCE,0x4FD0-0x4FD1,0x4FD8,0x4FDA,0x4FDC,0x4FE3,0x4FE6,0x4FE8,0x4FEA,0x4FED,0x4FEF,0x4FF1,0x4FF3,0x500C,0x500F,0x5014,0x501F,0x5021,0x5025,0x5028,0x502C,0x502E,0x503E,0x5043,0x504E,0x5065,0x507E-0x507F,0x5085,0x5088,0x50A3,0x50A5,0x50A7,0x50A9,0x50BA,0x50D6,0x50E6,0x50EC,0x50F3,0x50F5,0x50FB,0x5106-0x5107,0x5112,0x5121,0x5140,0x5146,0x5155-0x5156,0x515C,0x5162,0x516E,0x517C-0x517D,0x5180-0x5182,0x5195-0x5197,0x51A2,0x51A4,0x51AB,0x51B1,0x51B6,0x51BD,0x51C4,0x51C7,0x51C9,0x51CB-0x51CC,0x51CF,0x51DB,0x51EB,0x51F0,0x51F8,0x51FC-0x51FD,0x5201-0x5203,0x5208,0x520D-0x520E,0x5211,0x5216,0x522D,0x523D,0x523F-0x5243,0x524C,0x5250-0x5251,0x5254,0x525C,0x525E,0x5267,0x526A,0x5272,0x5281-0x5282,0x5288,0x5293,0x52A2,0x52AB-0x52AD,0x52B1,0x52C3,0x52CB,0x52D0,0x52F0,0x52F9,0x5308,0x530D,0x530F-0x5310,0x531A,0x5320,0x5323,0x5326,0x533B,0x533E,0x5348-0x5349,0x535A,0x5362-0x5363,0x5369,0x536E,0x5378,0x537A,0x537F,0x5384,0x5386,0x5389,0x538C-0x538D,0x53A2-0x53A3,0x53A5,0x53A8-0x53A9,0x53AE,0x53C9,0x53D4,0x53D9,0x53DB,0x53EE,0x53F2,0x53F5,0x53FC,0x5406,0x5409-0x540A,0x540F-0x5410,0x5412,0x5415,0x541D,0x5420,0x5423,0x5438,0x543B-0x543C,0x544B,0x5453,0x5456,0x5459,0x545B-0x545C,0x5464,0x5466,0x5478,0x547B,0x5482,0x5484,0x5486,0x548F-0x5490,0x5492,0x5495,0x5499-0x549B,0x549D,0x54A4,0x54A7-0x54A8,0x54AB,0x54BF,0x54C2,0x54C4,0x54C9,0x54CE,0x54D1-0x54D4,0x54D7,0x54D9-0x54DA,0x54DC,0x54DE,0x54E5,0x54F3,0x54FF,0x5501,0x5509,0x5520,0x5522-0x5523,0x552F,0x5531,0x5533,0x553E-0x553F,0x5555-0x5556,0x5564,0x5567,0x556A,0x556C-0x556E,0x5575-0x5578,0x557C,0x557E,0x5582,0x5591,0x55A7,0x55B1,0x55B5,0x55B9,0x55BB,0x55BE,0x55C5,0x55C9,0x55DC-0x55DD,0x55E3-0x55E6,0x55EA-0x55EC,0x55F3,0x55F5,0x55F7,0x55FE,0x5608-0x5609,0x560C,0x561B,0x561F,0x5623-0x5624,0x5627,0x562D,0x5631,0x5636,0x5639,0x563B,0x5654,0x5657-0x5659,0x565C,0x5664,0x5669,0x566C,0x567C,0x5685-0x5686,0x568E-0x568F,0x56DF,0x56EB,0x56F4-0x56F5,0x56F9,0x56FF,0x5703-0x5704,0x5706,0x5709-0x570A,0x572C-0x572F,0x5739,0x5740,0x5742,0x574A,0x574C-0x574D,0x575A-0x575F,0x5769-0x576A,0x576D,0x577C,0x5783,0x5785-0x5786,0x578B,0x5793,0x579B,0x57A1-0x57A4,0x57AB,0x57AD,0x57B2,0x57B4,0x57C2,0x57D2,0x57D5,0x57D8-0x57DA,0x57E0,0x57ED,0x57F4,0x57F8,0x57FA,0x5800,0x580D,0x5811,0x5819,0x581E,0x5820,0x5830,0x584D,0x5851,0x5865,0x586C,0x587E,0x5880-0x5881,0x5889,0x5892-0x5893,0x589A,0x589F,0x58A9,0x58BC,0x58C1,0x58D5,0x58EB,0x58F6,0x5914,0x5919,0x5924-0x5925,0x5937,0x593C,0x5941-0x5942,0x5944,0x594E,0x5955,0x595A,0x5962,0x5984,0x5987,0x598A,0x598D,0x5992-0x5993,0x59A3-0x59A5,0x59A8-0x59AB,0x59B2,0x59BB,0x59CA,0x59D1-0x59D2,0x59D4,0x59D7-0x59D8,0x59DC-0x59DD,0x59E8,0x59F9,0x59FB,0x59FF,0x5A01,0x5A04-0x5A05,0x5A07-0x5A08,0x5A0C,0x5A11,0x5A13,0x5A1F-0x5A20,0x5A23,0x5A25,0x5A31-0x5A32,0x5A34,0x5A3C,0x5A40,0x5A49-0x5A4A,0x5A62,0x5A67,0x5A6A,0x5A74-0x5A77,0x5A7F,0x5A92,0x5A9A-0x5A9B,0x5AB3,0x5AB8,0x5ABE,0x5AC1,0x5AC9,0x5ACC,0x5AD2,0x5AD8,0x5ADC,0x5AE0-0x5AE1,0x5AE3,0x5AE6,0x5AEB,0x5AF1,0x5B09,0x5B16,0x5B34,0x5B51,0x5B53,0x5B55,0x5B5A,0x5B5C-0x5B5D,0x5B62-0x5B65,0x5B6A,0x5B6C,0x5B70,0x5B73,0x5B75,0x5B7A,0x5B80,0x5B84,0x5B87,0x5B8F,0x5B99,0x5B9C,0x5BA0-0x5BA1,0x5BA4-0x5BA6,0x5BAB,0x5BB4-0x5BB5,0x5BB8,0x5BC2,0x5BC4-0x5BC5,0x5BCC,0x5BD0,0x5BD3,0x5BDD-0x5BDE,0x5BE4-0x5BE5,0x5BEE,0x5BFF,0x5C15-0x5C16,0x5C18,0x5C1C,0x5C24,0x5C27,0x5C34,0x5C38,0x5C3B,0x5C40-0x5C41,0x5C49-0x5C4B,0x5C50-0x5C51,0x5C59,0x5C60-0x5C61,0x5C63,0x5C65-0x5C66,0x5C7A,0x5C7F,0x5C8C-0x5C8D,0x5C90,0x5C94,0x5C96,0x5C98-0x5C9A,0x5C9C,0x5CA2-0x5CA3,0x5CA9,0x5CAB-0x5CAD,0x5CB1,0x5CB3,0x5CB5,0x5CB7,0x5CBD,0x5CBF,0x5CC1,0x5CC4,0x5CCB,0x5CE1,0x5CE5,0x5CE8,0x5CEA,0x5CED,0x5CF0,0x5CFB,0x5D02-0x5D03,0x5D16,0x5D1E,0x5D26-0x5D27,0x5D2D-0x5D2E,0x5D3D-0x5D3E,0x5D4B,0x5D58,0x5D5B,0x5D5D,0x5D69,0x5D6B-0x5D6C,0x5D74,0x5D82,0x5D99,0x5D9D,0x5DC5,0x5DCD,0x5DE9,0x5DEB,0x5DEF,0x5DFE,0x5E06,0x5E08,0x5E0F,0x5E19-0x5E1C,0x5E2D,0x5E37,0x5E3B-0x5E3D,0x5E42,0x5E44,0x5E4C,0x5E54,0x5E5B,0x5E5E,0x5E61,0x5E7B,0x5E7D,0x5E80,0x5E86,0x5E8B,0x5E8F-0x5E91,0x5E96,0x5EA0,0x5EA5,0x5EB8-0x5EB9,0x5EBE,0x5EC9,0x5ED2,0x5EDB,0x5EE8,0x5EEA,0x5EF4,0x5EFE-0x5EFF,0x5F02-0x5F03,0x5F08,0x5F0A-0x5F0B,0x5F11,0x5F13,0x5F17,0x5F1B,0x5F26-0x5F27,0x5F2A,0x5F2D,0x5F2F,0x5F3C,0x5F50,0x5F58,0x5F5D,0x5F64,0x5F70,0x5F79,0x5F7C,0x5F81-0x5F82,0x5F84,0x5F87,0x5F89,0x5F90,0x5F95,0x5F98,0x5F9C,0x5FA8,0x5FAD-0x5FAE,0x5FBD,0x5FC4,0x5FC6,0x5FC9,0x5FCC,0x5FD8,0x5FDD,0x5FE1,0x5FE4,0x5FE7,0x5FED,0x5FF8,0x5FFB,0x5FFF,0x6002-0x6006,0x600A,0x600F,0x6014,0x6016,0x6021,0x6026,0x6029,0x602F,0x603F,0x604B,0x6055,0x6059-0x605A,0x6063-0x6064,0x6067,0x606A,0x606C-0x606D,0x6078-0x607B,0x607D,0x6083,0x6089,0x608C-0x608D,0x6092,0x6094,0x6096,0x609A,0x609F-0x60A0,0x60A6,0x60AB,0x60AD,0x60B1,0x60B4,0x60B8,0x60BB-0x60BC,0x60CB,0x60D1,0x60D5,0x60D8,0x60DA,0x60DC,0x60DF,0x60E6-0x60E7,0x60E9,0x60EB-0x60EC,0x60EE-0x60EF,0x60F6,0x60FA,0x6106,0x6108,0x610E,0x6115,0x611A,0x6126,0x612B,0x6148,0x6151,0x6155,0x6167,0x6170,0x6175,0x6194,0x619D,0x61A8-0x61A9,0x61AC,0x61B7,0x61C8,0x61CB,0x61D1,0x61E6,0x61F5,0x61FF,0x6208,0x620A-0x620B,0x620D,0x6212,0x6217,0x621F,0x6222,0x6224-0x6225,0x622A,0x622C,0x622E,0x623D-0x623E,0x6248-0x6249,0x624C,0x6266,0x626C,0x626F,0x627C,0x6289,0x6291-0x6292,0x629A,0x62AB,0x62BF,0x62C4,0x62C7,0x62D2,0x62D9,0x62E3,0x62E8,0x62ED,0x62EF,0x62F3,0x631A,0x631E,0x6322-0x6324,0x6328,0x6339,0x633D,0x6342-0x6343,0x6345,0x6355,0x635E,0x6361,0x6363,0x6371,0x637A,0x6382,0x638F-0x6390,0x6396,0x63A3,0x63A9,0x63AC-0x63AE,0x63B0,0x63B3,0x63B7,0x63BC,0x63C6,0x63CE,0x63E0,0x63EA,0x63F6,0x63F8,0x63FD,0x63FF-0x6401,0x6405,0x640C,0x640F-0x6410,0x6414,0x6420,0x6426,0x642A,0x6434,0x643A,0x643D,0x643F,0x6444-0x6446,0x6448,0x644A,0x6452,0x6458,0x645E,0x646D,0x6478-0x6479,0x6482,0x6484,0x6491,0x64AC,0x64B5,0x64B7-0x64B8,0x64BC,0x64C0,0x64C5,0x64CE,0x64E2,0x64E4,0x6500,0x652B,0x6534-0x6535,0x6538,0x6549,0x655B,0x655D,0x656C,0x6572,0x6577,0x658B,0x6590-0x6591,0x6593,0x659B,0x659F,0x65A4,0x65A7,0x65C3,0x65C5-0x65C6,0x65CC,0x65CE,0x65D2,0x65D6-0x65D7,0x65E8,0x65ED,0x65EF,0x65F1,0x65F7,0x65FA,0x6600,0x6603,0x660A,0x6613,0x661D,0x662D,0x6631,0x6634,0x6636,0x663C,0x664B-0x664C,0x664F,0x6653-0x6657,0x6661,0x6664,0x6666,0x6670,0x6674,0x6676-0x6677,0x667A,0x667E,0x6684,0x668C,0x6691,0x669D,0x66AE,0x66B9,0x66BE,0x66D9,0x66DB-0x66DC,0x66E6,0x66F3,0x66FF,0x6715,0x673D,0x6746,0x6748,0x674F,0x6756,0x675E-0x675F,0x6769-0x676A,0x676F-0x6770,0x6772-0x6773,0x6775,0x6781,0x679A,0x67A2-0x67A3,0x67A5,0x67A7-0x67A8,0x67AB,0x67AD,0x67B0,0x67B3,0x67B5,0x67B7,0x67C3-0x67C4,0x67D2,0x67D8,0x67DD,0x67E9,0x67EC,0x67EF-0x67F1,0x67FF-0x6800,0x6808-0x680C,0x682A,0x6832-0x6833,0x683D,0x6840,0x6844,0x6846,0x6849,0x684E,0x6853,0x6855,0x6860,0x6862,0x6864,0x6866,0x6868-0x6869,0x686B,0x6874,0x6876-0x6877,0x6883,0x6886,0x6893,0x68A8,0x68AF-0x68B0,0x68B3,0x68B5,0x68C0,0x68C2,0x68D5,0x68D8,0x68DA,0x68E0,0x68FA,0x68FC,0x6901,0x6905,0x690B,0x690D,0x6910,0x6912,0x691F-0x6920,0x6924,0x692D,0x6930,0x6934,0x693D,0x6954,0x6957,0x695D,0x6963,0x6966,0x696B,0x6978-0x6979,0x6980,0x6984,0x6986-0x6989,0x698D,0x6994-0x6995,0x6998,0x699B,0x69A7-0x69A8,0x69AB,0x69AD,0x69B1,0x69B4,0x69B7,0x69BB,0x69CA,0x69CE,0x69D4,0x69E0,0x69F2,0x6A0A,0x6A17,0x6A1F,0x6A28,0x6A2F,0x6A31,0x6A35,0x6A3E,0x6A44,0x6A47,0x6A58,0x6A5B,0x6A61,0x6A65,0x6A71,0x6A79,0x6A7C,0x6A84,0x6A8E,0x6A91,0x6AA9,0x6AAC,0x6B20,0x6B24,0x6B32,0x6B37,0x6B3A,0x6B46,0x6B49,0x6B4C,0x6B67,0x6B7C,0x6B82-0x6B84,0x6B86-0x6B87,0x6B89-0x6B8A,0x6B92-0x6B93,0x6B9A-0x6B9B,0x6BAA,0x6BB3-0x6BB4,0x6BC2,0x6BC5,0x6BD3,0x6BD6-0x6BD7,0x6BD9,0x6BE1,0x6BEA,0x6BEF,0x6BF5,0x6BFD,0x6C05-0x6C07,0x6C0D,0x6C16,0x6C18-0x6C1B,0x6C1F,0x6C21-0x6C22,0x6C26-0x6C2A,0x6C2E-0x6C30,0x6C32,0x6C46,0x6C4A,0x6C50,0x6C54,0x6C5B-0x6C5C,0x6C5E,0x6C61,0x6C68,0x6C70,0x6C72,0x6C74,0x6C79,0x6C81,0x6C85,0x6C90,0x6C94,0x6C9B,0x6CA3-0x6CA5,0x6CA9-0x6CAB,0x6CAD,0x6CB2,0x6CB9,0x6CBC-0x6CBD,0x6CBF,0x6CD3,0x6CD7,0x6CE0-0x6CE1,0x6CEE,0x6CF1,0x6CF3,0x6CF6,0x6CF8,0x6CFB-0x6CFC,0x6CFE,0x6D04,0x6D0C,0x6D0E,0x6D19,0x6D25,0x6D27,0x6D31,0x6D33,0x6D39,0x6D43,0x6D46-0x6D48,0x6D4A,0x6D4E-0x6D4F,0x6D54,0x6D59,0x6D5E,0x6D60,0x6D63,0x6D66,0x6D6E-0x6D6F,0x6D74,0x6D7C,0x6D95,0x6D9B,0x6D9D,0x6D9F-0x6DA0,0x6DA4,0x6DA7-0x6DA8,0x6DAB,0x6DAF,0x6DB5,0x6DB8,0x6DBF-0x6DC0,0x6DC4-0x6DC7,0x6DD8,0x6DDD-0x6DDE,0x6DE4,0x6DF9,0x6DFC,0x6E0A,0x6E0C-0x6E0E,0x6E10,0x6E14,0x6E16-0x6E17,0x6E1A,0x6E1D,0x6E21,0x6E23-0x6E24,0x6E2D,0x6E32,0x6E3A,0x6E44,0x6E4E,0x6E56,0x6E58,0x6E7F,0x6E85-0x6E86,0x6E8F-0x6E90,0x6E9C,0x6EA2,0x6EA7,0x6EB7,0x6EBB,0x6EBD,0x6EC1,0x6ECF,0x6ED3-0x6ED4,0x6ED7,0x6EDE-0x6EE0,0x6EE2,0x6EE4-0x6EE6,0x6EE9,0x6EF4,0x6EF9,0x6F09,0x6F13-0x6F14,0x6F20,0x6F24,0x6F29-0x6F2A,0x6F2D,0x6F31,0x6F33,0x6F36,0x6F3E,0x6F46-0x6F47,0x6F4B,0x6F4D,0x6F5E,0x6F72,0x6F74,0x6F78,0x6F7A,0x6F88,0x6F8C,0x6F8E,0x6F9C,0x6FA7,0x6FC9,0x6FD1-0x6FD2,0x6FE0,0x6FEE,0x701A-0x701B,0x7023,0x7035,0x704F,0x705E,0x7076,0x7078,0x707C,0x7080,0x7089,0x7092,0x7099,0x709C-0x709D,0x70AB-0x70AD,0x70B1,0x70B3,0x70B7,0x70BB-0x70BD,0x70C0,0x70C3,0x70CA,0x70D8,0x70E6,0x70E8-0x70E9,0x70EB-0x70EC,0x70EF,0x70F7,0x70F9,0x70FD,0x710A,0x7110,0x7113,0x7115,0x7119-0x711A,0x7130,0x7145,0x714A,0x714C,0x714E,0x715C,0x715E,0x7164,0x716E,0x7172-0x7173,0x7178,0x717A,0x717D,0x718F,0x7194,0x7198,0x71A0,0x71B3,0x71B5,0x71B9,0x71CE,0x71D5,0x71E7,0x71EE,0x7230,0x7235-0x7236,0x724D,0x7252,0x7256,0x725D,0x7261,0x7266-0x7267,0x726E-0x726F,0x7272,0x7275,0x727A,0x727E-0x7281,0x728A-0x728B,0x728F,0x729F,0x72AC-0x72AD,0x72B0,0x72B7-0x72B9,0x72C1,0x72C8,0x72CD-0x72CE,0x72D0,0x72D2,0x72D9,0x72DE,0x72E8-0x72E9,0x72ED-0x72F4,0x72F7-0x72F8,0x72FA,0x7301,0x7303,0x730A,0x7315-0x7316,0x731C-0x731E,0x7321-0x7322,0x7325,0x7329-0x732A,0x732C,0x732E,0x7331,0x7337-0x7339,0x733E-0x733F,0x734D,0x7350,0x7352,0x7357,0x736D,0x736F,0x7389,0x738E,0x7391,0x7396,0x739B,0x73AB,0x73AE,0x73B2-0x73B3,0x73B7,0x73BA-0x73BB,0x73C0,0x73C2,0x73C8-0x73CA,0x73CF-0x73D1,0x73D9,0x73E0,0x73E5,0x73E7,0x7409-0x740A,0x740F-0x7410,0x741A-0x741B,0x7425-0x7426,0x742A,0x742C,0x742E,0x7430,0x7435-0x7436,0x7441,0x7455,0x745A-0x745C,0x746D,0x7470,0x7476-0x7477,0x747E,0x7480-0x7481,0x7483,0x7487,0x748B,0x748E,0x7490,0x749C,0x749E,0x74A7-0x74A9,0x74BA,0x74DE,0x74E2-0x74E3,0x74EF,0x74F4,0x74F7,0x750D,0x750F,0x7511,0x7513,0x7519,0x7525,0x752F,0x7533,0x753B,0x7540,0x7545,0x7548,0x754B,0x754E-0x754F,0x7554,0x755B,0x7566,0x7572,0x7574,0x757F,0x7583,0x7586,0x758F,0x7596,0x759A,0x759D,0x75A0-0x75A1,0x75A3-0x75A5,0x75AB-0x75AC,0x75AF-0x75B3,0x75BD-0x75BE,0x75C2-0x75C4,0x75C7-0x75CA,0x75CD,0x75D2,0x75D4,0x75D6,0x75D8,0x75DE,0x75E2-0x75E4,0x75E7-0x75E8,0x75EB,0x75F0-0x75F1,0x75F4,0x75F9,0x75FC,0x75FF-0x7601,0x7603,0x7605,0x760A,0x760C,0x7610,0x7617-0x7619,0x761B,0x7620,0x7622,0x7624,0x7626,0x7629-0x762B,0x762D,0x7630,0x7634,0x7638,0x763C,0x763E-0x7640,0x7643,0x764D,0x7654,0x7656,0x765C,0x7663,0x766B,0x766F,0x7682,0x7686,0x7688,0x768E,0x7691,0x7699,0x76B1-0x76B2,0x76C2,0x76C8,0x76CA,0x76CF-0x76D0,0x76D4,0x76D7,0x76E5,0x76F1,0x7704,0x7707,0x7709,0x770D,0x771A,0x7722,0x7726,0x7728,0x772F,0x7735-0x7736,0x773A,0x7741,0x7750-0x7751,0x775A-0x775B,0x7765-0x7766,0x7768,0x776C,0x7779,0x7784-0x7785,0x778C-0x778E,0x7792,0x779F,0x77A9,0x77B0,0x77B3,0x77BB,0x77BD,0x77CD,0x77D7,0x77E2,0x77E7,0x77E9,0x77EB-0x77EC,0x77EE,0x77F6,0x77FD-0x77FE,0x7800,0x7802,0x7811-0x7812,0x7817-0x7818,0x781A,0x781C,0x7823,0x7826-0x7827,0x782D,0x7837,0x7839-0x783C,0x783E,0x7840,0x7847,0x7852,0x7856-0x7857,0x786D,0x7877,0x787C,0x7887,0x7889,0x788D,0x7891,0x7893,0x7897-0x7898,0x789A-0x789C,0x78A5,0x78A7,0x78B2-0x78B4,0x78B9,0x78BE,0x78CA-0x78CB,0x78D0,0x78D4-0x78D5,0x78D9,0x78E8,0x78EC,0x78F2,0x78F4,0x7901,0x7905,0x7913,0x791E,0x7934,0x793B-0x793C,0x7940,0x7946,0x7949,0x7957,0x795A-0x795C,0x795F,0x7965,0x7967,0x796F,0x7977-0x7978,0x797A,0x7980,0x7984,0x798A,0x798F,0x799A,0x79A7,0x79B9-0x79BA,0x79BD-0x79BE,0x79C3,0x79C6,0x79C9,0x79D5,0x79E3,0x79E7,0x79E9,0x79EB,0x79ED,0x79FD,0x7A00,0x7A02-0x7A03,0x7A06,0x7A14,0x7A17,0x7A1A,0x7A23,0x7A33,0x7A3B-0x7A3C,0x7A46,0x7A57,0x7A78,0x7A84,0x7A86,0x7A88,0x7A8D,0x7A91,0x7A95,0x7A9F-0x7AA0,0x7AA6,0x7AAD,0x7AB3,0x7ABF,0x7AD6,0x7ADE,0x7AE3,0x7AE6,0x7AED,0x7AF9,0x7AFD,0x7AFF,0x7B03-0x7B04,0x7B06,0x7B08,0x7B0A,0x7B14-0x7B15,0x7B19,0x7B1B,0x7B1E,0x7B20,0x7B25,0x7B2A-0x7B2B,0x7B31,0x7B33,0x7B38,0x7B3A,0x7B3E,0x7B45,0x7B47,0x7B4C,0x7B4F-0x7B51,0x7B58,0x7B5A,0x7B5D,0x7B62,0x7B6E,0x7B71-0x7B72,0x7B75,0x7B7B,0x7B7E,0x7B85,0x7B8D,0x7B94-0x7B95,0x7B9C-0x7B9D,0x7BA6-0x7BAB,0x7BAD,0x7BB1,0x7BC1,0x7BC6,0x7BCC,0x7BD1,0x7BD3,0x7BD9-0x7BDA,0x7BDD,0x7BE5,0x7BEA,0x7BEE,0x7BF1,0x7BF7,0x7BFC,0x7C0B-0x7C0C,0x7C0F,0x7C16,0x7C1F,0x7C26-0x7C27,0x7C38,0x7C40,0x7C7C-0x7C7D,0x7C91-0x7C92,0x7C95,0x7C9C-0x7C9F,0x7CA4,0x7CAA,0x7CB1-0x7CB3,0x7CBC-0x7CBD,0x7CC7-0x7CC8,0x7CCA,0x7CCC-0x7CCD,0x7CD5,0x7CD7,0x7CD9,0x7CE0,0x7CE8,0x7CEF,0x7D0A,0x7D2B,0x7D77,0x7DA6,0x7E3B,0x7E9F-0x7EA1,0x7EA3,0x7EA8-0x7EAD,0x7EB0,0x7EB8-0x7EBA,0x7EBE,0x7EC0-0x7EC2,0x7EC5,0x7EC7,0x7EC9-0x7ECC,0x7ECE,0x7ED0-0x7ED2,0x7ED4,0x7ED7-0x7ED8,0x7EDA-0x7EDB,0x7EDE,0x7EE0-0x7EE1,0x7EE5-0x7EE9,0x7EEB,0x7EEE-0x7EEF,0x7EF1,0x7EF3-0x7EF4,0x7EF6-0x7EF8,0x7EFA-0x7EFB,0x7EFD-0x7EFF,0x7F01-0x7F08,0x7F0B-0x7F0D,0x7F11-0x7F12,0x7F14-0x7F15,0x7F18-0x7F1D,0x7F1F,0x7F21-0x7F28,0x7F2B-0x7F2E,0x7F30-0x7F31,0x7F33,0x7F38,0x7F42,0x7F44-0x7F45,0x7F50,0x7F54-0x7F55,0x7F58,0x7F5F,0x7F61,0x7F68-0x7F69,0x7F72,0x7F74,0x7F79,0x7F7E,0x7F81,0x7F8A,0x7F8C,0x7F94,0x7F9A,0x7F9D,0x7F9F,0x7FAF-0x7FB0,0x7FB2,0x7FBC,0x7FBF,0x7FC5,0x7FCA,0x7FCC,0x7FCE,0x7FD4-0x7FD5,0x7FD8,0x7FE1,0x7FE5-0x7FE6,0x7FE9,0x7FF0-0x7FF1,0x7FF3,0x7FFC,0x8000,0x8004,0x800B,0x8012,0x8014,0x8016,0x8018,0x801C,0x8020,0x8022,0x8025-0x8027,0x8029-0x802A,0x8031,0x8035,0x803B,0x803D,0x803F,0x8042-0x8043,0x8046,0x804B-0x804D,0x805A,0x8069,0x807F-0x8080,0x8087,0x808C,0x8093,0x8096,0x8098,0x809A-0x809B,0x809D,0x809F-0x80A0,0x80A4,0x80AA,0x80B1,0x80B4,0x80BC-0x80C1,0x80C3-0x80C4,0x80CE,0x80D9-0x80DB,0x80E4-0x80E5,0x80E7-0x80E8,0x80EA-0x80ED,0x80F0,0x80F4,0x80FC,0x8102,0x8106,0x810A,0x810D-0x810E,0x8110,0x8112,0x8116,0x812C,0x8132,0x8136,0x8146,0x8148,0x814B,0x8150-0x8151,0x8153,0x8155,0x8159-0x815A,0x8160,0x8165,0x8169,0x816D,0x8170,0x8174,0x8179-0x817D,0x8182,0x8188,0x818F,0x8191,0x819B-0x819D,0x81A3,0x81A8,0x81B3,0x81BA,0x81C0-0x81C1,0x81C3,0x81C6,0x81CA,0x81CC,0x81EC,0x81FB-0x81FC,0x8200-0x8201,0x8205-0x8206,0x8210,0x821B,0x821E-0x821F,0x8222-0x8223,0x8228,0x822B,0x822D,0x822F-0x8230,0x8234-0x8238,0x823B,0x823E,0x8244,0x8247,0x8249,0x824B,0x824F,0x825A,0x8268,0x8270,0x8273,0x8279-0x827A,0x8284,0x8288,0x828A,0x828F,0x8291,0x8297,0x8299,0x829C-0x829D,0x82A1,0x82A8,0x82AC,0x82AF-0x82B0,0x82B7-0x82B9,0x82BD,0x82C1,0x82C4,0x82C7-0x82C8,0x82CA-0x82CC,0x82CE,0x82D4,0x82D8,0x82DC,0x82DF-0x82E1,0x82F7,0x8302,0x8305-0x8306,0x8309,0x830C,0x830E-0x830F,0x8314-0x8315,0x8317,0x831A,0x8328,0x832F,0x8331,0x8333-0x8335,0x8338-0x833A,0x833C,0x8340,0x8346-0x8347,0x834F-0x8350,0x8354,0x835A,0x835C,0x835E-0x835F,0x8366-0x8367,0x8369-0x836E,0x8377-0x8378,0x837B,0x8385,0x8392-0x8393,0x839B,0x83AA,0x83B0,0x83B2-0x83B4,0x83B6,0x83B8-0x83BA,0x83BC,0x83C1,0x83C7,0x83CA,0x83D4,0x83D6,0x83D8,0x83DD,0x83DF-0x83E1,0x83EA,0x83F0-0x83F1,0x8403-0x8404,0x840B,0x840D-0x840F,0x8418,0x841C-0x841D,0x8424,0x8426-0x8427,0x8431,0x8438,0x843C,0x8446,0x8451,0x8459,0x845B,0x8469,0x846B,0x8473,0x8475,0x8478,0x847A,0x8482,0x8487-0x8489,0x848C,0x848E,0x8497,0x84B4,0x84B8-0x84BA,0x84C4,0x84CD,0x84D0,0x84D3,0x84D6,0x84DF-0x84E0,0x84E3,0x84E5-0x84E6,0x84EC,0x84F0,0x850C,0x8517,0x852C,0x8537-0x853C,0x8556,0x8559,0x8564,0x8568,0x8572,0x8574,0x857B,0x857E,0x8585,0x8587,0x858F,0x85A4,0x85A8,0x85AA,0x85AE-0x85B0,0x85B7,0x85B9,0x85C1,0x85D3,0x85D5,0x85DC,0x85E9,0x85FB,0x8605,0x8611,0x8629,0x8638,0x863C,0x864D-0x864F,0x8654,0x865A,0x865E,0x8662,0x866C,0x866E,0x8671,0x867A-0x867C,0x867F-0x8682,0x868A-0x868B,0x868D,0x8693,0x869C,0x86A7-0x86AA,0x86AC,0x86AF,0x86B1,0x86B6,0x86C0,0x86C4,0x86C9-0x86CB,0x86CE-0x86D0,0x86D4,0x86D8,0x86DB,0x86DF,0x86ED,0x86F0-0x86F4,0x86F9,0x8700,0x8702-0x8703,0x8707-0x870A,0x8717-0x8718,0x871C,0x871E,0x8722-0x8723,0x8725,0x873F,0x8747-0x8749,0x874C,0x8753,0x8757,0x8760,0x8763,0x876E,0x8770,0x8774,0x877B-0x877E,0x8782,0x8788,0x878B,0x8793,0x8797,0x879F,0x87A8,0x87AC-0x87AD,0x87AF,0x87B3,0x87B5,0x87BA,0x87BD,0x87CB,0x87D1,0x87D3,0x87DB,0x87E5,0x87EA,0x87EE,0x87F9,0x87FE,0x880A,0x8813,0x8815,0x8832,0x8839,0x8844-0x8845,0x884D,0x8854,0x8857,0x8862-0x8864,0x8869,0x886B-0x886C,0x8872,0x8877,0x887D-0x887E,0x8881,0x8884,0x8888,0x888B,0x88AD,0x88B1,0x88C6,0x88C9,0x88CE,0x88D4-0x88D5,0x88D8,0x88DF,0x88E3-0x88E5,0x88F0-0x88F1,0x88F8-0x88F9,0x88FE,0x8902,0x8910,0x8912-0x8913,0x8919,0x891B,0x8921,0x892B,0x8930,0x8934,0x8941,0x8944,0x895E-0x895F,0x8966,0x897B,0x8986,0x89C5,0x89C7,0x89CA-0x89CC,0x89CE-0x89D1,0x89DA,0x89DE,0x89E5-0x89E6,0x89EB,0x89EF,0x8A3E,0x8A48,0x8A89,0x8A93,0x8B07,0x8B26,0x8B66,0x8B6C,0x8BA0,0x8BA3,0x8BA5-0x8BA7,0x8BAA-0x8BAB,0x8BB3-0x8BB6,0x8BB9,0x8BBD,0x8BC0,0x8BC2-0x8BC3,0x8BC5,0x8BCA-0x8BCC,0x8BCE,0x8BD1-0x8BD4,0x8BD6-0x8BD7,0x8BD9-0x8BDC,0x8BDE-0x8BE4,0x8BE6-0x8BE9,0x8BEB-0x8BEC,0x8BEE,0x8BF1-0x8BF3,0x8BF8,0x8BFC-0x8BFD,0x8BFF-0x8C00,0x8C02,0x8C04-0x8C05,0x8C07,0x8C0A,0x8C0C,0x8C0E-0x8C10,0x8C12-0x8C1B,0x8C1D,0x8C1F,0x8C21,0x8C23-0x8C2B,0x8C2D,0x8C2F-0x8C30,0x8C32-0x8C36,0x8C47,0x8C4C,0x8C55,0x8C62,0x8C79,0x8C82,0x8C85,0x8C94,0x8C98,0x8D1E-0x8D1F,0x8D21,0x8D24,0x8D26-0x8D2A,0x8D2C,0x8D2E-0x8D2F,0x8D31,0x8D33,0x8D36-0x8D37,0x8D3A-0x8D3B,0x8D3D,0x8D3F-0x8D42,0x8D45-0x8D48,0x8D4A-0x8D4E,0x8D50,0x8D53-0x8D55,0x8D58-0x8D59,0x8D5C-0x8D5D,0x8D61-0x8D64,0x8D67,0x8D6D,0x8D73-0x8D75,0x8D8B,0x8D94,0x8DB1,0x8DB4,0x8DB8,0x8DBA,0x8DBE,0x8DC4,0x8DC6,0x8DCE-0x8DCF,0x8DD6-0x8DD7,0x8DDA,0x8DEA,0x8DF5,0x8DF7-0x8DFB,0x8DFD,0x8E0A,0x8E0C,0x8E0F,0x8E1D-0x8E1F,0x8E2C,0x8E2E-0x8E2F,0x8E35,0x8E3A,0x8E3D,0x8E40-0x8E41,0x8E47-0x8E49,0x8E4B,0x8E51-0x8E52,0x8E59,0x8E69,0x8E6C,0x8E6F-0x8E70,0x8E7C,0x8E8F-0x8E90,0x8E9C,0x8E9E,0x8EAC,0x8EAF,0x8ECE,0x8F69,0x8F6B,0x8F6D,0x8F71-0x8F73,0x8F75-0x8F7C,0x8F7E-0x8F7F,0x8F81-0x8F82,0x8F84-0x8F86,0x8F88-0x8F8B,0x8F8E,0x8F90,0x8F94-0x8F96,0x8F98-0x8F9A,0x8F9C,0x8FAB,0x8FB1,0x8FB6,0x8FC2,0x8FC4,0x8FC8,0x8FD3,0x8FD5,0x8FDD,0x8FE2,0x8FE8,0x8FEA,0x8FF3,0x8FF8,0x9005,0x900B,0x900D,0x9011-0x9012,0x9016,0x901D,0x9026,0x902D,0x9035-0x9036,0x9038,0x903B-0x903C,0x9044,0x904F-0x9052,0x9058,0x905B,0x9062,0x9065,0x9068,0x906E,0x9074,0x907F-0x9080,0x9082-0x9083,0x9088,0x9095,0x9097,0x9099,0x909D,0x90A1,0x90AC,0x90AE-0x90B1,0x90B3-0x90B6,0x90B8,0x90BE,0x90C1,0x90CA,0x90CF-0x90D1,0x90D3,0x90DB-0x90DC,0x90E6-0x90E7,0x90EB,0x90EF,0x90F8,0x90FE,0x9102,0x9104,0x9119,0x911E,0x9122-0x9123,0x912F,0x9143,0x9146,0x9149-0x914C,0x914E-0x914F,0x9157,0x915A,0x915D-0x915E,0x9163-0x9165,0x9169,0x916F-0x9172,0x9174-0x9176,0x9179,0x917D,0x9185,0x918C-0x918D,0x9190-0x9191,0x919A,0x91A2-0x91A3,0x91AA,0x91AD,0x91AF,0x91B4-0x91B5,0x91BA,0x91C9-0x91CA,0x91DC,0x9274,0x928E,0x92C8,0x933E,0x936A,0x938F,0x93CA,0x943E,0x9485-0x9487,0x9489-0x948E,0x9490,0x9492-0x9493,0x9495,0x9499-0x949D,0x94A0-0x94A1,0x94A3-0x94A4,0x94A7-0x94AC,0x94B0,0x94B2-0x94BA,0x94BC-0x94BE,0x94C0,0x94C2-0x94C4,0x94C6,0x94C8-0x94C9,0x94CB-0x94CE,0x94D0-0x94D2,0x94D5-0x94D9,0x94DC-0x94E2,0x94E7-0x94E9,0x94EC,0x94EE-0x94F5,0x94F7-0x94F9,0x94FC,0x9502-0x9509,0x950B-0x950F,0x9511-0x9514,0x9516-0x9518,0x951A-0x951B,0x951D-0x951F,0x9521-0x9523,0x9525-0x9526,0x9528-0x952B,0x952D,0x952F-0x9532,0x9534-0x953A,0x953C,0x953E-0x9542,0x9544-0x9546,0x9549-0x954A,0x954C-0x954F,0x9551-0x9554,0x9557-0x9559,0x955B-0x955F,0x9562-0x9565,0x9567-0x956D,0x956F-0x9573,0x9576,0x95EB,0x95F1,0x95F3,0x95F6,0x95F8,0x95FA,0x95FC,0x95FE,0x9600-0x9606,0x9608-0x960E,0x9610-0x9612,0x9615-0x9617,0x961C-0x961D,0x9621,0x962A,0x9631,0x9634,0x9636,0x963C,0x9645,0x9649,0x964C,0x9654,0x965B,0x9661,0x9667-0x9668,0x9672,0x9677,0x9685,0x9688,0x968D,0x9699,0x969C,0x96B3,0x96C1,0x96CC-0x96CF,0x96D2,0x96D5,0x96E0,0x96E8,0x96EF,0x96F3,0x96F9,0x96FE,0x9701,0x9704,0x9706,0x9708-0x9709,0x970E-0x970F,0x9713,0x9716,0x971E,0x972A,0x972D,0x9739,0x9756,0x975B,0x9765,0x9773-0x9774,0x9776,0x977C,0x9785,0x978D,0x9791-0x9792,0x97AD,0x97AF,0x97B2,0x97E6-0x97E7,0x97EA-0x97ED,0x97F5-0x97F6,0x9877-0x9879,0x987C-0x987E,0x9880-0x9881,0x9883,0x9885,0x988A,0x988D,0x988F-0x9890,0x9893-0x9894,0x9896,0x989A-0x989C,0x989E-0x989F,0x98A2,0x98A5-0x98A7,0x98D1,0x98D3,0x98D5,0x98D9-0x98DA,0x98E8,0x990D,0x9954-0x9955,0x9963,0x9965,0x9968-0x996C,0x996E-0x9972,0x9974-0x9975,0x9977,0x997A,0x997C-0x997D,0x9980,0x9984-0x9985,0x998A-0x998B,0x998D,0x998F-0x9992,0x9994,0x9999,0x99A8,0x9A6D,0x9A6F-0x9A71,0x9A73-0x9A7F,0x9A81,0x9A84-0x9A86,0x9A88,0x9A8A-0x9A8B,0x9A8F-0x9A93,0x9A96,0x9A98,0x9A9B-0x9A9F,0x9AA1-0x9AA5,0x9AA7-0x9AA8,0x9AB6-0x9AB7,0x9ABA,0x9ABC,0x9AC0,0x9AC5,0x9ACC,0x9AD1,0x9AD3,0x9AE1,0x9AE6,0x9AEB,0x9AED,0x9AF9,0x9B03,0x9B08,0x9B0F,0x9B1F,0x9B23,0x9B2F,0x9B43,0x9B45,0x9B47-0x9B49,0x9B4D,0x9B4F,0x9B51,0x9B54,0x9C7C,0x9C7F,0x9C82,0x9C86-0x9C88,0x9C8B,0x9C8D-0x9C8E,0x9C90,0x9C92,0x9C94-0x9C95,0x9C9A-0x9C9C,0x9C9E-0x9CA6,0x9CA8-0x9CA9,0x9CAB,0x9CAE,0x9CB0-0x9CB8,0x9CBA-0x9CBD,0x9CC4-0x9CC7,0x9CCA-0x9CD0,0x9CD3-0x9CD9,0x9CDC-0x9CDF,0x9CE2,0x9E20-0x9E22,0x9E25-0x9E26,0x9E28-0x9E2D,0x9E2F,0x9E31-0x9E33,0x9E35-0x9E3A,0x9E3D,0x9E41-0x9E43,0x9E45-0x9E4C,0x9E4E,0x9E51,0x9E55,0x9E57,0x9E5A-0x9E5C,0x9E5E,0x9E63-0x9E64,0x9E66-0x9E6D,0x9E70-0x9E71,0x9E73,0x9E7E-0x9E7F,0x9E82,0x9E88,0x9E8B,0x9E92-0x9E93,0x9E9D,0x9EB4,0x9EB8,0x9EBE,0x9EC9,0x9ECD-0x9ECF,0x9ED4,0x9ED8,0x9EDB-0x9EDC,0x9EDF-0x9EE0,0x9EE2,0x9EE5,0x9EE9-0x9EEA,0x9EEF,0x9EFB-0x9EFC,0x9F0B,0x9F0D,0x9F10,0x9F13,0x9F17,0x9F19,0x9F20,0x9F22,0x9F2C,0x9F2F,0x9F37,0x9F39,0x9F3B,0x9F3D-0x9F3E,0x9F44,0x9F51,0x9F7F-0x9F80,0x9F83-0x9F87,0x9F89-0x9F8C,0x9F9A-0x9F9B,0x9FA0 diff --git a/packs/zh-Hans/locales/zh-Hans/manifest.ini b/packs/zh-Hans/locales/zh-Hans/manifest.ini index 000447c5..4b1253f1 100644 --- a/packs/zh-Hans/locales/zh-Hans/manifest.ini +++ b/packs/zh-Hans/locales/zh-Hans/manifest.ini @@ -2,7 +2,8 @@ kind=locale id=zh-Hans display_name=Simplified Chinese native_name=简体中文 -ui_font_pack=zh-hans-cjk -content_font_pack=zh-hans-cjk +ui_font_pack=zh-hans-core +content_font_pack=zh-hans-core +preferred_content_supplement_packs=zh-hans-ext ime_pack=zh-hans-pinyin strings=strings.tsv diff --git a/packs/zh-Hans/package.ini b/packs/zh-Hans/package.ini index b35e49ce..a201787e 100644 --- a/packs/zh-Hans/package.ini +++ b/packs/zh-Hans/package.ini @@ -3,7 +3,7 @@ id=zh-Hans package_type=locale-bundle version=1.0.0 display_name=Simplified Chinese -summary=Full Simplified Chinese locale bundle with external CJK font coverage and the built-in Pinyin IME backend. +summary=Tiered Simplified Chinese locale bundle with a fast core font, an on-demand extension font, and the built-in Pinyin IME backend. description=DESCRIPTION.txt readme=README.md author=Trail Mate diff --git a/platform/esp/arduino_common/include/ble/ble_manager.h b/platform/esp/arduino_common/include/ble/ble_manager.h index 3c045c49..f70b788a 100644 --- a/platform/esp/arduino_common/include/ble/ble_manager.h +++ b/platform/esp/arduino_common/include/ble/ble_manager.h @@ -22,7 +22,7 @@ class BleService { public: virtual ~BleService() = default; - virtual void start() = 0; + virtual bool start() = 0; virtual void stop() = 0; virtual void update() = 0; virtual bool getPairingStatus(BlePairingStatus* out) const diff --git a/platform/esp/arduino_common/include/ble/meshcore_ble.h b/platform/esp/arduino_common/include/ble/meshcore_ble.h index e8259e10..c92a1e6f 100644 --- a/platform/esp/arduino_common/include/ble/meshcore_ble.h +++ b/platform/esp/arduino_common/include/ble/meshcore_ble.h @@ -27,7 +27,7 @@ class MeshCoreBleService : public BleService, MeshCoreBleService(app::IAppBleFacade& ctx, const std::string& device_name); ~MeshCoreBleService() override; - void start() override; + bool start() override; void stop() override; void update() override; diff --git a/platform/esp/arduino_common/include/ble/meshtastic_ble.h b/platform/esp/arduino_common/include/ble/meshtastic_ble.h index 39e8c431..36cd95e9 100644 --- a/platform/esp/arduino_common/include/ble/meshtastic_ble.h +++ b/platform/esp/arduino_common/include/ble/meshtastic_ble.h @@ -35,7 +35,7 @@ class MeshtasticBleService : public BleService, MeshtasticBleService(app::IAppBleFacade& ctx, const std::string& device_name); ~MeshtasticBleService() override; - void start() override; + bool start() override; void stop() override; void update() override; diff --git a/platform/esp/arduino_common/include/lv_conf.h b/platform/esp/arduino_common/include/lv_conf.h index b11f4352..8b00a529 100644 --- a/platform/esp/arduino_common/include/lv_conf.h +++ b/platform/esp/arduino_common/include/lv_conf.h @@ -41,12 +41,11 @@ * - LV_STDLIB_CUSTOM: Implement the functions externally * * Note: - * Original LilyGoLib used LV_STDLIB_CUSTOM with a custom implementation - * of lv_malloc_core/lv_free_core in LV_Helper_v9.cpp. To simplify and - * avoid linker issues, switch to LV_STDLIB_CLIB so LVGL uses the C - * library's malloc/free internally. + * Keep LVGL on LV_STDLIB_CUSTOM so large runtime objects such as external + * binfont packs can prefer PSRAM while small control allocations stay in + * internal RAM. The custom allocator lives in LV_Helper_v9.cpp. */ -#define LV_USE_STDLIB_MALLOC LV_STDLIB_CLIB +#define LV_USE_STDLIB_MALLOC LV_STDLIB_CUSTOM #define LV_USE_STDLIB_STRING LV_STDLIB_BUILTIN #define LV_USE_STDLIB_SPRINTF LV_STDLIB_BUILTIN diff --git a/platform/esp/arduino_common/include/platform/esp/arduino_common/app_tasks.h b/platform/esp/arduino_common/include/platform/esp/arduino_common/app_tasks.h index 3e97a8d3..bbc52c6a 100644 --- a/platform/esp/arduino_common/include/platform/esp/arduino_common/app_tasks.h +++ b/platform/esp/arduino_common/include/platform/esp/arduino_common/app_tasks.h @@ -66,6 +66,16 @@ class AppTasks return radio_rx_queue_; } + static TaskHandle_t getRadioTaskHandle() + { + return radio_task_handle_; + } + + static TaskHandle_t getMeshTaskHandle() + { + return mesh_task_handle_; + } + /** * @brief Pause radio + mesh tasks (for exclusive radio modes like walkie-talkie) */ diff --git a/platform/esp/arduino_common/include/platform/esp/arduino_common/gps/gps_service.h b/platform/esp/arduino_common/include/platform/esp/arduino_common/gps/gps_service.h index 84f87a96..e9ba3b66 100644 --- a/platform/esp/arduino_common/include/platform/esp/arduino_common/gps/gps_service.h +++ b/platform/esp/arduino_common/include/platform/esp/arduino_common/gps/gps_service.h @@ -39,7 +39,8 @@ class GpsService void setMotionIdleTimeout(uint32_t timeout_ms); void setMotionSensorId(uint8_t sensor_id); TaskHandle_t getTaskHandle() const { return gps_task_handle_; } - bool isEnabled() const { return !gps_disabled_ && gps_board_ != nullptr; } + TaskHandle_t getMotionTaskHandle() const { return motion_task_handle_; } + bool isEnabled() const { return !gps_disabled_ && gps_ready_; } bool isPowered() const { return gps_powered_; } uint32_t getLastMotionMs() const; @@ -72,6 +73,7 @@ class GpsService bool gps_time_synced_ = false; bool gps_powered_ = false; bool gps_disabled_ = false; + bool gps_ready_ = false; MotionConfig motion_config_{}; MotionPolicy motion_policy_{}; diff --git a/platform/esp/arduino_common/include/platform/esp/arduino_common/memory_diag.h b/platform/esp/arduino_common/include/platform/esp/arduino_common/memory_diag.h new file mode 100644 index 00000000..f339a83e --- /dev/null +++ b/platform/esp/arduino_common/include/platform/esp/arduino_common/memory_diag.h @@ -0,0 +1,9 @@ +#pragma once + +namespace platform::esp::arduino_common::memory_diag +{ + +void logHeapSnapshot(const char* stage); +void logTaskSnapshot(const char* stage); + +} // namespace platform::esp::arduino_common::memory_diag diff --git a/platform/esp/arduino_common/src/LV_Helper_v9.cpp b/platform/esp/arduino_common/src/LV_Helper_v9.cpp index c9e388e3..b1fdc5a8 100644 --- a/platform/esp/arduino_common/src/LV_Helper_v9.cpp +++ b/platform/esp/arduino_common/src/LV_Helper_v9.cpp @@ -633,6 +633,38 @@ lv_indev_t* lv_get_encoder_indev() } #if LV_USE_STDLIB_MALLOC == LV_STDLIB_CUSTOM +namespace +{ +constexpr size_t kLvglLargeAllocThresholdBytes = 2048; + +bool lvgl_has_psram() +{ +#if HAS_PSRAM + return heap_caps_get_total_size(MALLOC_CAP_SPIRAM) > 0; +#else + return false; +#endif +} + +uint32_t lvgl_primary_caps(size_t size) +{ + if (lvgl_has_psram() && size >= kLvglLargeAllocThresholdBytes) + { + return MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT; + } + return MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT; +} + +uint32_t lvgl_secondary_caps(size_t size) +{ + if (lvgl_has_psram() && size >= kLvglLargeAllocThresholdBytes) + { + return MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT; + } + return MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT; +} +} // namespace + // LVGL 9.x custom memory management functions extern "C" void lv_mem_init(void) { @@ -662,7 +694,11 @@ extern "C" void lv_mem_remove_pool(lv_mem_pool_t pool) extern "C" void* lv_malloc_core(size_t size) { #if HAS_PSRAM - return ps_malloc(size); + if (size == 0) + { + return nullptr; + } + return heap_caps_malloc_prefer(size, 2, lvgl_primary_caps(size), lvgl_secondary_caps(size)); #else return malloc(size); #endif @@ -671,7 +707,13 @@ extern "C" void* lv_malloc_core(size_t size) extern "C" void* lv_realloc_core(void* p, size_t new_size) { #if HAS_PSRAM - return ps_realloc(p, new_size); + if (new_size == 0) + { + heap_caps_free(p); + return nullptr; + } + return heap_caps_realloc_prefer( + p, new_size, 2, lvgl_primary_caps(new_size), lvgl_secondary_caps(new_size)); #else return realloc(p, new_size); #endif @@ -679,7 +721,11 @@ extern "C" void* lv_realloc_core(void* p, size_t new_size) extern "C" void lv_free_core(void* p) { +#if HAS_PSRAM + heap_caps_free(p); +#else free(p); +#endif } extern "C" void lv_mem_monitor_core(lv_mem_monitor_t* mon_p) diff --git a/platform/esp/arduino_common/src/app_runtime_bootstrap_support.cpp b/platform/esp/arduino_common/src/app_runtime_bootstrap_support.cpp index 7220f01b..d9ba4450 100644 --- a/platform/esp/arduino_common/src/app_runtime_bootstrap_support.cpp +++ b/platform/esp/arduino_common/src/app_runtime_bootstrap_support.cpp @@ -5,6 +5,8 @@ #include "ble/ble_manager.h" #include "platform/esp/arduino_common/app_context_platform_bindings.h" #include "platform/esp/arduino_common/app_event_runtime_support.h" +#include "platform/esp/arduino_common/memory_diag.h" +#include "ui/ui_boot.h" namespace platform::esp::arduino_common { @@ -28,12 +30,19 @@ bool bootstrapAppContext(app::AppContext& app_context, return false; } + memory_diag::logHeapSnapshot("bootstrap.after_app_context_init"); app::bindAppFacade(app_context); + ui::boot::set_log_line("Starting BLE..."); app_context.attachBleManager(platform::esp::arduino_common::createBleManager(app_context)); + memory_diag::logHeapSnapshot("bootstrap.after_ble_manager"); app_context.attachEventRuntimeHooks(platform::esp::arduino_common::makeAppEventRuntimeHooks()); + memory_diag::logHeapSnapshot("bootstrap.after_event_hooks"); result.app_context_bound = true; + ui::boot::set_log_line("Starting radio tasks..."); result.background_tasks = platform::esp::arduino_common::startBackgroundTasks(handles.lora_board, app_context.getMeshAdapter()); + memory_diag::logHeapSnapshot("bootstrap.after_background_tasks"); + memory_diag::logTaskSnapshot("bootstrap.after_background_tasks"); if (out_result) { diff --git a/platform/esp/arduino_common/src/ble/ble_manager.cpp b/platform/esp/arduino_common/src/ble/ble_manager.cpp index d72c2e2b..7d064fd6 100644 --- a/platform/esp/arduino_common/src/ble/ble_manager.cpp +++ b/platform/esp/arduino_common/src/ble/ble_manager.cpp @@ -9,9 +9,41 @@ #include #include #include +#include namespace ble { +namespace +{ +constexpr std::size_t kBleMinInternalFreeBytes = 48 * 1024; +constexpr std::size_t kBleMinInternalLargestBlockBytes = 20 * 1024; + +std::size_t ble_internal_free_bytes() +{ + return heap_caps_get_free_size(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); +} + +std::size_t ble_internal_largest_block_bytes() +{ + return heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); +} + +void log_ble_heap_snapshot(const char* stage) +{ + Serial.printf("[BLE][MEM] %s ram_free=%u ram_largest=%u psram_free=%u psram_largest=%u\n", + stage ? stage : "state", + static_cast(ble_internal_free_bytes()), + static_cast(ble_internal_largest_block_bytes()), + static_cast(heap_caps_get_free_size(MALLOC_CAP_SPIRAM)), + static_cast(heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM))); +} + +bool has_ble_startup_headroom() +{ + return ble_internal_free_bytes() >= kBleMinInternalFreeBytes && + ble_internal_largest_block_bytes() >= kBleMinInternalLargestBlockBytes; +} +} // namespace BleManager::BleManager(app::IAppBleFacade& ctx) : ctx_(ctx), @@ -109,9 +141,32 @@ void BleManager::restartService(chat::MeshProtocol protocol) const std::string device_name = buildDeviceName(protocol); - NimBLEDevice::init(device_name); + log_ble_heap_snapshot("before init"); + if (!has_ble_startup_headroom()) + { + active_protocol_ = protocol; + Serial.printf("[BLE] skip start protocol=%s reason=low_internal_ram free=%u largest=%u min_free=%u min_largest=%u\n", + chat::infra::meshProtocolSlug(protocol), + static_cast(ble_internal_free_bytes()), + static_cast(ble_internal_largest_block_bytes()), + static_cast(kBleMinInternalFreeBytes), + static_cast(kBleMinInternalLargestBlockBytes)); + return; + } + + if (!NimBLEDevice::init(device_name)) + { + active_protocol_ = protocol; + Serial.printf("[BLE] init failed protocol=%s name=%s\n", + chat::infra::meshProtocolSlug(protocol), + device_name.c_str()); + log_ble_heap_snapshot("init failed"); + return; + } + NimBLEDevice::setPower(ESP_PWR_LVL_P9); nimble_initialized_ = true; + log_ble_heap_snapshot("after init"); if (protocol == chat::MeshProtocol::MeshCore) { @@ -134,7 +189,16 @@ void BleManager::restartService(chat::MeshProtocol protocol) protocol_name, service_uuid, device_name.c_str()); - service_->start(); + if (!service_->start()) + { + Serial.printf("[BLE] service start failed protocol=%s name=%s\n", + protocol_name, + device_name.c_str()); + service_->stop(); + service_.reset(); + shutdownNimble(); + log_ble_heap_snapshot("service start failed"); + } } } diff --git a/platform/esp/arduino_common/src/ble/meshcore_ble.cpp b/platform/esp/arduino_common/src/ble/meshcore_ble.cpp index 6d99ee07..6f745505 100644 --- a/platform/esp/arduino_common/src/ble/meshcore_ble.cpp +++ b/platform/esp/arduino_common/src/ble/meshcore_ble.cpp @@ -799,13 +799,18 @@ const chat::meshcore::MeshCoreAdapter* MeshCoreBleService::meshCoreAdapter() con return static_cast(backend); } -void MeshCoreBleService::start() +bool MeshCoreBleService::start() { if (shared_core_) { shared_core_->reset(); } - NimBLEDevice::setMTU(185); + if (!NimBLEDevice::setMTU(185)) + { + Serial.printf("[BLE][meshcore] start failed reason=set_mtu mtu=%u\n", 185U); + stop(); + return false; + } if (kMeshCoreBleSecurityEnabled) { refreshBlePin(); @@ -815,6 +820,12 @@ void MeshCoreBleService::start() NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY); } setupService(); + if (!server_ || !service_ || !tx_char_ || !rx_char_) + { + Serial.printf("[BLE][meshcore] start failed reason=service_alloc\n"); + stop(); + return false; + } startAdvertising(); multi_acks_ = ctx_.getConfig().meshcore_config.meshcore_multi_acks ? 1 : 0; @@ -824,6 +835,7 @@ void MeshCoreBleService::start() { team->addIncomingDataObserver(this); } + return true; } void MeshCoreBleService::stop() diff --git a/platform/esp/arduino_common/src/ble/meshtastic_ble.cpp b/platform/esp/arduino_common/src/ble/meshtastic_ble.cpp index 889e10d8..238faab1 100644 --- a/platform/esp/arduino_common/src/ble/meshtastic_ble.cpp +++ b/platform/esp/arduino_common/src/ble/meshtastic_ble.cpp @@ -417,7 +417,7 @@ MeshtasticBleService::~MeshtasticBleService() stop(); } -void MeshtasticBleService::start() +bool MeshtasticBleService::start() { loadBleConfig(); loadModuleConfig(); @@ -426,16 +426,40 @@ void MeshtasticBleService::start() pairingModeName(ble_config_.mode), static_cast(ble_config_.fixed_pin)); NimBLEDevice::setPower(ESP_PWR_LVL_P9); - NimBLEDevice::setMTU(kPreferredBleMtu); + if (!NimBLEDevice::setMTU(kPreferredBleMtu)) + { + ble_log("start failed reason=set_mtu mtu=%u", static_cast(kPreferredBleMtu)); + stop(); + return false; + } applyBleSecurity(); from_phone_mutex_ = xSemaphoreCreateMutex(); to_phone_mutex_ = xSemaphoreCreateMutex(); + if (!from_phone_mutex_ || !to_phone_mutex_) + { + ble_log("start failed reason=mutex_alloc"); + stop(); + return false; + } server_ = NimBLEDevice::createServer(); + if (!server_) + { + ble_log("start failed reason=create_server"); + stop(); + return false; + } server_->setCallbacks(new MeshtasticServerCallbacks(*this)); setupService(); + if (!service_ || !to_radio_ || !from_radio_ || !from_num_ || !log_radio_ || + !battery_service_ || !battery_level_) + { + ble_log("start failed reason=service_alloc"); + stop(); + return false; + } startAdvertising(); ctx_.getChatService().addIncomingTextObserver(this); @@ -446,6 +470,13 @@ void MeshtasticBleService::start() } phone_session_.reset(new MeshtasticPhoneSession(ctx_, *this, this)); + if (!phone_session_) + { + ble_log("start failed reason=phone_session_alloc"); + stop(); + return false; + } + return true; } void MeshtasticBleService::stop() diff --git a/platform/esp/arduino_common/src/gps/gps_service.cpp b/platform/esp/arduino_common/src/gps/gps_service.cpp index 08c4e0a6..440e3e6e 100644 --- a/platform/esp/arduino_common/src/gps/gps_service.cpp +++ b/platform/esp/arduino_common/src/gps/gps_service.cpp @@ -33,13 +33,21 @@ void GpsService::begin(GpsBoard& gps_board, MotionBoard& motion_board, gps_board_ = &gps_board; motion_board_ = &motion_board; gps_adapter_.begin(gps_board); - motion_adapter_.begin(motion_board); gps_disabled_ = (disable_hw_init & NO_HW_GPS) != 0; if (gps_disabled_) { + gps_ready_ = false; return; } + gps_ready_ = gps_adapter_.isReady(); + if (!gps_ready_) + { + Serial.printf("[GPS] service inactive reason=adapter_not_ready\n"); + return; + } + + motion_adapter_.begin(motion_board); gps_data_mutex_ = xSemaphoreCreateMutex(); if (gps_data_mutex_ == NULL) @@ -184,7 +192,7 @@ void GpsService::setPowerStrategy(uint8_t strategy) { runtime_state_.setPowerStrategy(strategy); - if (gps_disabled_ || gps_board_ == nullptr) + if (!isEnabled() || gps_board_ == nullptr) { return; } @@ -205,7 +213,7 @@ void GpsService::setTeamModeActive(bool active) return; } - if (gps_disabled_ || gps_board_ == nullptr) + if (!isEnabled() || gps_board_ == nullptr) { return; } @@ -217,7 +225,7 @@ void GpsService::setGnssConfig(uint8_t mode, uint8_t sat_mask) { runtime_config_.setGnssConfig(mode, sat_mask); - if (gps_disabled_ || gps_board_ == nullptr) + if (!isEnabled() || gps_board_ == nullptr) { return; } @@ -232,7 +240,7 @@ void GpsService::setNmeaConfig(uint8_t output_hz, uint8_t sentence_mask) { runtime_config_.setNmeaConfig(output_hz, sentence_mask); - if (gps_disabled_ || gps_board_ == nullptr) + if (!isEnabled() || gps_board_ == nullptr) { return; } @@ -245,7 +253,7 @@ void GpsService::setNmeaConfig(uint8_t output_hz, uint8_t sentence_mask) void GpsService::setMotionConfig(const MotionConfig& config) { - if (gps_board_ == nullptr || gps_disabled_) + if (!isEnabled() || gps_board_ == nullptr) { return; } @@ -283,7 +291,7 @@ void GpsService::applyGnssConfig() { return; } - if (gps_disabled_ || gps_board_ == nullptr) + if (!isEnabled() || gps_board_ == nullptr) { return; } @@ -301,7 +309,7 @@ void GpsService::applyNmeaConfig() { return; } - if (gps_disabled_ || gps_board_ == nullptr) + if (!isEnabled() || gps_board_ == nullptr) { return; } diff --git a/platform/esp/arduino_common/src/memory_diag.cpp b/platform/esp/arduino_common/src/memory_diag.cpp new file mode 100644 index 00000000..958582a4 --- /dev/null +++ b/platform/esp/arduino_common/src/memory_diag.cpp @@ -0,0 +1,62 @@ +#include "platform/esp/arduino_common/memory_diag.h" + +#include + +#include "esp_heap_caps.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "platform/esp/arduino_common/app_tasks.h" +#include "platform/esp/arduino_common/gps/gps_service.h" + +namespace platform::esp::arduino_common::memory_diag +{ +namespace +{ + +const char* safe_text(const char* value) +{ + return (value && value[0] != '\0') ? value : ""; +} + +unsigned long stack_high_water_bytes(TaskHandle_t handle) +{ + if (!handle) + { + return 0; + } + return static_cast(uxTaskGetStackHighWaterMark(handle)) * sizeof(StackType_t); +} + +void log_named_task(const char* label, TaskHandle_t handle) +{ + Serial.printf("[Mem][Task] name=%s active=%u stack_hw=%lu\n", + safe_text(label), + handle ? 1U : 0U, + stack_high_water_bytes(handle)); +} + +} // namespace + +void logHeapSnapshot(const char* stage) +{ + Serial.printf("[Mem][Heap] stage=%s ram_free=%u ram_largest=%u psram_free=%u psram_largest=%u tasks=%u\n", + safe_text(stage), + static_cast(heap_caps_get_free_size(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)), + static_cast(heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)), + static_cast(heap_caps_get_free_size(MALLOC_CAP_SPIRAM)), + static_cast(heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM)), + static_cast(uxTaskGetNumberOfTasks())); +} + +void logTaskSnapshot(const char* stage) +{ + Serial.printf("[Mem][Tasks] stage=%s count=%u\n", + safe_text(stage), + static_cast(uxTaskGetNumberOfTasks())); + log_named_task("gps_collect", gps::GpsService::getInstance().getTaskHandle()); + log_named_task("motion_mgr", gps::GpsService::getInstance().getMotionTaskHandle()); + log_named_task("radio_task", app::AppTasks::getRadioTaskHandle()); + log_named_task("mesh_task", app::AppTasks::getMeshTaskHandle()); +} + +} // namespace platform::esp::arduino_common::memory_diag diff --git a/platform/esp/arduino_common/src/screen_sleep.cpp b/platform/esp/arduino_common/src/screen_sleep.cpp index 52d6ed0b..94dff7ce 100644 --- a/platform/esp/arduino_common/src/screen_sleep.cpp +++ b/platform/esp/arduino_common/src/screen_sleep.cpp @@ -133,6 +133,19 @@ void refresh_active_screen() lv_refr_now(nullptr); } +void refresh_screen_saver_locale_labels(int unread) +{ + if (s_screen_saver_unread_label != nullptr) + { + ::ui::i18n::set_label_text_fmt(s_screen_saver_unread_label, "Unread: %d", unread); + } + + if (s_screen_saver_hint_label != nullptr) + { + ::ui::i18n::set_label_text(s_screen_saver_hint_label, "Press SPACE to resume"); + } +} + void screen_saver_refresh() { if (!s_screen_saver_layer || !s_screen_saver_time_label || !s_screen_saver_unread_label) @@ -148,15 +161,7 @@ void screen_saver_refresh() lv_label_set_text(s_screen_saver_time_label, time_buf); const int unread = readUnreadCount(); - if (unread > 0) - { - const std::string text = ::ui::i18n::format("Unread: %d", unread); - lv_label_set_text(s_screen_saver_unread_label, text.c_str()); - } - else - { - ::ui::i18n::set_label_text(s_screen_saver_unread_label, "Unread: 0"); - } + refresh_screen_saver_locale_labels(unread); } void screen_saver_timer_cb(lv_timer_t* /*timer*/) @@ -204,19 +209,15 @@ void init_screen_saver() s_screen_saver_unread_label = lv_label_create(s_screen_saver_layer); lv_obj_set_style_text_color(s_screen_saver_unread_label, lv_color_hex(0x6B4A1E), 0); lv_obj_set_style_text_font(s_screen_saver_unread_label, &lv_font_montserrat_20, 0); - ::ui::i18n::set_label_text(s_screen_saver_unread_label, "Unread: 0"); lv_obj_align(s_screen_saver_unread_label, LV_ALIGN_CENTER, 0, 10); s_screen_saver_hint_label = lv_label_create(s_screen_saver_layer); lv_obj_set_style_text_color(s_screen_saver_hint_label, lv_color_hex(0x8A6A3A), 0); lv_obj_set_style_text_font(s_screen_saver_hint_label, &lv_font_montserrat_14, 0); -#if defined(ARDUINO_T_DECK) || defined(ARDUINO_T_DECK_PRO) - ::ui::i18n::set_label_text(s_screen_saver_hint_label, "Press SPACE to resume"); -#else - ::ui::i18n::set_label_text(s_screen_saver_hint_label, "Press SPACE to resume"); -#endif lv_obj_align(s_screen_saver_hint_label, LV_ALIGN_CENTER, 0, 40); + refresh_screen_saver_locale_labels(0); + lv_obj_add_flag(s_screen_saver_layer, LV_OBJ_FLAG_HIDDEN); } diff --git a/scripts/build_pack_repository.py b/scripts/build_pack_repository.py index 4ec695bb..ee394f23 100644 --- a/scripts/build_pack_repository.py +++ b/scripts/build_pack_repository.py @@ -88,14 +88,102 @@ def parse_bool(value: str | None, default: bool = False) -> bool: return default +def resolve_build_path(spec: str, stage_font_dir: Path, stage_bundle_dir: Path, repo_root: Path) -> Path: + candidate = Path(spec) + if candidate.is_absolute(): + return candidate + + for base in (stage_font_dir, stage_bundle_dir, repo_root): + resolved = (base / candidate).resolve() + if resolved.exists(): + return resolved + + return (repo_root / candidate).resolve() + + +def build_font_charset_if_configured( + stage_font_dir: Path, + stage_bundle_dir: Path, + repo_root: Path, +) -> bool: + build_path = stage_font_dir / "build.ini" + if not build_path.exists(): + return False + + build = parse_key_value_file(build_path) + include_manifests = parse_bool(build.get("include_manifests"), default=True) + include_locales = parse_bool(build.get("include_locales"), default=True) + extra_chars = split_csv(build.get("extra_chars_file")) + seed_charsets = split_csv(build.get("seed_charset_file")) + exclude_charsets = split_csv(build.get("exclude_charset_file")) + ranked_chars_file = build.get("ranked_chars_file", "") + ranked_char_limit = parse_int(build.get("ranked_char_limit"), 0) + + uses_generator = ( + not include_manifests + or not include_locales + or bool(extra_chars) + or bool(seed_charsets) + or bool(exclude_charsets) + or bool(ranked_chars_file) + ) + if not uses_generator: + return False + + generator = repo_root / "tools" / "build_locale_pack_charset.py" + if not generator.exists(): + raise FileNotFoundError(f"Missing charset builder script: {generator}") + + command = [ + sys.executable, + str(generator), + "--pack-root", + str(stage_bundle_dir.resolve()), + "--font-pack-id", + stage_font_dir.name, + ] + if not include_manifests: + command.append("--no-include-manifests") + if not include_locales: + command.append("--no-include-locales") + for spec in extra_chars: + command.extend([ + "--extra-chars-file", + str(resolve_build_path(spec, stage_font_dir, stage_bundle_dir, repo_root)), + ]) + for spec in seed_charsets: + command.extend([ + "--seed-charset-file", + str(resolve_build_path(spec, stage_font_dir, stage_bundle_dir, repo_root)), + ]) + for spec in exclude_charsets: + command.extend([ + "--exclude-charset-file", + str(resolve_build_path(spec, stage_font_dir, stage_bundle_dir, repo_root)), + ]) + if ranked_chars_file: + command.extend([ + "--ranked-chars-file", + str(resolve_build_path(ranked_chars_file, stage_font_dir, stage_bundle_dir, repo_root)), + ]) + if ranked_char_limit > 0: + command.extend(["--ranked-char-limit", str(ranked_char_limit)]) + + subprocess.run(command, check=True) + return True + + def build_font_if_missing( stage_font_dir: Path, repo_root: Path, node_exe: str, npm_exe: str | None, + force_rebuild: bool = False, ) -> None: build_path = stage_font_dir / "build.ini" font_bin_path = stage_font_dir / "font.bin" + if force_rebuild and font_bin_path.exists(): + font_bin_path.unlink() if font_bin_path.exists(): return if not build_path.exists(): @@ -159,7 +247,8 @@ def stage_bundle( fonts_root = stage_bundle_dir / "fonts" if fonts_root.is_dir(): for font_dir in sorted(path for path in fonts_root.iterdir() if path.is_dir()): - build_font_if_missing(font_dir, repo_root, node_exe, npm_exe) + force_rebuild = build_font_charset_if_configured(font_dir, stage_bundle_dir, repo_root) + build_font_if_missing(font_dir, repo_root, node_exe, npm_exe, force_rebuild=force_rebuild) return stage_bundle_dir @@ -249,6 +338,9 @@ def collect_locale_records(stage_bundle_dir: Path) -> list[dict[str, object]]: "content_font_pack_id": manifest.get( "content_font_pack", manifest.get("ui_font_pack", "") ), + "preferred_content_supplement_pack_ids": split_csv( + manifest.get("preferred_content_supplement_packs", manifest.get("content_supplement_packs", "")) + ), "ime_pack_id": manifest.get("ime_pack", ""), } ) diff --git a/site/data/packs.json b/site/data/packs.json index 216beadc..47d6514c 100644 --- a/site/data/packs.json +++ b/site/data/packs.json @@ -1,7 +1,7 @@ { "schema_version": 1, "archive_layout": "trailmate-pack-v1", - "generated_at": "2026-04-20T16:09:03.769450Z", + "generated_at": "2026-04-21T02:00:30.208708Z", "packages": [ { "id": "europe-latin-ext", @@ -31,6 +31,7 @@ "native_name": "Deutsch", "ui_font_pack_id": "latin-ext-eu", "content_font_pack_id": "latin-ext-eu", + "preferred_content_supplement_pack_ids": [], "ime_pack_id": "" }, { @@ -39,6 +40,7 @@ "native_name": "Español", "ui_font_pack_id": "latin-ext-eu", "content_font_pack_id": "latin-ext-eu", + "preferred_content_supplement_pack_ids": [], "ime_pack_id": "" }, { @@ -47,6 +49,7 @@ "native_name": "Français", "ui_font_pack_id": "latin-ext-eu", "content_font_pack_id": "latin-ext-eu", + "preferred_content_supplement_pack_ids": [], "ime_pack_id": "" }, { @@ -55,6 +58,7 @@ "native_name": "Italiano", "ui_font_pack_id": "latin-ext-eu", "content_font_pack_id": "latin-ext-eu", + "preferred_content_supplement_pack_ids": [], "ime_pack_id": "" }, { @@ -63,6 +67,7 @@ "native_name": "Nederlands", "ui_font_pack_id": "latin-ext-eu", "content_font_pack_id": "latin-ext-eu", + "preferred_content_supplement_pack_ids": [], "ime_pack_id": "" }, { @@ -71,6 +76,7 @@ "native_name": "Polski", "ui_font_pack_id": "latin-ext-eu", "content_font_pack_id": "latin-ext-eu", + "preferred_content_supplement_pack_ids": [], "ime_pack_id": "" }, { @@ -79,6 +85,7 @@ "native_name": "Português (Portugal)", "ui_font_pack_id": "latin-ext-eu", "content_font_pack_id": "latin-ext-eu", + "preferred_content_supplement_pack_ids": [], "ime_pack_id": "" } ], @@ -101,8 +108,8 @@ "archive": { "layout": "trailmate-pack-v1", "path": "assets/packs/europe-latin-ext-1.0.0.zip", - "size_bytes": 12197, - "sha256": "66aa3e25f3666bb32f638f0eb61a6a130b0f7b74409db0a904fc8bbe05ee7ad4" + "size_bytes": 12326, + "sha256": "b5eae5d57ac3cf6cb367268abc87cec3cd66f53429b8dbc2a239b4f6ecfd9c81" }, "files": { "package_manifest": "package.ini", @@ -138,6 +145,7 @@ "native_name": "日本語", "ui_font_pack_id": "ja-cjk", "content_font_pack_id": "ja-cjk", + "preferred_content_supplement_pack_ids": [], "ime_pack_id": "" } ], @@ -160,8 +168,8 @@ "archive": { "layout": "trailmate-pack-v1", "path": "assets/packs/ja-1.0.0.zip", - "size_bytes": 11239, - "sha256": "21d00d81dac31d334411d85fafb5483547a16a479b93fc3936682be16138aa45" + "size_bytes": 11246, + "sha256": "c559c456d613be3befdbac0f77050468fd2346e0ccda5492ebe40762a8f5b5c6" }, "files": { "package_manifest": "package.ini", @@ -197,6 +205,7 @@ "native_name": "한국어", "ui_font_pack_id": "ko-cjk", "content_font_pack_id": "ko-cjk", + "preferred_content_supplement_pack_ids": [], "ime_pack_id": "" } ], @@ -219,8 +228,8 @@ "archive": { "layout": "trailmate-pack-v1", "path": "assets/packs/ko-1.0.0.zip", - "size_bytes": 8461, - "sha256": "02bde352d3d071e4e0bbdeea7b546f784e5318a579e8a597fa5e47bb817962f2" + "size_bytes": 8470, + "sha256": "153d8bd1ffacb75a08f8be7483e50c4e559b949dea7a7b0f08cb592718f29dd3" }, "files": { "package_manifest": "package.ini", @@ -233,8 +242,8 @@ "package_type": "locale-bundle", "version": "1.0.0", "display_name": "Simplified Chinese", - "summary": "Full Simplified Chinese locale bundle with external CJK font coverage and the built-in Pinyin IME backend.", - "description": "Simplified Chinese installs the zh-Hans locale, the zh-hans-cjk external CJK font pack,\nand the zh-hans-pinyin IME registration used by the built-in Pinyin input backend.\n\nUse this bundle when you want a Chinese interface, Chinese text entry, or reliable\nrendering of Chinese names and chat content while another locale remains active.", + "summary": "Tiered Simplified Chinese locale bundle with a fast core font, an on-demand extension font, and the built-in Pinyin IME backend.", + "description": "Simplified Chinese installs the zh-Hans locale, a tiered two-pack font stack, and the\nzh-hans-pinyin IME registration used by the built-in Pinyin input backend.\n\nThe bundle ships:\n- zh-hans-core: the common-glyph UI/content font loaded first for fast startup and lower steady-state RAM use\n- zh-hans-ext: the remaining Chinese glyph coverage that the runtime can load on demand as a content supplement\n- zh-hans-pinyin: the built-in Pinyin IME registration layer\n\nUse this bundle when you want a Chinese interface, Chinese text entry, or reliable\nrendering of Chinese names and chat content while another locale remains active, without\npaying the full monolithic CJK font cost up front.", "author": "Trail Mate", "homepage": "https://vicliu624.github.io/trail-mate/", "min_firmware_version": "0.1.18-alpha", @@ -254,17 +263,26 @@ "id": "zh-Hans", "display_name": "Simplified Chinese", "native_name": "简体中文", - "ui_font_pack_id": "zh-hans-cjk", - "content_font_pack_id": "zh-hans-cjk", + "ui_font_pack_id": "zh-hans-core", + "content_font_pack_id": "zh-hans-core", + "preferred_content_supplement_pack_ids": [ + "zh-hans-ext" + ], "ime_pack_id": "zh-hans-pinyin" } ], "fonts": [ { - "id": "zh-hans-cjk", - "display_name": "Simplified Chinese CJK", + "id": "zh-hans-core", + "display_name": "Simplified Chinese Core", "usage": "both", - "estimated_ram_bytes": 476075 + "estimated_ram_bytes": 217456 + }, + { + "id": "zh-hans-ext", + "display_name": "Simplified Chinese Extension", + "usage": "content", + "estimated_ram_bytes": 248636 } ], "ime": [ @@ -276,16 +294,16 @@ ] }, "runtime": { - "estimated_unique_font_ram_bytes": 476075, + "estimated_unique_font_ram_bytes": 466092, "locale_count": 1, - "font_count": 1, + "font_count": 2, "ime_count": 1 }, "archive": { "layout": "trailmate-pack-v1", "path": "assets/packs/zh-Hans-1.0.0.zip", - "size_bytes": 328766, - "sha256": "a7d5623755d962820c8849f7c48aa4c1bb741d30f14985dcae932922f76eee2a" + "size_bytes": 338342, + "sha256": "a598cd28e5b601d261b8a70c435d107e034ef8967b4fd85ae4978361f99fc85b" }, "files": { "package_manifest": "package.ini", @@ -321,6 +339,7 @@ "native_name": "繁體中文", "ui_font_pack_id": "zh-hant-cjk", "content_font_pack_id": "zh-hant-cjk", + "preferred_content_supplement_pack_ids": [], "ime_pack_id": "" } ], @@ -343,8 +362,8 @@ "archive": { "layout": "trailmate-pack-v1", "path": "assets/packs/zh-Hant-1.0.0.zip", - "size_bytes": 11401, - "sha256": "b1fda6665d46a115f9ed5a63c7d54dea0f4c0c27b157770a89ac3bfdf86d2227" + "size_bytes": 11411, + "sha256": "334b4504a3e6e8c504f63fcabcd15994f8a2f1338dd11c775081b15a843d108e" }, "files": { "package_manifest": "package.ini", diff --git a/tools/build_locale_pack_charset.py b/tools/build_locale_pack_charset.py index 1130b08c..db06aebd 100644 --- a/tools/build_locale_pack_charset.py +++ b/tools/build_locale_pack_charset.py @@ -52,14 +52,63 @@ def iter_extra_texts(extra_paths: list[Path]): raise FileNotFoundError(f"missing extra chars file: {path}") yield path.read_text(encoding="utf-8") +def iter_charset_file_chars(paths: list[Path]): + for path in paths: + if not path.exists(): + raise FileNotFoundError(f"missing charset file: {path}") + for ch in path.read_text(encoding="utf-8"): + if ch.isspace() or ord(ch) < 0x80: + continue + yield ch -def collect_charset(pack_root: Path, extra_paths: list[Path]) -> list[str]: + +def iter_ranked_chars(path: Path, limit: int): + if not path.exists(): + raise FileNotFoundError(f"missing ranked chars file: {path}") + + emitted = 0 + for ch in path.read_text(encoding="utf-8"): + if ch.isspace() or ord(ch) < 0x80: + continue + yield ch + emitted += 1 + if limit > 0 and emitted >= limit: + break + + +def collect_charset(pack_root: Path, + include_manifests: bool, + include_locales: bool, + extra_paths: list[Path], + seed_paths: list[Path], + exclude_paths: list[Path], + ranked_chars_path: Path | None, + ranked_char_limit: int) -> list[str]: chars: set[str] = set() - for text in list(iter_manifest_texts(pack_root)) + list(iter_locale_texts(pack_root)) + list(iter_extra_texts(extra_paths)): + + text_sources: list[str] = [] + if include_manifests: + text_sources.extend(iter_manifest_texts(pack_root)) + if include_locales: + text_sources.extend(iter_locale_texts(pack_root)) + text_sources.extend(iter_extra_texts(extra_paths)) + + for text in text_sources: for ch in text: if ch.isspace() or ord(ch) < 0x80: continue chars.add(ch) + + for ch in iter_charset_file_chars(seed_paths): + chars.add(ch) + + if ranked_chars_path is not None: + for ch in iter_ranked_chars(ranked_chars_path, ranked_char_limit): + chars.add(ch) + + for ch in iter_charset_file_chars(exclude_paths): + chars.discard(ch) + return sorted(chars, key=ord) @@ -86,7 +135,7 @@ def write_ranges(path: Path, chars: list[str]) -> None: def main() -> int: - parser = argparse.ArgumentParser(description="Build charset files for a locale pack bundle.") + parser = argparse.ArgumentParser(description="Build charset files for a locale/font pack bundle.") parser.add_argument("--pack-root", type=Path, required=True, help="Pack bundle root, for example packs/zh-Hans") parser.add_argument( "--font-pack-id", @@ -99,6 +148,40 @@ def main() -> int: default=[], help="UTF-8 text file with additional glyphs to include. May be passed multiple times.", ) + parser.add_argument( + "--seed-charset-file", + action="append", + default=[], + help="Existing charset file whose glyphs should be unioned into the output. May be passed multiple times.", + ) + parser.add_argument( + "--exclude-charset-file", + action="append", + default=[], + help="Existing charset file whose glyphs should be removed from the output. May be passed multiple times.", + ) + parser.add_argument( + "--ranked-chars-file", + type=Path, + default=None, + help="UTF-8 ranked glyph file. The first --ranked-char-limit non-ASCII glyphs are added to the output.", + ) + parser.add_argument( + "--ranked-char-limit", + type=int, + default=0, + help="Maximum number of glyphs to consume from --ranked-chars-file. Use 0 for all.", + ) + parser.add_argument( + "--no-include-manifests", + action="store_true", + help="Do not include display_name/native_name text from manifest.ini files under the bundle.", + ) + parser.add_argument( + "--no-include-locales", + action="store_true", + help="Do not include localized strings.tsv text from the bundle.", + ) parser.add_argument( "--charset-out", type=Path, @@ -115,17 +198,29 @@ def main() -> int: pack_root = args.pack_root.resolve() extra_paths = [Path(item).resolve() for item in args.extra_chars_file] + seed_paths = [Path(item).resolve() for item in args.seed_charset_file] + exclude_paths = [Path(item).resolve() for item in args.exclude_charset_file] + ranked_chars_path = args.ranked_chars_file.resolve() if args.ranked_chars_file else None font_pack_dir = resolve_font_pack_dir(pack_root, args.font_pack_id) charset_out = args.charset_out or (font_pack_dir / "charset.txt") ranges_out = args.ranges_out or (font_pack_dir / "ranges.txt") - chars = collect_charset(pack_root, extra_paths) + chars = collect_charset(pack_root, + include_manifests=not args.no_include_manifests, + include_locales=not args.no_include_locales, + extra_paths=extra_paths, + seed_paths=seed_paths, + exclude_paths=exclude_paths, + ranked_chars_path=ranked_chars_path, + ranked_char_limit=max(0, args.ranked_char_limit)) write_charset(charset_out, chars) write_ranges(ranges_out, chars) print(f"pack_root={pack_root}") print(f"font_pack_dir={font_pack_dir}") print(f"glyph_count={len(chars)}") + print(f"include_manifests={0 if args.no_include_manifests else 1}") + print(f"include_locales={0 if args.no_include_locales else 1}") print(f"charset_out={charset_out}") print(f"ranges_out={ranges_out}") return 0 diff --git a/tools/extract_pinyin_chars.py b/tools/extract_pinyin_chars.py index 085dc40e..eeac6e69 100644 --- a/tools/extract_pinyin_chars.py +++ b/tools/extract_pinyin_chars.py @@ -1,33 +1,122 @@ -import re +#!/usr/bin/env python3 + +from __future__ import annotations + +import argparse from pathlib import Path -src = Path('src/ui/widgets/ime/pinyin_data.h') -text = src.read_text(encoding='utf-8') -chars = set() -for line in text.splitlines(): - line = line.strip() - if not line or line.startswith('#') or line.startswith('/*') or line.startswith('*/'): - continue - if '\t' in line: - _, rest = line.split('\t', 1) - else: - parts = line.split(' ', 1) - if len(parts) < 2: - continue - rest = parts[1] - for token in rest.split(' '): - token = token.strip() - if not token: - continue - for ch in token: - if ch.isspace(): +DEFAULT_SOURCE = Path("modules/ui_shared/include/ui/widgets/ime/pinyin_data.h") +DEFAULT_SORTED_OUTPUT = Path("tools/pinyin_chars.txt") +DEFAULT_RANKED_OUTPUT = Path("tools/pinyin_ranked_chars.txt") + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser( + description="Extract unique and ranked Chinese glyph sets from the built-in Pinyin IME dictionary." + ) + parser.add_argument( + "--source", + type=Path, + default=DEFAULT_SOURCE, + help="Path to pinyin_data.h", + ) + parser.add_argument( + "--sorted-output", + type=Path, + default=DEFAULT_SORTED_OUTPUT, + help="Output path for the codepoint-sorted unique glyph file.", + ) + parser.add_argument( + "--ranked-output", + type=Path, + default=DEFAULT_RANKED_OUTPUT, + help="Output path for the frequency-ranked glyph file.", + ) + return parser.parse_args() + + +def iter_candidate_lines(source_text: str): + in_dict = False + for raw_line in source_text.splitlines(): + line = raw_line.rstrip("\r") + if not in_dict: + marker = 'R"PINYIN_DICT(' + if marker not in line: continue - chars.add(ch) + line = line.split(marker, 1)[1] + in_dict = True -# Build sorted list by codepoint -chars_list = sorted(chars, key=lambda c: ord(c)) + if ')PINYIN_DICT"' in line: + line = line.split(')PINYIN_DICT"', 1)[0] + if line: + yield line + break -out = Path('tools/pinyin_chars.txt') -out.write_text(''.join(chars_list), encoding='utf-8') -print(f"chars: {len(chars_list)}") + yield line + + +def is_cjk_candidate_char(ch: str) -> bool: + return len(ch) == 1 and not ch.isspace() and ord(ch) >= 0x80 + + +def wrap_chars(chars: list[str], width: int = 64) -> str: + if not chars: + return "" + return "\n".join("".join(chars[index:index + width]) for index in range(0, len(chars), width)) + "\n" + + +def main() -> int: + args = parse_args() + + source_path = args.source.resolve() + if not source_path.exists(): + raise FileNotFoundError(f"pinyin dictionary source not found: {source_path}") + + source_text = source_path.read_text(encoding="utf-8") + + unique_chars: set[str] = set() + ranked_scores: dict[str, int] = {} + first_seen_order: dict[str, int] = {} + next_seen_index = 0 + + for line in iter_candidate_lines(source_text): + if not line or line.startswith("#"): + continue + if "\t" not in line: + continue + + _, candidate_text = line.split("\t", 1) + tokens = [token.strip() for token in candidate_text.split(" ") if token.strip()] + for token_index, token in enumerate(tokens): + token_weight = max(1, 256 - token_index) + for ch in token: + if not is_cjk_candidate_char(ch): + continue + unique_chars.add(ch) + ranked_scores[ch] = ranked_scores.get(ch, 0) + token_weight + if ch not in first_seen_order: + first_seen_order[ch] = next_seen_index + next_seen_index += 1 + + sorted_chars = sorted(unique_chars, key=ord) + ranked_chars = sorted( + unique_chars, + key=lambda ch: (-ranked_scores.get(ch, 0), first_seen_order.get(ch, 0), ord(ch)), + ) + + args.sorted_output.parent.mkdir(parents=True, exist_ok=True) + args.sorted_output.write_text(wrap_chars(sorted_chars), encoding="utf-8") + + args.ranked_output.parent.mkdir(parents=True, exist_ok=True) + args.ranked_output.write_text(wrap_chars(ranked_chars), encoding="utf-8") + + print(f"source={source_path}") + print(f"unique_glyph_count={len(sorted_chars)}") + print(f"sorted_output={args.sorted_output.resolve()}") + print(f"ranked_output={args.ranked_output.resolve()}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tools/fonts/README.md b/tools/fonts/README.md index 168b2d41..28ca47a9 100644 --- a/tools/fonts/README.md +++ b/tools/fonts/README.md @@ -23,7 +23,7 @@ The tool validates each glyph via encode/decode round-trip before writing. ## External Pack Workflow Simplified Chinese no longer ships as a compiled-in UI font. The repository now -expects Chinese glyph coverage to be generated into an external font pack. +expects Chinese glyph coverage to be generated into external font packs. The reference bundle lives under: @@ -33,19 +33,32 @@ packs/zh-Hans Typical flow: -1. Refresh the subset files: +1. Refresh the ranked Pinyin glyph sources: ```bash -python tools/build_locale_pack_charset.py --pack-root packs/zh-Hans --extra-chars-file tools/pinyin_chars.txt +python tools/extract_pinyin_chars.py ``` -2. Generate `packs/zh-Hans/fonts/zh-hans-cjk/font.bin` with `lv_font_conv` - using: +2. Generate the core pack subset: + +```bash +python tools/build_locale_pack_charset.py --pack-root packs/zh-Hans --font-pack-id zh-hans-core +``` + +3. Generate the extension pack subset: + +```bash +python tools/build_locale_pack_charset.py --pack-root packs/zh-Hans --font-pack-id zh-hans-ext +``` + +4. Generate `font.bin` files with `lv_font_conv` using: - font source: `tools/fonts/NotoSansCJKsc-Regular.otf` -- glyph subset: `packs/zh-Hans/fonts/zh-hans-cjk/charset.txt` or `ranges.txt` +- glyph subsets: + - `packs/zh-Hans/fonts/zh-hans-core/charset.txt` + - `packs/zh-Hans/fonts/zh-hans-ext/charset.txt` - output format: `bin` - size: `16` - bpp: `2` -3. Copy the pack directories onto the SD card under `/trailmate/packs/...`. +5. Copy the pack directories onto the SD card under `/trailmate/packs/...`. diff --git a/tools/pinyin_chars.txt b/tools/pinyin_chars.txt index 0a0b379d..cdcb26ef 100644 --- a/tools/pinyin_chars.txt +++ b/tools/pinyin_chars.txt @@ -1 +1,106 @@ -"(=CDEGIMNOPRTY[]_achiknorsty一丁七万丈三上下丌不与丐丑专且丕世丘丙业丛东丝丞丢两严丧丨个丫丬中丰串临丶丸丹为主丽举丿乃久乇么义之乌乍乎乏乐乒乓乔乖乘乙乜九乞也习乡书乩买乱乳乾了予争事二亍于亏云互亓五井亘亚些亟亠亡亢交亥亦产亨亩享京亭亮亲亳亵人亻亿什仁仂仃仄仅仆仇仉今介仍从仑仓仔仕他仗付仙仝仞仟仡代令以仨仪仫们仰仲仳仵件价任份仿企伉伊伍伎伏伐休众优伙会伛伞伟传伢伤伥伦伧伪伫伯估伲伴伶伸伺似伽佃但位低住佐佑体何佗佘余佚佛作佝佞佟你佣佤佥佧佩佬佯佰佳佴佶佻佼佾使侃侄侈侉例侍侏侑侔侗供依侠侣侥侦侧侨侩侪侬侮侯侵便促俄俅俊俎俏俐俑俗俘俚俜保俞俟信俣俦俨俩俪俭修俯俱俳俸俺俾倌倍倏倒倔倘候倚倜借倡倥倦倨倩倪倬倭倮债值倾偃假偈偌偎偏偕做停健偬偶偷偻偾偿傀傅傈傍傣傥傧储傩催傲傺傻像僖僚僦僧僬僭僮僳僵僻儆儇儋儒儡儿兀允元兄充兆先光克免兑兔兕兖党兜兢入全八公六兮兰共关兴兵其具典兹养兼兽冀冁冂内冈冉册再冒冕冖冗写军农冠冢冤冥冫冬冯冰冱冲决况冶冷冻冼冽净凄准凇凉凋凌减凑凛凝几凡凤凫凭凯凰凳凵凶凸凹出击凼函凿刀刁刂刃分切刈刊刍刎刑划刖列刘则刚创初删判刨利别刭刮到刳制刷券刹刺刻刽刿剀剁剂剃削剌前剐剑剔剖剜剞剡剥剧剩剪副割剽剿劁劂劈劐劓力劝办功加务劢劣动助努劫劬劭励劲劳劾势勃勇勉勋勐勒勖勘募勤勰勹勺勾勿匀包匆匈匍匏匐匕化北匙匚匝匠匡匣匦匪匮匹区医匾匿十千卅升午卉半华协卑卒卓单卖南博卜卞卟占卡卢卣卤卦卧卩卫卮卯印危即却卵卷卸卺卿厂厄厅历厉压厌厍厕厘厚厝原厢厣厥厦厨厩厮厶去县叁参又叉及友双反发叔取受变叙叛叟叠口古句另叨叩只叫召叭叮可台叱史右叵叶号司叹叻叼叽吁吃各吆合吉吊同名后吏吐向吒吓吕吖吗君吝吞吟吠吡吣否吧吨吩含听吭吮启吱吲吴吵吸吹吻吼吾呀呃呆呈告呋呐呒呓呔呕呖呗员呙呛呜呢呤呦周呱呲味呵呶呷呸呻呼命咀咂咄咆咋和咎咏咐咒咔咕咖咙咚咛咝咣咤咦咧咨咩咪咫咬咭咯咱咳咴咸咻咽咿哀品哂哄哆哇哈哉哌响哎哏哐哑哒哓哔哕哗哙哚哜哝哞哟哥哦哧哨哩哪哭哮哲哳哺哼哽哿唁唆唇唉唏唐唑唔唛唠唢唣唤唧唪唬售唯唰唱唳唷唼唾唿啁啃啄商啉啊啐啕啖啜啡啤啥啦啧啪啬啭啮啵啶啷啸啻啼啾喀喁喂喃善喇喈喉喊喋喏喑喔喘喙喜喝喟喧喱喳喵喷喹喻喽喾嗄嗅嗉嗌嗍嗑嗒嗓嗔嗖嗜嗝嗟嗡嗣嗤嗥嗦嗨嗪嗫嗬嗯嗲嗳嗵嗷嗽嗾嘀嘁嘈嘉嘌嘎嘏嘘嘛嘞嘟嘣嘤嘧嘬嘭嘱嘲嘴嘶嘹嘻嘿噌噍噎噔噗噘噙噜噢噤器噩噪噫噬噱噶噻噼嚅嚆嚎嚏嚓嚣嚯嚷嚼囊囔囗囚四囝回囟因囡团囤囫园困囱围囵囹固国图囿圃圄圆圈圉圊圜土圣在圩圪圬圭圮圯地圳圹场圻圾址坂均坊坌坍坎坏坐坑块坚坛坜坝坞坟坠坡坤坦坨坩坪坫坭坯坳坶坷坻坼垂垃垄垅垆型垌垒垓垛垠垡垢垣垤垦垧垩垫垭垮垲垴垸埂埃埋城埏埒埔埕埘埙埚埝域埠埤埭埯埴埸培基埽堀堂堆堇堋堍堑堕堙堞堠堡堤堪堰堵塄塌塍塑塔塘塞塥填塬塾墀墁境墅墉墒墓墙墚增墟墨墩墼壁壅壑壕壤士壬壮声壳壶壹夂处备复夏夔夕外夙多夜够夤夥大天太夫夭央夯失头夷夸夹夺夼奁奂奄奇奈奉奋奎奏契奔奕奖套奘奚奠奢奥女奴奶奸她好妁如妃妄妆妇妈妊妍妒妓妖妗妙妞妣妤妥妨妩妪妫妮妯妲妹妻妾姆姊始姐姑姒姓委姗姘姚姜姝姣姥姨姬姹姻姿威娃娄娅娆娇娈娉娌娑娓娘娜娟娠娣娥娩娱娲娴娶娼婀婆婉婊婕婚婢婧婪婴婵婶婷婺婿媒媚媛媪媲媳媵媸媾嫁嫂嫉嫌嫒嫔嫖嫘嫜嫠嫡嫣嫦嫩嫫嫱嬉嬖嬗嬲嬴嬷孀子孑孓孔孕字存孙孚孛孜孝孟孢季孤孥学孩孪孬孰孱孳孵孺孽宀宁它宄宅宇守安宋完宏宓宕宗官宙定宛宜宝实宠审客宣室宥宦宪宫宰害宴宵家宸容宽宾宿寂寄寅密寇富寐寒寓寝寞察寡寤寥寨寮寰寸对寺寻导寿封射将尉尊小少尔尕尖尘尚尜尝尢尤尥尧尬就尴尸尹尺尻尼尽尾尿局屁层居屈屉届屋屎屏屐屑展屙属屠屡屣履屦屮屯山屹屺屿岁岂岈岌岍岐岑岔岖岗岘岙岚岛岜岢岣岩岫岬岭岱岳岵岷岸岽岿峁峄峋峒峙峡峤峥峦峨峪峭峰峻崂崃崆崇崎崔崖崛崞崤崦崧崩崭崮崴崽崾嵇嵊嵋嵌嵘嵛嵝嵩嵫嵬嵯嵴嶂嶙嶝嶷巅巍巛川州巡巢工左巧巨巩巫差巯己已巳巴巷巽巾币市布帅帆师希帏帐帑帔帕帖帘帙帚帛帜帝带帧席帮帱帷常帻帼帽幂幄幅幌幔幕幛幞幡幢干平年并幸幺幻幼幽广庀庄庆庇床庋序庐庑库应底庖店庙庚府庞废庠庥度座庭庳庵庶康庸庹庾廉廊廑廒廓廖廛廨廪廴延廷建廾廿开弁异弃弄弈弊弋式弑弓引弗弘弛弟张弥弦弧弩弪弭弯弱弹强弼彀彐归当录彖彗彘彝彡形彤彦彩彪彬彭彰影彳彷役彻彼往征徂径待徇很徉徊律後徐徒徕得徘徙徜御徨循徭微徵德徼徽心忄必忆忉忌忍忏忐忑忒忖志忘忙忝忠忡忤忧忪快忭忮忱念忸忻忽忾忿怀态怂怃怄怅怆怊怍怎怏怒怔怕怖怙怛怜思怠怡急怦性怨怩怪怫怯怵总怼怿恁恂恃恋恍恐恒恕恙恚恝恢恣恤恧恨恩恪恫恬恭息恰恳恶恸恹恺恻恼恽恿悃悄悉悌悍悒悔悖悚悛悝悟悠患悦您悫悬悭悯悱悲悴悸悻悼情惆惊惋惑惕惘惚惜惝惟惠惦惧惨惩惫惬惭惮惯惰想惴惶惹惺愀愁愆愈愉愍愎意愕愚感愠愣愤愦愧愫愿慈慊慌慎慑慕慝慢慧慨慰慵慷憋憎憔憝憧憨憩憬憷憾懂懈懊懋懑懒懔懦懵懿戆戈戊戋戌戍戎戏成我戒戕或戗战戚戛戟戡戢戤戥截戬戮戳戴户戽戾房所扁扃扇扈扉手扌才扎扑扒打扔托扛扣扦执扩扪扫扬扭扮扯扰扳扶批扼找承技抄抉把抑抒抓投抖抗折抚抛抟抠抡抢护报抨披抬抱抵抹抻押抽抿拂拄担拆拇拈拉拊拌拍拎拐拒拓拔拖拗拘拙拚招拜拟拢拣拥拦拧拨择括拭拮拯拱拳拴拶拷拼拽拾拿持挂指挈按挎挑挖挚挛挝挞挟挠挡挢挣挤挥挨挪挫振挲挹挺挽捂捃捅捆捉捋捌捍捎捏捐捕捞损捡换捣捧捩捭据捱捶捷捺捻掀掂掇授掉掊掌掎掏掐排掖掘掠探掣接控推掩措掬掭掮掰掳掴掷掸掺掼掾揄揆揉揍揎描提插揖揞揠握揣揩揪揭揲援揶揸揽揿搀搁搂搅搋搌搏搐搓搔搛搜搞搠搡搦搪搬搭搴携搽搿摁摄摅摆摇摈摊摒摔摘摞摧摩摭摸摹摺撂撄撅撇撑撒撕撖撙撞撤撩撬播撮撰撵撷撸撺撼擀擂擅操擎擐擒擗擘擞擢擤擦攀攉攒攘攥攫攮支攴攵收攸改攻放政故效敉敌敏救敕敖教敛敝敞敢散敦敫敬数敲整敷文斋斌斐斑斓斗料斛斜斟斡斤斥斧斩斫断斯新方於施旁旃旄旅旆旋旌旎族旒旖旗无既日旦旧旨早旬旭旮旯旰旱时旷旺昀昂昃昆昊昌明昏易昔昕昙昝星映春昧昨昭是昱昴昵昶昼显晁晃晋晌晏晒晓晔晕晖晗晚晟晡晤晦晨普景晰晴晶晷智晾暂暄暇暌暑暖暗暝暧暨暮暴暹暾曙曛曜曝曦曩曰曲曳更曷曹曼曾替最月有朊朋服朐朔朕朗望朝期朦木未末本札术朱朴朵机朽杀杂权杆杈杉杌李杏材村杓杖杜杞束杠条来杨杩杪杭杯杰杲杳杵杷杼松板极构枇枉枋析枕林枘枚果枝枞枢枣枥枧枨枪枫枭枯枰枳枵架枷枸柁柃柄柏某柑柒染柔柘柙柚柜柝柞柠柢查柩柬柯柰柱柳柴柽柿栀栅标栈栉栊栋栌栎栏树栓栖栗栝校栩株栲栳样核根格栽栾桀桁桂桃桄桅框案桉桊桌桎桐桑桓桔桕桠桡桢档桤桥桦桧桨桩桫桴桶桷梁梃梅梆梏梓梗梢梦梧梨梭梯械梳梵检棂棉棋棍棒棕棘棚棠棣森棰棱棵棹棺棼椁椅椋植椎椐椒椟椠椤椭椰椴椹椽椿楂楔楗楚楝楞楠楣楦楫楮楱楷楸楹楼榀概榄榆榇榈榉榍榔榕榘榛榜榧榨榫榭榱榴榷榻槁槊槌槎槐槔槛槟槠槭槲槽槿樊樗樘樟模樨横樯樱樵樽樾橄橇橐橘橙橛橡橥橱橹橼檀檄檎檐檑檗檠檩檫檬欠次欢欣欤欧欲欷欹欺款歃歆歇歉歌歙止正此步武歧歪歹死歼殁殂殃殄殆殇殉殊残殍殒殓殖殚殛殡殪殳殴段殷殿毁毂毅毋母每毒毓比毕毖毗毙毛毡毪毫毯毳毵毹毽氅氆氇氍氏氐民氓气氕氖氘氙氚氛氟氡氢氤氦氧氨氩氪氮氯氰氲水氵永氽汀汁求汆汇汉汊汐汔汕汗汛汜汝汞江池污汤汨汩汪汰汲汴汶汹汽汾沁沂沃沅沆沈沉沌沏沐沓沔沙沛沟没沣沤沥沦沧沩沪沫沭沮沱沲河沸油治沼沽沾沿泄泅泉泊泌泐泓泔法泖泗泛泞泠泡波泣泥注泪泫泮泯泰泱泳泵泶泷泸泺泻泼泽泾洁洄洇洋洌洎洒洗洙洚洛洞津洧洪洫洮洱洲洳洵洹活洼洽派流浃浅浆浇浈浊测浍济浏浑浒浓浔浙浚浜浞浠浣浦浩浪浮浯浴海浸浼涂涅消涉涌涎涑涓涔涕涛涝涞涟涠涡涣涤润涧涨涩涪涫涮涯液涵涸涿淀淄淅淆淇淋淌淑淖淘淙淝淞淠淡淤淦淫淬淮深淳混淹添淼清渊渌渍渎渐渑渔渖渗渚渝渠渡渣渤渥温渫渭港渲渴游渺湃湄湍湎湓湔湖湘湛湟湫湮湾湿溃溅溆溉溏源溘溜溟溢溥溧溪溯溱溲溴溶溷溺溻溽滁滂滇滋滏滑滓滔滕滗滚滞滟滠满滢滤滥滦滨滩滴滹漂漆漉漏漓演漕漠漤漩漪漫漭漯漱漳漶漾潆潇潋潍潘潜潞潢潦潭潮潲潴潸潺潼澄澈澉澌澍澎澜澡澧澳澶澹激濂濉濑濒濞濠濡濮濯瀑瀚瀛瀣瀵瀹灌灏灞火灬灭灯灰灵灶灸灼灾灿炀炅炉炊炎炒炔炕炖炙炜炝炫炬炭炮炯炱炳炷炸点炻炼炽烀烁烂烃烈烊烘烙烛烟烤烦烧烨烩烫烬热烯烷烹烽焉焊焐焓焕焖焘焙焚焦焯焰焱然煅煊煌煎煜煞煤煦照煨煮煲煳煸煺煽熄熊熏熔熘熙熟熠熨熬熳熵熹燃燎燔燕燠燥燧燮燹爆爝爨爪爬爰爱爵父爷爸爹爻爽爿片版牌牍牒牖牙牛牝牟牡牢牦牧物牮牯牲牵特牺牾牿犀犁犄犊犋犍犏犒犟犬犭犯犰犴状犷犸犹狁狂狃狄狈狍狎狐狒狗狙狞狠狡狨狩独狭狮狯狰狱狲狳狴狷狸狺狻狼猁猃猊猎猓猕猖猗猛猜猝猞猡猢猥猩猪猫猬献猱猴猷猸猹猾猿獍獐獒獗獠獬獭獯獾玄率玉王玎玑玖玛玟玢玩玫玮环现玲玳玷玺玻珀珂珈珉珊珍珏珐珑珙珞珠珥珧珩班珲球琅理琉琊琏琐琚琛琢琥琦琨琪琬琮琰琳琴琵琶琼瑁瑕瑗瑙瑚瑛瑜瑞瑟瑭瑰瑶瑷瑾璀璁璃璇璋璎璐璜璞璧璨璩璺瓒瓜瓞瓠瓢瓣瓤瓦瓮瓯瓴瓶瓷瓿甄甍甏甑甓甘甙甚甜生甥用甩甫甬甭甯田由甲申电男甸町画甾畀畅畈畋界畎畏畔留畚畛畜略畦番畲畴畸畹畿疃疆疋疏疑疒疔疖疗疙疚疝疟疠疡疣疤疥疫疬疮疯疰疱疲疳疴疵疸疹疼疽疾痂痃痄病症痈痉痊痍痒痔痕痖痘痛痞痢痣痤痦痧痨痪痫痰痱痴痹痼痿瘀瘁瘃瘅瘊瘌瘐瘕瘗瘘瘙瘛瘟瘠瘢瘤瘥瘦瘩瘪瘫瘭瘰瘳瘴瘵瘸瘼瘾瘿癀癃癌癍癔癖癜癞癣癫癯癸登白百皂的皆皇皈皋皎皑皓皖皙皤皮皱皲皴皿盂盅盆盈益盍盎盏盐监盒盔盖盗盘盛盟盥目盯盱盲直相盹盼盾省眄眇眈眉看眍眙眚真眠眢眦眨眩眭眯眵眶眷眸眺眼着睁睃睇睐睑睚睛睡睢督睥睦睨睫睬睹睽睾睿瞀瞄瞅瞌瞍瞎瞑瞒瞟瞠瞢瞥瞧瞩瞪瞬瞰瞳瞵瞻瞽瞿矍矗矛矜矢矣知矧矩矫矬短矮石矶矸矽矾矿砀码砂砉砌砍砑砒研砖砗砘砚砜砝砟砣砥砦砧砩砬砭砰破砷砸砹砺砻砼砾础硅硇硌硎硐硒硕硖硗硝硪硫硬硭确硷硼碇碉碌碍碎碑碓碗碘碚碛碜碟碡碣碥碧碰碱碲碳碴碹碾磁磅磉磊磋磐磔磕磙磨磬磲磴磷磺礁礅礓礞礤礴示礻礼社祀祁祆祈祉祓祖祗祚祛祜祝神祟祠祢祥祧票祭祯祷祸祺禀禁禄禅禊福禚禧禳禹禺离禽禾秀私秃秆秉秋种科秒秕秘租秣秤秦秧秩秫秭积称秸移秽稀稂稃稆程稍税稔稗稚稞稠稣稳稷稹稻稼稽稿穆穑穗穰穴究穷穸穹空穿窀突窃窄窆窈窍窑窒窕窖窗窘窜窝窟窠窥窦窨窬窭窳窿立竖站竞竟章竣童竦竭端竹竺竽竿笃笄笆笈笊笋笏笑笔笕笙笛笞笠笤笥符笨笪笫第笮笱笳笸笺笼笾筅筇等筋筌筏筐筑筒答策筘筚筛筝筠筢筮筱筲筵筷筹筻签简箅箍箐箔箕算箜箝管箢箦箧箨箩箪箫箬箭箱箴箸篁篆篇篌篑篓篙篚篝篡篥篦篪篮篱篷篼篾簇簋簌簏簖簟簦簧簪簸簿籀籁籍米籴类籼籽粉粑粒粕粗粘粜粝粞粟粢粤粥粪粮粱粲粳粹粼粽精糁糅糇糈糊糌糍糕糖糗糙糜糟糠糨糯糸系紊素索紧紫累絮絷綦綮縻繁繇纂纛纟纠纡红纣纤纥约级纨纩纪纫纬纭纯纰纱纲纳纵纶纷纸纹纺纽纾线绀绁绂练组绅细织终绉绊绋绌绍绎经绐绑绒结绔绕绗绘给绚绛络绝绞统绠绡绢绣绥绦继绨绩绪绫续绮绯绰绱绲绳维绵绶绷绸绺绻综绽绾绿缀缁缂缃缄缅缆缇缈缉缋缌缍缎缏缑缒缓缔缕编缗缘缙缚缛缜缝缟缠缡缢缣缤缥缦缧缨缩缪缫缬缭缮缯缰缱缲缳缴缵缶缸缺罂罄罅罐网罔罕罗罘罚罟罡罢罨罩罪置罱署罴罹罾羁羊羌美羔羚羝羞羟羡群羧羯羰羲羸羹羼羽羿翁翅翊翌翎翔翕翘翟翠翡翥翦翩翮翰翱翳翻翼耀老考耄者耆耋而耍耐耒耔耕耖耗耘耙耜耠耢耥耦耧耨耩耪耱耳耵耶耷耸耻耽耿聂聃聆聊聋职聍聒联聘聚聩聪聱聿肀肃肄肆肇肉肋肌肓肖肘肚肛肜肝肟肠股肢肤肥肩肪肫肭肮肯肱育肴肷肺肼肽肾肿胀胁胂胃胄胆背胍胎胖胗胙胚胛胜胝胞胡胤胥胧胨胩胪胫胬胭胯胰胱胲胳胴胶胸胺胼能脂脆脉脊脍脎脏脐脑脒脓脔脖脘脚脞脬脯脱脲脶脸脾腆腈腊腋腌腐腑腓腔腕腙腚腠腥腧腩腭腮腰腱腴腹腺腻腼腽腾腿膀膂膈膊膏膑膘膛膜膝膣膦膨膪膳膺膻臀臁臂臃臆臊臌臣臧自臬臭至致臻臼臾舀舁舂舄舅舆舌舍舐舒舔舛舜舞舟舡舢舣舨航舫般舭舯舰舱舳舴舵舶舷舸船舻舾艄艇艉艋艏艘艚艟艨艮良艰色艳艴艹艺艽艾艿节芄芈芊芋芍芎芏芑芒芗芘芙芜芝芟芡芤芥芦芨芩芪芫芬芭芮芯芰花芳芴芷芸芹芽芾苁苄苇苈苊苋苌苍苎苏苑苒苓苔苕苗苘苛苜苞苟苠苡苣苤若苦苫苯英苴苷苹苻茁茂范茄茅茆茇茈茉茌茎茏茑茔茕茗茚茛茜茧茨茫茬茭茯茱茳茴茵茶茸茹茺茼荀荃荆荇草荏荐荑荒荔荚荛荜荞荟荠荡荣荤荥荦荧荨荩荪荫荬荭荮药荷荸荻荼荽莅莆莉莎莒莓莘莛莜莞莠莨莩莪莫莰莱莲莳莴莶获莸莹莺莼莽菀菁菅菇菊菌菏菔菖菘菜菝菟菠菡菥菩菪菰菱菲菸菹菽萁萃萄萆萋萌萍萎萏萑萘萜萝萤营萦萧萨萱萸萼落葆葑著葙葚葛葜葡董葩葫葬葭葱葳葵葶葸葺蒂蒇蒈蒉蒋蒌蒎蒗蒙蒜蒡蒯蒲蒴蒸蒹蒺蒽蒿蓁蓄蓉蓊蓍蓐蓑蓓蓖蓝蓟蓠蓣蓥蓦蓬蓰蓼蓿蔌蔑蔓蔗蔚蔟蔡蔫蔬蔷蔸蔹蔺蔻蔼蔽蕃蕈蕉蕊蕖蕙蕞蕤蕨蕲蕴蕹蕺蕻蕾薄薅薇薏薛薜薤薨薪薮薯薰薷薹藁藉藏藐藓藕藜藤藩藻藿蘅蘑蘖蘧蘩蘸蘼虍虎虏虐虑虔虚虞虢虫虬虮虱虹虺虻虼虽虾虿蚀蚁蚂蚊蚋蚌蚍蚓蚕蚜蚝蚣蚤蚧蚨蚩蚪蚬蚯蚰蚱蚴蚵蚶蚺蛀蛄蛆蛇蛉蛊蛋蛎蛏蛐蛑蛔蛘蛙蛛蛞蛟蛤蛩蛭蛮蛰蛱蛲蛳蛴蛸蛹蛾蜀蜂蜃蜇蜈蜉蜊蜍蜒蜓蜕蜗蜘蜚蜜蜞蜡蜢蜣蜥蜩蜮蜱蜴蜷蜻蜾蜿蝇蝈蝉蝌蝎蝓蝗蝙蝠蝣蝤蝥蝮蝰蝴蝶蝻蝼蝽蝾螂螃螅螈螋融螓螗螟螨螫螬螭螯螳螵螺螽蟀蟆蟊蟋蟑蟒蟓蟛蟠蟥蟪蟮蟹蟾蠃蠊蠓蠕蠖蠛蠡蠢蠲蠹蠼血衄衅行衍衔街衙衡衢衣衤补表衩衫衬衮衰衲衷衽衾衿袁袂袄袅袈袋袍袒袖袜袢袤被袭袱袷袼裁裂装裆裉裎裒裔裕裘裙裟裢裣裤裥裨裰裱裳裴裸裹裼裾褂褊褐褒褓褙褚褛褡褥褪褫褰褴褶襁襄襞襟襦襻西要覃覆见观规觅视觇览觉觊觋觌觎觏觐觑角觖觚觜觞解觥触觫觯觳言訇訾詈詹誉誊誓謇謦警譬讠计订讣认讥讦讧讨让讪讫训议讯记讲讳讴讵讶讷许讹论讼讽设访诀证诂诃评诅识诈诉诊诋诌词诎诏译诒诓诔试诖诗诘诙诚诛诜话诞诟诠诡询诣诤该详诧诨诩诫诬语诮误诰诱诲诳说诵诶请诸诹诺读诼诽课诿谀谁谂调谄谅谆谇谈谊谋谌谍谎谏谐谑谒谓谔谕谖谗谘谙谚谛谜谝谟谠谡谢谣谤谥谦谧谨谩谪谫谬谭谮谯谰谱谲谳谴谵谶谷豁豆豇豉豌豕豚象豢豪豫豳豸豹豺貂貅貉貊貌貔貘贝贞负贡财责贤败账货质贩贪贫贬购贮贯贰贱贲贳贴贵贶贷贸费贺贻贼贽贾贿赀赁赂赃资赅赆赇赈赉赊赋赌赍赎赏赐赓赔赕赖赘赙赚赛赜赝赞赠赡赢赣赤赦赧赫赭走赳赴赵赶起趁趄超越趋趑趔趟趣趱足趴趵趸趺趼趾趿跃跄跆跋跌跎跏跑跖跗跚跛距跞跟跣跤跨跪跫跬路跳践跷跸跹跺跻跽踅踉踊踌踏踔踝踞踟踢踣踩踪踬踮踯踱踵踹踺踽蹀蹁蹂蹄蹇蹈蹉蹊蹋蹑蹒蹙蹦蹩蹬蹭蹯蹰蹲蹴蹶蹼蹿躁躅躇躏躐躔躜躞身躬躯躲躺軎车轧轨轩轫转轭轮软轰轱轲轳轴轵轶轷轸轹轺轻轼载轾轿辁辂较辄辅辆辇辈辉辊辋辍辎辏辐辑输辔辕辖辗辘辙辚辛辜辞辟辣辨辩辫辰辱辶边辽达迁迂迄迅过迈迎运近迓返迕还这进远违连迟迢迤迥迦迨迩迪迫迭迮述迳迷迸迹追退送适逃逄逅逆选逊逋逍透逐逑递途逖逗通逛逝逞速造逡逢逦逭逮逯逵逶逸逻逼逾遁遂遄遇遍遏遐遑遒道遗遘遛遢遣遥遨遭遮遴遵遽避邀邂邃邈邋邑邓邕邗邙邛邝邡邢那邦邪邬邮邯邰邱邳邴邵邶邸邹邺邻邾郁郄郅郇郊郎郏郐郑郓郗郛郜郝郡郢郦郧部郫郭郯郴郸都郾鄂鄄鄙鄞鄢鄣鄯鄱鄹酃酆酉酊酋酌配酎酏酐酒酗酚酝酞酡酢酣酤酥酩酪酬酮酯酰酱酲酴酵酶酷酸酹酽酾酿醅醇醉醋醌醍醐醑醒醚醛醢醣醪醭醮醯醴醵醺采釉释里重野量金釜鉴銎銮鋈錾鍪鎏鏊鏖鐾鑫钅钆钇针钉钊钋钌钍钎钏钐钒钓钔钕钗钙钚钛钜钝钞钟钠钡钢钣钤钥钦钧钨钩钪钫钬钭钮钯钰钱钲钳钴钵钶钷钸钹钺钻钼钽钾钿铀铁铂铃铄铅铆铈铉铊铋铌铍铎铐铑铒铕铖铗铘铙铛铜铝铞铟铠铡铢铣铤铥铧铨铩铪铫铬铭铮铯铰铱铲铳铴铵银铷铸铹铺铼铽链铿销锁锂锃锄锅锆锇锈锉锊锋锌锍锎锏锐锑锒锓锔锕锖锗锘错锚锛锝锞锟锡锢锣锤锥锦锨锩锪锫锬锭键锯锰锱锲锴锵锶锷锸锹锺锻锼锾锿镀镁镂镄镅镆镇镉镊镌镍镎镏镐镑镒镓镔镖镗镘镙镛镜镝镞镟镡镢镣镤镥镦镧镨镩镪镫镬镭镯镰镱镲镳镶长门闩闪闫闭问闯闰闱闲闳间闵闶闷闸闹闺闻闼闽闾阀阁阂阃阄阅阆阈阉阊阋阌阍阎阏阐阑阒阔阕阖阗阙阚阜阝队阡阢阪阮阱防阳阴阵阶阻阼阽阿陀陂附际陆陇陈陉陋陌降限陔陕陛陟陡院除陧陨险陪陬陲陴陵陶陷隅隆隈隋隍随隐隔隗隘隙障隧隰隳隶隹隼隽难雀雁雄雅集雇雉雌雍雎雏雒雕雠雨雩雪雯雳零雷雹雾需霁霄霆震霈霉霍霎霏霓霖霜霞霪霭霰露霸霹霾青靓靖静靛非靠靡面靥革靳靴靶靼鞅鞋鞍鞑鞒鞔鞘鞠鞣鞫鞭鞯鞲鞴韦韧韩韪韫韬韭音韵韶页顶顷顸项顺须顼顽顾顿颀颁颂颃预颅领颇颈颉颊颌颍颏颐频颓颔颖颗题颚颛颜额颞颟颠颡颢颤颥颦颧风飑飒飓飕飘飙飚飞食飧飨餍餐餮饔饕饣饥饧饨饩饪饫饬饭饮饯饰饱饲饴饵饶饷饺饼饽饿馀馁馄馅馆馇馈馊馋馍馏馐馑馒馓馔馕首馗馘香馥馨马驭驮驯驰驱驳驴驵驶驷驸驹驺驻驼驽驾驿骀骁骂骄骅骆骇骈骊骋验骏骐骑骒骓骖骗骘骚骛骜骝骞骟骠骡骢骣骤骥骧骨骰骱骶骷骸骺骼髀髁髂髅髋髌髑髓高髟髡髦髫髭髯髹髻鬃鬈鬏鬓鬟鬣鬯鬲鬻鬼魁魂魃魄魅魇魈魉魍魏魑魔鱼鱿鲁鲂鲅鲆鲇鲈鲋鲍鲎鲐鲑鲒鲔鲕鲚鲛鲜鲞鲟鲠鲡鲢鲣鲤鲥鲦鲧鲨鲩鲫鲭鲮鲰鲱鲲鲳鲴鲵鲶鲷鲸鲺鲻鲼鲽鳃鳄鳅鳆鳇鳊鳋鳌鳍鳎鳏鳐鳓鳔鳕鳖鳗鳘鳙鳜鳝鳞鳟鳢鸟鸠鸡鸢鸣鸥鸦鸨鸩鸪鸫鸬鸭鸯鸱鸲鸳鸵鸶鸷鸸鸹鸺鸽鸾鸿鹁鹂鹃鹄鹅鹆鹇鹈鹉鹊鹋鹌鹎鹏鹑鹕鹗鹘鹚鹛鹜鹞鹣鹤鹦鹧鹨鹩鹪鹫鹬鹭鹰鹱鹳鹾鹿麂麇麈麋麒麓麝麟麦麴麸麻麽麾黄黉黍黎黏黑黔默黛黜黝黟黠黢黥黧黩黪黯黹黻黼黾鼋鼍鼎鼐鼓鼗鼙鼠鼢鼬鼯鼷鼹鼻鼽鼾齄齐齑齿龀龃龄龅龆龇龈龉龊龋龌龙龚龛龟龠 \ No newline at end of file +一丁七万丈三上下丌不与丐丑专且丕世丘丙业丛东丝丞丢两严丧丨个丫丬中丰串临丶丸丹为主丽举丿乃久乇么义之乌乍乎乏乐乒乓乔乖乘乙乜九乞 +也习乡书乩买乱乳乾了予争事二亍于亏云互亓五井亘亚些亟亠亡亢交亥亦产亨亩享京亭亮亲亳亵人亻亿什仁仂仃仄仅仆仇仉今介仍从仑仓仔仕他仗 +付仙仝仞仟仡代令以仨仪仫们仰仲仳仵件价任份仿企伉伊伍伎伏伐休众优伙会伛伞伟传伢伤伥伦伧伪伫伯估伲伴伶伸伺似伽佃但位低住佐佑体何佗 +佘余佚佛作佝佞佟你佣佤佥佧佩佬佯佰佳佴佶佻佼佾使侃侄侈侉例侍侏侑侔侗供依侠侣侥侦侧侨侩侪侬侮侯侵便促俄俅俊俎俏俐俑俗俘俚俜保俞俟 +信俣俦俨俩俪俭修俯俱俳俸俺俾倌倍倏倒倔倘候倚倜借倡倥倦倨倩倪倬倭倮债值倾偃假偈偌偎偏偕做停健偬偶偷偻偾偿傀傅傈傍傣傥傧储傩催傲傺 +傻像僖僚僦僧僬僭僮僳僵僻儆儇儋儒儡儿兀允元兄充兆先光克免兑兔兕兖党兜兢入全八公六兮兰共关兴兵其具典兹养兼兽冀冁冂内冈冉册再冒冕冖 +冗写军农冠冢冤冥冫冬冯冰冱冲决况冶冷冻冼冽净凄准凇凉凋凌减凑凛凝几凡凤凫凭凯凰凳凵凶凸凹出击凼函凿刀刁刂刃分切刈刊刍刎刑划刖列刘 +则刚创初删判刨利别刭刮到刳制刷券刹刺刻刽刿剀剁剂剃削剌前剐剑剔剖剜剞剡剥剧剩剪副割剽剿劁劂劈劐劓力劝办功加务劢劣动助努劫劬劭励劲 +劳劾势勃勇勉勋勐勒勖勘募勤勰勹勺勾勿匀包匆匈匍匏匐匕化北匙匚匝匠匡匣匦匪匮匹区医匾匿十千卅升午卉半华协卑卒卓单卖南博卜卞卟占卡卢 +卣卤卦卧卩卫卮卯印危即却卵卷卸卺卿厂厄厅历厉压厌厍厕厘厚厝原厢厣厥厦厨厩厮厶去县叁参又叉及友双反发叔取受变叙叛叟叠口古句另叨叩只 +叫召叭叮可台叱史右叵叶号司叹叻叼叽吁吃各吆合吉吊同名后吏吐向吒吓吕吖吗君吝吞吟吠吡吣否吧吨吩含听吭吮启吱吲吴吵吸吹吻吼吾呀呃呆呈 +告呋呐呒呓呔呕呖呗员呙呛呜呢呤呦周呱呲味呵呶呷呸呻呼命咀咂咄咆咋和咎咏咐咒咔咕咖咙咚咛咝咣咤咦咧咨咩咪咫咬咭咯咱咳咴咸咻咽咿哀品 +哂哄哆哇哈哉哌响哎哏哐哑哒哓哔哕哗哙哚哜哝哞哟哥哦哧哨哩哪哭哮哲哳哺哼哽哿唁唆唇唉唏唐唑唔唛唠唢唣唤唧唪唬售唯唰唱唳唷唼唾唿啁啃 +啄商啉啊啐啕啖啜啡啤啥啦啧啪啬啭啮啵啶啷啸啻啼啾喀喁喂喃善喇喈喉喊喋喏喑喔喘喙喜喝喟喧喱喳喵喷喹喻喽喾嗄嗅嗉嗌嗍嗑嗒嗓嗔嗖嗜嗝嗟 +嗡嗣嗤嗥嗦嗨嗪嗫嗬嗯嗲嗳嗵嗷嗽嗾嘀嘁嘈嘉嘌嘎嘏嘘嘛嘞嘟嘣嘤嘧嘬嘭嘱嘲嘴嘶嘹嘻嘿噌噍噎噔噗噘噙噜噢噤器噩噪噫噬噱噶噻噼嚅嚆嚎嚏嚓嚣 +嚯嚷嚼囊囔囗囚四囝回囟因囡团囤囫园困囱围囵囹固国图囿圃圄圆圈圉圊圜土圣在圩圪圬圭圮圯地圳圹场圻圾址坂均坊坌坍坎坏坐坑块坚坛坜坝坞 +坟坠坡坤坦坨坩坪坫坭坯坳坶坷坻坼垂垃垄垅垆型垌垒垓垛垠垡垢垣垤垦垧垩垫垭垮垲垴垸埂埃埋城埏埒埔埕埘埙埚埝域埠埤埭埯埴埸培基埽堀堂 +堆堇堋堍堑堕堙堞堠堡堤堪堰堵塄塌塍塑塔塘塞塥填塬塾墀墁境墅墉墒墓墙墚增墟墨墩墼壁壅壑壕壤士壬壮声壳壶壹夂处备复夏夔夕外夙多夜够夤 +夥大天太夫夭央夯失头夷夸夹夺夼奁奂奄奇奈奉奋奎奏契奔奕奖套奘奚奠奢奥女奴奶奸她好妁如妃妄妆妇妈妊妍妒妓妖妗妙妞妣妤妥妨妩妪妫妮妯 +妲妹妻妾姆姊始姐姑姒姓委姗姘姚姜姝姣姥姨姬姹姻姿威娃娄娅娆娇娈娉娌娑娓娘娜娟娠娣娥娩娱娲娴娶娼婀婆婉婊婕婚婢婧婪婴婵婶婷婺婿媒媚 +媛媪媲媳媵媸媾嫁嫂嫉嫌嫒嫔嫖嫘嫜嫠嫡嫣嫦嫩嫫嫱嬉嬖嬗嬲嬴嬷孀子孑孓孔孕字存孙孚孛孜孝孟孢季孤孥学孩孪孬孰孱孳孵孺孽宀宁它宄宅宇守 +安宋完宏宓宕宗官宙定宛宜宝实宠审客宣室宥宦宪宫宰害宴宵家宸容宽宾宿寂寄寅密寇富寐寒寓寝寞察寡寤寥寨寮寰寸对寺寻导寿封射将尉尊小少 +尔尕尖尘尚尜尝尢尤尥尧尬就尴尸尹尺尻尼尽尾尿局屁层居屈屉届屋屎屏屐屑展屙属屠屡屣履屦屮屯山屹屺屿岁岂岈岌岍岐岑岔岖岗岘岙岚岛岜岢 +岣岩岫岬岭岱岳岵岷岸岽岿峁峄峋峒峙峡峤峥峦峨峪峭峰峻崂崃崆崇崎崔崖崛崞崤崦崧崩崭崮崴崽崾嵇嵊嵋嵌嵘嵛嵝嵩嵫嵬嵯嵴嶂嶙嶝嶷巅巍巛川 +州巡巢工左巧巨巩巫差巯己已巳巴巷巽巾币市布帅帆师希帏帐帑帔帕帖帘帙帚帛帜帝带帧席帮帱帷常帻帼帽幂幄幅幌幔幕幛幞幡幢干平年并幸幺幻 +幼幽广庀庄庆庇床庋序庐庑库应底庖店庙庚府庞废庠庥度座庭庳庵庶康庸庹庾廉廊廑廒廓廖廛廨廪廴延廷建廾廿开弁异弃弄弈弊弋式弑弓引弗弘弛 +弟张弥弦弧弩弪弭弯弱弹强弼彀彐归当录彖彗彘彝彡形彤彦彩彪彬彭彰影彳彷役彻彼往征徂径待徇很徉徊律後徐徒徕得徘徙徜御徨循徭微徵德徼徽 +心忄必忆忉忌忍忏忐忑忒忖志忘忙忝忠忡忤忧忪快忭忮忱念忸忻忽忾忿怀态怂怃怄怅怆怊怍怎怏怒怔怕怖怙怛怜思怠怡急怦性怨怩怪怫怯怵总怼怿 +恁恂恃恋恍恐恒恕恙恚恝恢恣恤恧恨恩恪恫恬恭息恰恳恶恸恹恺恻恼恽恿悃悄悉悌悍悒悔悖悚悛悝悟悠患悦您悫悬悭悯悱悲悴悸悻悼情惆惊惋惑惕 +惘惚惜惝惟惠惦惧惨惩惫惬惭惮惯惰想惴惶惹惺愀愁愆愈愉愍愎意愕愚感愠愣愤愦愧愫愿慈慊慌慎慑慕慝慢慧慨慰慵慷憋憎憔憝憧憨憩憬憷憾懂懈 +懊懋懑懒懔懦懵懿戆戈戊戋戌戍戎戏成我戒戕或戗战戚戛戟戡戢戤戥截戬戮戳戴户戽戾房所扁扃扇扈扉手扌才扎扑扒打扔托扛扣扦执扩扪扫扬扭扮 +扯扰扳扶批扼找承技抄抉把抑抒抓投抖抗折抚抛抟抠抡抢护报抨披抬抱抵抹抻押抽抿拂拄担拆拇拈拉拊拌拍拎拐拒拓拔拖拗拘拙拚招拜拟拢拣拥拦 +拧拨择括拭拮拯拱拳拴拶拷拼拽拾拿持挂指挈按挎挑挖挚挛挝挞挟挠挡挢挣挤挥挨挪挫振挲挹挺挽捂捃捅捆捉捋捌捍捎捏捐捕捞损捡换捣捧捩捭据 +捱捶捷捺捻掀掂掇授掉掊掌掎掏掐排掖掘掠探掣接控推掩措掬掭掮掰掳掴掷掸掺掼掾揄揆揉揍揎描提插揖揞揠握揣揩揪揭揲援揶揸揽揿搀搁搂搅搋 +搌搏搐搓搔搛搜搞搠搡搦搪搬搭搴携搽搿摁摄摅摆摇摈摊摒摔摘摞摧摩摭摸摹摺撂撄撅撇撑撒撕撖撙撞撤撩撬播撮撰撵撷撸撺撼擀擂擅操擎擐擒擗 +擘擞擢擤擦攀攉攒攘攥攫攮支攴攵收攸改攻放政故效敉敌敏救敕敖教敛敝敞敢散敦敫敬数敲整敷文斋斌斐斑斓斗料斛斜斟斡斤斥斧斩斫断斯新方於 +施旁旃旄旅旆旋旌旎族旒旖旗无既日旦旧旨早旬旭旮旯旰旱时旷旺昀昂昃昆昊昌明昏易昔昕昙昝星映春昧昨昭是昱昴昵昶昼显晁晃晋晌晏晒晓晔晕 +晖晗晚晟晡晤晦晨普景晰晴晶晷智晾暂暄暇暌暑暖暗暝暧暨暮暴暹暾曙曛曜曝曦曩曰曲曳更曷曹曼曾替最月有朊朋服朐朔朕朗望朝期朦木未末本札 +术朱朴朵机朽杀杂权杆杈杉杌李杏材村杓杖杜杞束杠条来杨杩杪杭杯杰杲杳杵杷杼松板极构枇枉枋析枕林枘枚果枝枞枢枣枥枧枨枪枫枭枯枰枳枵架 +枷枸柁柃柄柏某柑柒染柔柘柙柚柜柝柞柠柢查柩柬柯柰柱柳柴柽柿栀栅标栈栉栊栋栌栎栏树栓栖栗栝校栩株栲栳样核根格栽栾桀桁桂桃桄桅框案桉 +桊桌桎桐桑桓桔桕桠桡桢档桤桥桦桧桨桩桫桴桶桷梁梃梅梆梏梓梗梢梦梧梨梭梯械梳梵检棂棉棋棍棒棕棘棚棠棣森棰棱棵棹棺棼椁椅椋植椎椐椒椟 +椠椤椭椰椴椹椽椿楂楔楗楚楝楞楠楣楦楫楮楱楷楸楹楼榀概榄榆榇榈榉榍榔榕榘榛榜榧榨榫榭榱榴榷榻槁槊槌槎槐槔槛槟槠槭槲槽槿樊樗樘樟模樨 +横樯樱樵樽樾橄橇橐橘橙橛橡橥橱橹橼檀檄檎檐檑檗檠檩檫檬欠次欢欣欤欧欲欷欹欺款歃歆歇歉歌歙止正此步武歧歪歹死歼殁殂殃殄殆殇殉殊残殍 +殒殓殖殚殛殡殪殳殴段殷殿毁毂毅毋母每毒毓比毕毖毗毙毛毡毪毫毯毳毵毹毽氅氆氇氍氏氐民氓气氕氖氘氙氚氛氟氡氢氤氦氧氨氩氪氮氯氰氲水氵 +永氽汀汁求汆汇汉汊汐汔汕汗汛汜汝汞江池污汤汨汩汪汰汲汴汶汹汽汾沁沂沃沅沆沈沉沌沏沐沓沔沙沛沟没沣沤沥沦沧沩沪沫沭沮沱沲河沸油治沼 +沽沾沿泄泅泉泊泌泐泓泔法泖泗泛泞泠泡波泣泥注泪泫泮泯泰泱泳泵泶泷泸泺泻泼泽泾洁洄洇洋洌洎洒洗洙洚洛洞津洧洪洫洮洱洲洳洵洹活洼洽派 +流浃浅浆浇浈浊测浍济浏浑浒浓浔浙浚浜浞浠浣浦浩浪浮浯浴海浸浼涂涅消涉涌涎涑涓涔涕涛涝涞涟涠涡涣涤润涧涨涩涪涫涮涯液涵涸涿淀淄淅淆 +淇淋淌淑淖淘淙淝淞淠淡淤淦淫淬淮深淳混淹添淼清渊渌渍渎渐渑渔渖渗渚渝渠渡渣渤渥温渫渭港渲渴游渺湃湄湍湎湓湔湖湘湛湟湫湮湾湿溃溅溆 +溉溏源溘溜溟溢溥溧溪溯溱溲溴溶溷溺溻溽滁滂滇滋滏滑滓滔滕滗滚滞滟滠满滢滤滥滦滨滩滴滹漂漆漉漏漓演漕漠漤漩漪漫漭漯漱漳漶漾潆潇潋潍 +潘潜潞潢潦潭潮潲潴潸潺潼澄澈澉澌澍澎澜澡澧澳澶澹激濂濉濑濒濞濠濡濮濯瀑瀚瀛瀣瀵瀹灌灏灞火灬灭灯灰灵灶灸灼灾灿炀炅炉炊炎炒炔炕炖炙 +炜炝炫炬炭炮炯炱炳炷炸点炻炼炽烀烁烂烃烈烊烘烙烛烟烤烦烧烨烩烫烬热烯烷烹烽焉焊焐焓焕焖焘焙焚焦焯焰焱然煅煊煌煎煜煞煤煦照煨煮煲煳 +煸煺煽熄熊熏熔熘熙熟熠熨熬熳熵熹燃燎燔燕燠燥燧燮燹爆爝爨爪爬爰爱爵父爷爸爹爻爽爿片版牌牍牒牖牙牛牝牟牡牢牦牧物牮牯牲牵特牺牾牿犀 +犁犄犊犋犍犏犒犟犬犭犯犰犴状犷犸犹狁狂狃狄狈狍狎狐狒狗狙狞狠狡狨狩独狭狮狯狰狱狲狳狴狷狸狺狻狼猁猃猊猎猓猕猖猗猛猜猝猞猡猢猥猩猪 +猫猬献猱猴猷猸猹猾猿獍獐獒獗獠獬獭獯獾玄率玉王玎玑玖玛玟玢玩玫玮环现玲玳玷玺玻珀珂珈珉珊珍珏珐珑珙珞珠珥珧珩班珲球琅理琉琊琏琐琚 +琛琢琥琦琨琪琬琮琰琳琴琵琶琼瑁瑕瑗瑙瑚瑛瑜瑞瑟瑭瑰瑶瑷瑾璀璁璃璇璋璎璐璜璞璧璨璩璺瓒瓜瓞瓠瓢瓣瓤瓦瓮瓯瓴瓶瓷瓿甄甍甏甑甓甘甙甚甜 +生甥用甩甫甬甭甯田由甲申电男甸町画甾畀畅畈畋界畎畏畔留畚畛畜略畦番畲畴畸畹畿疃疆疋疏疑疒疔疖疗疙疚疝疟疠疡疣疤疥疫疬疮疯疰疱疲疳 +疴疵疸疹疼疽疾痂痃痄病症痈痉痊痍痒痔痕痖痘痛痞痢痣痤痦痧痨痪痫痰痱痴痹痼痿瘀瘁瘃瘅瘊瘌瘐瘕瘗瘘瘙瘛瘟瘠瘢瘤瘥瘦瘩瘪瘫瘭瘰瘳瘴瘵瘸 +瘼瘾瘿癀癃癌癍癔癖癜癞癣癫癯癸登白百皂的皆皇皈皋皎皑皓皖皙皤皮皱皲皴皿盂盅盆盈益盍盎盏盐监盒盔盖盗盘盛盟盥目盯盱盲直相盹盼盾省眄 +眇眈眉看眍眙眚真眠眢眦眨眩眭眯眵眶眷眸眺眼着睁睃睇睐睑睚睛睡睢督睥睦睨睫睬睹睽睾睿瞀瞄瞅瞌瞍瞎瞑瞒瞟瞠瞢瞥瞧瞩瞪瞬瞰瞳瞵瞻瞽瞿矍 +矗矛矜矢矣知矧矩矫矬短矮石矶矸矽矾矿砀码砂砉砌砍砑砒研砖砗砘砚砜砝砟砣砥砦砧砩砬砭砰破砷砸砹砺砻砼砾础硅硇硌硎硐硒硕硖硗硝硪硫硬 +硭确硷硼碇碉碌碍碎碑碓碗碘碚碛碜碟碡碣碥碧碰碱碲碳碴碹碾磁磅磉磊磋磐磔磕磙磨磬磲磴磷磺礁礅礓礞礤礴示礻礼社祀祁祆祈祉祓祖祗祚祛祜 +祝神祟祠祢祥祧票祭祯祷祸祺禀禁禄禅禊福禚禧禳禹禺离禽禾秀私秃秆秉秋种科秒秕秘租秣秤秦秧秩秫秭积称秸移秽稀稂稃稆程稍税稔稗稚稞稠稣 +稳稷稹稻稼稽稿穆穑穗穰穴究穷穸穹空穿窀突窃窄窆窈窍窑窒窕窖窗窘窜窝窟窠窥窦窨窬窭窳窿立竖站竞竟章竣童竦竭端竹竺竽竿笃笄笆笈笊笋笏 +笑笔笕笙笛笞笠笤笥符笨笪笫第笮笱笳笸笺笼笾筅筇等筋筌筏筐筑筒答策筘筚筛筝筠筢筮筱筲筵筷筹筻签简箅箍箐箔箕算箜箝管箢箦箧箨箩箪箫箬 +箭箱箴箸篁篆篇篌篑篓篙篚篝篡篥篦篪篮篱篷篼篾簇簋簌簏簖簟簦簧簪簸簿籀籁籍米籴类籼籽粉粑粒粕粗粘粜粝粞粟粢粤粥粪粮粱粲粳粹粼粽精糁 +糅糇糈糊糌糍糕糖糗糙糜糟糠糨糯糸系紊素索紧紫累絮絷綦綮縻繁繇纂纛纟纠纡红纣纤纥约级纨纩纪纫纬纭纯纰纱纲纳纵纶纷纸纹纺纽纾线绀绁绂 +练组绅细织终绉绊绋绌绍绎经绐绑绒结绔绕绗绘给绚绛络绝绞统绠绡绢绣绥绦继绨绩绪绫续绮绯绰绱绲绳维绵绶绷绸绺绻综绽绾绿缀缁缂缃缄缅缆 +缇缈缉缋缌缍缎缏缑缒缓缔缕编缗缘缙缚缛缜缝缟缠缡缢缣缤缥缦缧缨缩缪缫缬缭缮缯缰缱缲缳缴缵缶缸缺罂罄罅罐网罔罕罗罘罚罟罡罢罨罩罪置 +罱署罴罹罾羁羊羌美羔羚羝羞羟羡群羧羯羰羲羸羹羼羽羿翁翅翊翌翎翔翕翘翟翠翡翥翦翩翮翰翱翳翻翼耀老考耄者耆耋而耍耐耒耔耕耖耗耘耙耜耠 +耢耥耦耧耨耩耪耱耳耵耶耷耸耻耽耿聂聃聆聊聋职聍聒联聘聚聩聪聱聿肀肃肄肆肇肉肋肌肓肖肘肚肛肜肝肟肠股肢肤肥肩肪肫肭肮肯肱育肴肷肺肼 +肽肾肿胀胁胂胃胄胆背胍胎胖胗胙胚胛胜胝胞胡胤胥胧胨胩胪胫胬胭胯胰胱胲胳胴胶胸胺胼能脂脆脉脊脍脎脏脐脑脒脓脔脖脘脚脞脬脯脱脲脶脸脾 +腆腈腊腋腌腐腑腓腔腕腙腚腠腥腧腩腭腮腰腱腴腹腺腻腼腽腾腿膀膂膈膊膏膑膘膛膜膝膣膦膨膪膳膺膻臀臁臂臃臆臊臌臣臧自臬臭至致臻臼臾舀舁 +舂舄舅舆舌舍舐舒舔舛舜舞舟舡舢舣舨航舫般舭舯舰舱舳舴舵舶舷舸船舻舾艄艇艉艋艏艘艚艟艨艮良艰色艳艴艹艺艽艾艿节芄芈芊芋芍芎芏芑芒芗 +芘芙芜芝芟芡芤芥芦芨芩芪芫芬芭芮芯芰花芳芴芷芸芹芽芾苁苄苇苈苊苋苌苍苎苏苑苒苓苔苕苗苘苛苜苞苟苠苡苣苤若苦苫苯英苴苷苹苻茁茂范茄 +茅茆茇茈茉茌茎茏茑茔茕茗茚茛茜茧茨茫茬茭茯茱茳茴茵茶茸茹茺茼荀荃荆荇草荏荐荑荒荔荚荛荜荞荟荠荡荣荤荥荦荧荨荩荪荫荬荭荮药荷荸荻荼 +荽莅莆莉莎莒莓莘莛莜莞莠莨莩莪莫莰莱莲莳莴莶获莸莹莺莼莽菀菁菅菇菊菌菏菔菖菘菜菝菟菠菡菥菩菪菰菱菲菸菹菽萁萃萄萆萋萌萍萎萏萑萘萜 +萝萤营萦萧萨萱萸萼落葆葑著葙葚葛葜葡董葩葫葬葭葱葳葵葶葸葺蒂蒇蒈蒉蒋蒌蒎蒗蒙蒜蒡蒯蒲蒴蒸蒹蒺蒽蒿蓁蓄蓉蓊蓍蓐蓑蓓蓖蓝蓟蓠蓣蓥蓦蓬 +蓰蓼蓿蔌蔑蔓蔗蔚蔟蔡蔫蔬蔷蔸蔹蔺蔻蔼蔽蕃蕈蕉蕊蕖蕙蕞蕤蕨蕲蕴蕹蕺蕻蕾薄薅薇薏薛薜薤薨薪薮薯薰薷薹藁藉藏藐藓藕藜藤藩藻藿蘅蘑蘖蘧蘩 +蘸蘼虍虎虏虐虑虔虚虞虢虫虬虮虱虹虺虻虼虽虾虿蚀蚁蚂蚊蚋蚌蚍蚓蚕蚜蚝蚣蚤蚧蚨蚩蚪蚬蚯蚰蚱蚴蚵蚶蚺蛀蛄蛆蛇蛉蛊蛋蛎蛏蛐蛑蛔蛘蛙蛛蛞蛟 +蛤蛩蛭蛮蛰蛱蛲蛳蛴蛸蛹蛾蜀蜂蜃蜇蜈蜉蜊蜍蜒蜓蜕蜗蜘蜚蜜蜞蜡蜢蜣蜥蜩蜮蜱蜴蜷蜻蜾蜿蝇蝈蝉蝌蝎蝓蝗蝙蝠蝣蝤蝥蝮蝰蝴蝶蝻蝼蝽蝾螂螃螅螈 +螋融螓螗螟螨螫螬螭螯螳螵螺螽蟀蟆蟊蟋蟑蟒蟓蟛蟠蟥蟪蟮蟹蟾蠃蠊蠓蠕蠖蠛蠡蠢蠲蠹蠼血衄衅行衍衔街衙衡衢衣衤补表衩衫衬衮衰衲衷衽衾衿袁 +袂袄袅袈袋袍袒袖袜袢袤被袭袱袷袼裁裂装裆裉裎裒裔裕裘裙裟裢裣裤裥裨裰裱裳裴裸裹裼裾褂褊褐褒褓褙褚褛褡褥褪褫褰褴褶襁襄襞襟襦襻西要 +覃覆见观规觅视觇览觉觊觋觌觎觏觐觑角觖觚觜觞解觥触觫觯觳言訇訾詈詹誉誊誓謇謦警譬讠计订讣认讥讦讧讨让讪讫训议讯记讲讳讴讵讶讷许讹 +论讼讽设访诀证诂诃评诅识诈诉诊诋诌词诎诏译诒诓诔试诖诗诘诙诚诛诜话诞诟诠诡询诣诤该详诧诨诩诫诬语诮误诰诱诲诳说诵诶请诸诹诺读诼诽 +课诿谀谁谂调谄谅谆谇谈谊谋谌谍谎谏谐谑谒谓谔谕谖谗谘谙谚谛谜谝谟谠谡谢谣谤谥谦谧谨谩谪谫谬谭谮谯谰谱谲谳谴谵谶谷豁豆豇豉豌豕豚象 +豢豪豫豳豸豹豺貂貅貉貊貌貔貘贝贞负贡财责贤败账货质贩贪贫贬购贮贯贰贱贲贳贴贵贶贷贸费贺贻贼贽贾贿赀赁赂赃资赅赆赇赈赉赊赋赌赍赎赏 +赐赓赔赕赖赘赙赚赛赜赝赞赠赡赢赣赤赦赧赫赭走赳赴赵赶起趁趄超越趋趑趔趟趣趱足趴趵趸趺趼趾趿跃跄跆跋跌跎跏跑跖跗跚跛距跞跟跣跤跨跪 +跫跬路跳践跷跸跹跺跻跽踅踉踊踌踏踔踝踞踟踢踣踩踪踬踮踯踱踵踹踺踽蹀蹁蹂蹄蹇蹈蹉蹊蹋蹑蹒蹙蹦蹩蹬蹭蹯蹰蹲蹴蹶蹼蹿躁躅躇躏躐躔躜躞身 +躬躯躲躺軎车轧轨轩轫转轭轮软轰轱轲轳轴轵轶轷轸轹轺轻轼载轾轿辁辂较辄辅辆辇辈辉辊辋辍辎辏辐辑输辔辕辖辗辘辙辚辛辜辞辟辣辨辩辫辰辱 +辶边辽达迁迂迄迅过迈迎运近迓返迕还这进远违连迟迢迤迥迦迨迩迪迫迭迮述迳迷迸迹追退送适逃逄逅逆选逊逋逍透逐逑递途逖逗通逛逝逞速造逡 +逢逦逭逮逯逵逶逸逻逼逾遁遂遄遇遍遏遐遑遒道遗遘遛遢遣遥遨遭遮遴遵遽避邀邂邃邈邋邑邓邕邗邙邛邝邡邢那邦邪邬邮邯邰邱邳邴邵邶邸邹邺邻 +邾郁郄郅郇郊郎郏郐郑郓郗郛郜郝郡郢郦郧部郫郭郯郴郸都郾鄂鄄鄙鄞鄢鄣鄯鄱鄹酃酆酉酊酋酌配酎酏酐酒酗酚酝酞酡酢酣酤酥酩酪酬酮酯酰酱酲 +酴酵酶酷酸酹酽酾酿醅醇醉醋醌醍醐醑醒醚醛醢醣醪醭醮醯醴醵醺采釉释里重野量金釜鉴銎銮鋈錾鍪鎏鏊鏖鐾鑫钅钆钇针钉钊钋钌钍钎钏钐钒钓钔 +钕钗钙钚钛钜钝钞钟钠钡钢钣钤钥钦钧钨钩钪钫钬钭钮钯钰钱钲钳钴钵钶钷钸钹钺钻钼钽钾钿铀铁铂铃铄铅铆铈铉铊铋铌铍铎铐铑铒铕铖铗铘铙铛 +铜铝铞铟铠铡铢铣铤铥铧铨铩铪铫铬铭铮铯铰铱铲铳铴铵银铷铸铹铺铼铽链铿销锁锂锃锄锅锆锇锈锉锊锋锌锍锎锏锐锑锒锓锔锕锖锗锘错锚锛锝锞 +锟锡锢锣锤锥锦锨锩锪锫锬锭键锯锰锱锲锴锵锶锷锸锹锺锻锼锾锿镀镁镂镄镅镆镇镉镊镌镍镎镏镐镑镒镓镔镖镗镘镙镛镜镝镞镟镡镢镣镤镥镦镧镨 +镩镪镫镬镭镯镰镱镲镳镶长门闩闪闫闭问闯闰闱闲闳间闵闶闷闸闹闺闻闼闽闾阀阁阂阃阄阅阆阈阉阊阋阌阍阎阏阐阑阒阔阕阖阗阙阚阜阝队阡阢阪 +阮阱防阳阴阵阶阻阼阽阿陀陂附际陆陇陈陉陋陌降限陔陕陛陟陡院除陧陨险陪陬陲陴陵陶陷隅隆隈隋隍随隐隔隗隘隙障隧隰隳隶隹隼隽难雀雁雄雅 +集雇雉雌雍雎雏雒雕雠雨雩雪雯雳零雷雹雾需霁霄霆震霈霉霍霎霏霓霖霜霞霪霭霰露霸霹霾青靓靖静靛非靠靡面靥革靳靴靶靼鞅鞋鞍鞑鞒鞔鞘鞠鞣 +鞫鞭鞯鞲鞴韦韧韩韪韫韬韭音韵韶页顶顷顸项顺须顼顽顾顿颀颁颂颃预颅领颇颈颉颊颌颍颏颐频颓颔颖颗题颚颛颜额颞颟颠颡颢颤颥颦颧风飑飒飓 +飕飘飙飚飞食飧飨餍餐餮饔饕饣饥饧饨饩饪饫饬饭饮饯饰饱饲饴饵饶饷饺饼饽饿馀馁馄馅馆馇馈馊馋馍馏馐馑馒馓馔馕首馗馘香馥馨马驭驮驯驰驱 +驳驴驵驶驷驸驹驺驻驼驽驾驿骀骁骂骄骅骆骇骈骊骋验骏骐骑骒骓骖骗骘骚骛骜骝骞骟骠骡骢骣骤骥骧骨骰骱骶骷骸骺骼髀髁髂髅髋髌髑髓高髟髡 +髦髫髭髯髹髻鬃鬈鬏鬓鬟鬣鬯鬲鬻鬼魁魂魃魄魅魇魈魉魍魏魑魔鱼鱿鲁鲂鲅鲆鲇鲈鲋鲍鲎鲐鲑鲒鲔鲕鲚鲛鲜鲞鲟鲠鲡鲢鲣鲤鲥鲦鲧鲨鲩鲫鲭鲮鲰鲱 +鲲鲳鲴鲵鲶鲷鲸鲺鲻鲼鲽鳃鳄鳅鳆鳇鳊鳋鳌鳍鳎鳏鳐鳓鳔鳕鳖鳗鳘鳙鳜鳝鳞鳟鳢鸟鸠鸡鸢鸣鸥鸦鸨鸩鸪鸫鸬鸭鸯鸱鸲鸳鸵鸶鸷鸸鸹鸺鸽鸾鸿鹁鹂鹃 +鹄鹅鹆鹇鹈鹉鹊鹋鹌鹎鹏鹑鹕鹗鹘鹚鹛鹜鹞鹣鹤鹦鹧鹨鹩鹪鹫鹬鹭鹰鹱鹳鹾鹿麂麇麈麋麒麓麝麟麦麴麸麻麽麾黄黉黍黎黏黑黔默黛黜黝黟黠黢黥黧 +黩黪黯黹黻黼黾鼋鼍鼎鼐鼓鼗鼙鼠鼢鼬鼯鼷鼹鼻鼽鼾齄齐齑齿龀龃龄龅龆龇龈龉龊龋龌龙龚龛龟龠 diff --git a/tools/pinyin_ranked_chars.txt b/tools/pinyin_ranked_chars.txt new file mode 100644 index 00000000..596e1bf8 --- /dev/null +++ b/tools/pinyin_ranked_chars.txt @@ -0,0 +1,106 @@ +敦湛苴哪洒那蹲差著呼撮番拔奠呵濡邪唬拚啐杓佻啁溥趵挈渫揄方平么族能派旁接卷需税趣哈提伯角揣假踹厂核姐傍佛沾逐柴狠榜扒拆沌削啡咯圳 +屈唔甸斜淖哽踔奇絮肫卑潭勺渴契町隶蛇蚌芍哆蜡逗荼宛槭拂堤陂蓼孱貉鞴湔侉疵薜萆雉眭猗被不且大但家行和说还着体查她度率内于告果混没百 +单朝重土横广参追落般卒跳俊搞撰余蔡侧格苦坏校免招它听彭包抱达划恁泥服除弟忒棍秘衰培育波簇挑盾哏缪溺折省仅句遇巡暴扭措兑呆胆繁喝呐 +寨胜肮愁遁累辨宅摧泛逢概吓搜台池串隋咖摩桃陶喊朴吾浚咋沈仇槌冉龟挎薄堡亢浩芒咪咳呶莎蔽趁丞汶奥栅填惴哇姚伽猎哨射夭啜霍押僮稠涂淡 +皋亘亨宿扮斥滋哩牟梢醒虹眩攘苞潼谷瞑泵祝肋卜棱蔟辟涔狻嗄捷示嗽堋喔趟磺嘿潘舂澹轧訇黾尉掺栝矜嵌麽逡食髟啉碌昧惆喋傀渥挲瘟笮隔鞠叹 +庵敞庶媪脾叱剥氏菩艟濯噢酮抵呷涓摺膊焯橙蹴蕃魄膪滇炔拓泣淫娶豫褚橐咽娩柞捍睃埝洮倜蛤苫朐澶蜚晟棣沮婺捎硐汽鄱笏睢湫拾苑腌漯繇揲揭 +酪擐涑镡砉俾徵蕞茈胍醮拗瀑嘁觳沱迭疴嗑臾茇褶毳箐瓠袷隹覃哧涎隗佝柠咻觖囝跛碣趿獬蝤砝莜慊歙捭掊犴舄枸汁桔吱瞿羡茭鬻粢揞咭硌菀骱嗌 +怫胝鬲噎耆洇硪疋埤圩偈艴伎汩熨搋仡阿把藏造曾长传从最的都而个会其前将身了令明无嗯年若色是他有这之半便份部才种调感可括见卡完六路团 +容以些员转白增地得投杂抗共许强兄缺任弄南呢区庄亲声月塞谁数言英也咱啊乃干吧比草僧超车称窗垂促奏受至儿房古号化解客蓝万女片屯王寻奔 +漂餐察次掉鸟否港合给哼或机件觉刻控卵勒冷某握迫惹信事太占眼由择封撇册尚弹灯典耳痕红狼皇荒己坑跨款眠肉已血扎赚炮怕椎淳司登顿堆活惊 +圣牢乐描母戎思沙术约众排冰攒邓涉洞读恶哦奋吩害找茫昆精足圈狂魁盟耐暖切汤什综注刀丁赶硬杭系夏均穹块位尿穰偌涮吞吴仰骠臧禅颤尺承治 +穿淙蝶吨仿骸艮吭越价青络僚俩游陆露埋幕莫聘脱温呀研跑插葱塔冯嗨溃降咔腔立列末倪匿幸芮召休嫖屏抄绰堪吃喜幢毒底敌跌斗妃夹零模娜枘粘 +券拴斯缩限御昂膀拼搓吵乘离虫涌揍粹怀盖甘娃捆脚景例聊朦冒冥震属野园央致凹伴倍倘挫搭杜逛炕期怜萌童叶胞剽赦盛呈臭助董恍穴喀棵氓猫艿 +捻宁喏挝仔凿爪霸扁蚕囱唇石筒汗舌耗妖祖蕊匡扑剖栓扰透探湍褪亡洋奘叭搬夯拍兔裴市副彀巨潦貌芎燥姓式唆鞋彬虑踩抬踱担詹嗲鼎豚陀乾羹涡 +珩汪援焦旬蟒乜熟耶暧嚓澡刹兹枞醋塌拈匪肺扛咎痪踉撩皿胖映允裳盯澄拖刺桐盹汾纶妞垧枉靡褥跫雀溯壅烟浜槽敕捶楱昔汀钭槁贾灌虾桁缴掘姥 +嘞泷鞔味戕怨乍袍淌酢踢炖捧胳猓既岂箬慝帑苹支歇幼拽拶俸嘲帘斫偬狄奸邢戏壳蛞腊佬疑慎嗖宪磅附憧巛沓佃碟掴沆咬坷蛙硎刳蔓墨帕糁蜕窀琢 +币槟屮晁堵堕介滑捐麇泯囡狃娉售朱尹阻爆肥剿憾忑佴彷盼蛩枯斡巷洽罱脉肭戌阮汕失嗍析湃柏瘥躇疔镦睾聒潢豁喟居浸租獠尥辗砰厦识羧炎札跋 +芭嘬逮愍噶胲戆颈劾匀髁邋磷袤谜毋似隧梭盒枕嗔净畜荃叨峒囤杠伉拘徊湟暇垦烙杉肆耙捌瓿厘盅扶镐革洼皓劲吟适莨侔勤蚺叟蕹钥印埃螃葡蝙膘 +枋歹铤驮髂亥亏溟隘臂抨泊焘侗掀蠖技羸抹唛笤洗予鏖扳弁埔厕喳硫嗒咣茄胶筋隽栗糜苤溲祠翟蜓惰炅瞢蛑渑蚴彦倩鞘邺朊矣嚣蒡移烛呔恫匮甄蜷 +筠忐哐勿檀恂妁昕啄吖俺澳裒蒲掾棰钿甬蒿雇呱柜祭渠懔拎疟荨舍忪呃呗褊簿秤淬耷蹄掇激浅僭馗滂恿蚤陬刨稹卞伧檫嵯戚籴葶蚣骰萑嚯挟嚼龈袜 +俏莘哮殷钯豳溴醛蟠拱肩纤苕蓑饧鑫癌胺瞥缏玢噌忏躔忱郴铛伺甫洚羽迦蠼玟迮胗杷肜脞嘀逄溉苛壑皖荤齐揩咸倭拌唪逞骀蜩燔淦酐莞狡乙蟊舒徙 +袒舔募垠施焉帧觜淑彗攉裢祢荽遗巽贲嵊莉舡蚝蕉遽噱氽跣艾泌郢纛袢咴芦劐獾窖衿漆唼衙曝疹帱逾桧阚赫怙菹咀苓蟆寺蓿愉愠煦棹旰嗟戡勖乇匕 +纥祈坯积楷嬷藐畹幅灬妯戛槛泫桊呒溪葚液荥甾怍抻怛柑蹶皤芩霰歃馇嬗惝眈垌旮稞涣堇泺殁砟樘踅邑溘枝洵疸曷鹘侥缲鲭於庇瞠竺矸圜槿靓鞫瞵 +爿愀悛楂鹄珲浍坶淠胂螅沸菏硅蠃寰喙籍蜻蠡厶泞铊哺垩盍膦墅坳蜾瑗泖幺媵撕柚茧儋馘霾偻巳尢尾柁泔颌哌藿稷俟硝莠孛檐掸碡袼撅貊铅佰呲洁 +婕妗溱夕陟酡芥澉浒脘泅崴吁瀹箸蘖踣茬郝葭颉睫廑檠濂爻唷裨坫铫窒脯旄趑逯峤偕蓁殖侏啻跤凵砌泄甭涪郇哕艽叻帔岈擘氐梏蛸椹跬肷聱膻柙徼 +砬熙窨茁燹蚵昵栖杌湮粥懊柽怵怠睇桅栎吲蕈箢拊垸碱茜殍匙苻宓鄹卤嘏蝎噍糸舳鲅蘧彖瘳茛拮蜒菅箴敫捋稽瘕佼崛酾跞蜱冼崤蚰莩裼氤楮锬棋趄 +媲姣恃嘘梧鲑菽蛆瞀芟莆藉阏唑肢俞犍爝珞撖诘苣黧仂捩蔫祁铣芾躅坻杼蔚悝蝥沂吡昙砩囗螫柢厝砥佚郄馥彡忾芫芴搛迤埯蛾倚沏隰剡澍袂枇芪亟 +圾豸阽屎翮姬篦腱峙叽夂陴郗窬菥喈綮缉嶷咦栩壹暨蹊佗祓秸圻唏濞揖埏阢黝睽煨擗疙蜮髻庳崎脔卟檗芘豉雩唧痦燠噫芋瘵恝屹趼喁仳畸黹蜍菸蕺 +丿彳肄圪嵇眙荑坨腧郅忮毹洫焱萁蜴欹荠丌掎犄爱安办帮报本表别并策产成抽出创吹春此窜存当到等点定丢动断对多诶恩发反非分改刚高根更公构 +怪关光规国好黑很后话黄婚教进经迥就决军开看康考肯空口况困拉来兰郎老类里两龙楼乱论满忙毛们密面庙灭民谬目囊脑嫩你娘您牛农耨虐配票品 +破普情穷求去全却群然让人仍日如润萨三丧扫森山上少社生手书耍双顺送苏算虽孙所唐讨特腾天条铁同头推瓦外文翁我西下想小心修选学亚样要一 +因应用原在赞则贼怎战真正中州抓装准子走组钻尊作八保北必变标宾擦采残仓测岑常陈城丑处船床纯村打代党道电铥东段队摁二法犯放飞风该跟工 +够挂拐归过海汉航何恨候欢回加叫金京窘九君靠克恐寇夸快莱浪雷愣理连量料林领流略伦马买慢贸美门梦米妙蔑敏名难馕闹念酿喷飘贫评婆起千秦 +琼取权确裙染嚷绕热荣柔软瑞闰弱撒散桑嫂杀晒商设时刷帅爽水宋艘素随损谈堂逃疼田停图歪为问嗡物现相笑新性宣训业哟又与云葬早责炸展张镇 +政只周主状自总罪遵做傲邦备崩边斌兵步财苍曹层场潮彻臣程充聪篡寸错带荡第殿顶端蒽罚范费缶夫庚故寡乖官贵滚含毫衡侯乎花环挥魂及间江交 +今炯究据绝刊科恳铿扣垮宽扩赖览朗劳力联疗烈临另留隆鸾掠轮吗卖曼莽每闷蒙勉命谋木男曩恼尼纽浓怒欧盆朋批频凭仆恰钱巧侵球燃壤饶融揉入 +锐赛伞嗓骚筛善收霜朔四松诉酸岁索藤贴庭通退托挖晚望瓮卧五息先向形雄秀须玄雪阳夜影永元曰运再暂脏泽谮赠站章照者阵争知住专桌宗纂嘴坐 +按盎巴班宝笨彪滨病布材惨舱操缠撤沉持冲初川闯锤辍匆凑答待档导德爹冬独短夺额尔凡防废纷奉复敢钢稿各耕功购瓜管孩韩豪恒洪厚护华淮换毁 +昏建讲近酒绢郡烤孔叩哭愧阔啦涞烂楞利脸良辽邻灵刘拢漏律挛锊仑罗妈麦猛迷苗蠛闵拿喃囔挠馁逆袅钮侬奴判篇气遣枪桥窃请秋劝桡认扔蹂睿腮 +叁颡瑟闪伤烧神十首摔闩硕讼速遂笋躺套滕题添帖廷统偷突往闻沃务县象消写兴凶旋薛迅压养爷意营右院砸载簪赃遭掌证壮坠捉纵左案罢拜版背编 +镖补礤彩惭沧漕蹭钗巢辰崇筹炊蠢戳丛辏粗蹿翠挡倒瞪帝店叠订懂豆锻朵俄伐饭访菲凤尬纲狗观鬼衮河轰後患慌惠浑火甲较结尽久具凯砍拷啃库筷 +髋矿坤廓赉拦廊泪塄练亮裂麟笼陋銮沦麻漫盲钔绵闽鸣纳奶攮讷辇嬲捏哝努诺偶爬牌盘佩湓碰偏氕瓶铺葜墙琴清曲泉髯荛仁鞣飒鳃搡啥赏绍深使守 +唰甩孀睡舜耸俗蒜碎隼态坦誊厅痛徒窝武希显像星袖讯牙杨药引拥友语远灾糟憎债斩丈诏振整制终洲撞谆卓资邹攥醉樽座锕暗熬败板棒悲苯蹦遍鬓 +丙裁灿茶尝钞酬喘醇词撺崔忖戴丹谠岛颠抖督缎躲贰翻芳粉丰府嘎岗梗攻沟股刮馆胱癸绲郭寒鸿喉户槐缓晃汇几监蒋界境扃旧举倦胩勘犒课芤胯馈 +喇癞栏琅垒梁淋陵陇搂峦洛矛妹扪孟弥棉秒篾悯铭姆楠瑙拟涅凝脓弩呕抛陪皮骗颇七迁抢悄妾钦邛丘阙苒禳娆忍溶糅卅噻磉穑傻陕稍甚升实授树蟀 +氵瞬烁死诵泰糖餮挺抟湾网蓊侠线响效谢辛胸羞逊严摇音迎勇愿匝宰瓒躁缯诈帐哲珍直忠砖妆缀字踪诹缵撙昨哀岸敖爸贝畚毕辩憋殡菜豺昌晨楚钏 +疮椿辞爨催皴旦宕凳谍冻怼饿迩乏愤冈诰供勾卦冠桂鲧铪骇弘猴胡灰获即架简奖节紧竟救眷菌佧慨坎慷颗崆抠酷蒯窥琨辣籁懒泐擂李粮廖劣琳柳垄 +喽鲁栾抡骂蛮卯梅焖咩缗眸奈疒妮茑孽拧挪庞鹏嫔坡潜瞧擒囚瓤壬蓉汝馓埽涩纱扇述吮颂擞肃飧锁塘铽甜亭途腿玩未细协欣熊绣续悬谑循雅验义银 +优欲源哉甑眨障赵针征指钟馔桩擢紫棕躜鳟佐碍鳌摆绷鳖濒禀捕粲嘈恻虿唱扯尘诚宠础陲赐琮汆袋裆盗锝簦吊窦椴钝饵阀烦妨父缸膏哥耿宫顾褂贯 +犷跪辊锅蘅宏吼忽画踝唤惶货检疆禁冂娟爵铐裉倥哙框奎髡睐滥捞诔恋凉寥鳞胧娄录滦囵逻玛迈瞒帽眉蜜缅瞄穆氖赧蛲廿脲聂忸殴徘泡赔缥萍掐签 +羌怯寝轻趋拳鹊刃绒儒蕤仨毵搔啬煞晌摄审世寿嵩荪胎替萜艇铜吐疃颓臀弯忘委稳习香销薪匈靴询演扬雍犹玉岳驵藻罾仗浙贞舟诸篆锥酌鬃驺绑杯 +锛迸笔博猜糙侪阐偿触怆鹑腠镩脆凼蹬低雕钉栋兜煅碓墩珥筏坊芬峰丐埂贡钩固惯轨磙裹逅幻煌恢诨伙计驾坚匠皆晋纠局侃尻柯箜筘裤脍旷阃剌濑 +篮阆鳓历莲辆霖龄溜聋镂孪裸码邙茂懑冕茗牧鼐铙佞懦鸥啪叛翩瓢器牵跄乔禽銎邱榷熔辱蚋缫衫觞邵申输槊凇薮榫踏汰棠涛眺亠妥碗妄谓纹席辖险 +项孝馨型汹朽序勋延羊腰页议阴庸油预阅咂栽錾灶赜锃斋杖朕郑仲宙赘拙挨坝镑辈坌鞭蹩缤柄璨艚叉蝉掣迟绸舛慈苁蹙磋贷蛋砀垫钓牒叮陡渡簖憝 +鹅垡纺锋肝糕恭苟姑诖桄丨翰薨鲎湖桓谎祸嘉剑姜津静舅鹃恺栲侩逵锟垃崃岚螂磊礼廉咧凛凌瘤咙髅嘛谩硭媒蠓觅沔渺默慕钠蝻硇鲇蹑狞傩藕琶俳 +庖蓬匹谝瞟牝坪浦呛卿筇裘驱犬韧茸乳臊铯擅墒兽怂塑绥狲苔掏梯霆桶娲顽卫吻乡晓芯嗅轩隐佣尤缘悦崽昝枣仄摘瞻涨昭辄诊质浊粽俎祚矮袄谤避 +贬婊瘪摈秉怖睬骖螬谗肠澈赤畴储椽猝鞑诞祷镫癫刁咚铎娥鸸返肪焚福钙杆杲歌弓垢醢旱昊贺糇虎哗慧阍惑记佳减警厥峻龛钪蔻窟狯鲲徕澜榔蕾炼 +谅洌岭珑娈螺劢幔枚湎邈岷墓捺萘猱腻碾嗫咛钕瓯趴匏骈泼锵沁庆茕酋阕纫冗蠕脎瘙珊绱伸剩士瘦束私悚飕粟琐榻肽贪膛萄迢屠佤挽威屋吸霞仙萧 +胁衅岫徐璇遥盈咏圆跃晕趱噪啧窄盏胀遮症肿昼颛灼姿鲰唉鞍斑彼汴飙饼诧谄畅炒砗忡瞅莼璁悴鹾哒黛菪蹈噔簟锭蚪肚厄洱珐舫疯钆竿阁躬诟鼓棺 +虢氦罕壕哄篌互宦辉馄基渐绛郊锦敬揪蠲钧铠瞰糠骷盔悃旯揽锒儡椋缭冽赁玲榴茏篓旅骆熳漭茅煤檬抿暝魔鍪暮柰腩孬伲撵啮甯孥沤蒎乓咆沛疲颦 +乒蔷敲倾瘸妊嵘孺砂殇韶牲师绶铄丝竦馊稣钛坛烫淘粜婷佟煺饨腽旺围雯午袭献享忻刑锈虚喧泶丫易饮赢泳韵闸账兆侦挣衷骤姊腙诅哎黯颁鲍裱傧 +炳黪艹岔搀倡坼惩踌遄蝽龊殂萃锉靼稻磴递凋碇痘赌鄂铒坟缝尕垓尴罡羔骨剐罐崞函濠荷烘骺焕蝗悔济舰僵谨睛疚剧闶眍喾郐眶夔醌铼缆丽敛燎鬣 +廪铃琉窿嵝绿荬馒媚懵眯缈哞衲垴霓黏臬糯讴辔棚嘌姘企谦樯衾顷虬诠稔榕鳋删熵奢绳狩叔淞酥髓嗦鳎滩傥滔涕恬窕秃丸维蚊误悉峡详歆馐崖氧邀 +亦鹰忧雨粤孕糌皂帻砦栈彰罩睁冢皱啭氨疤饱闭匾膑蟾耖衬厨氚磁骢瘁笪殆捣嶝迪貂腚趸咄遏贩匚斐蜂妇尜陔肛割赓笱瑰颃嚎闳堠猾凰徽溷极嫁兼 +浆轿鸠俱诀骏锴筐葵阑啷耒吏链粱埒吝菱栊蝼萝蚂髦眇螟亩驽搦耦葩攀疱胚榀欠晴躯铨悫仞茹铩膳绅史艏搠崧嗾娑蹋炱谭啼凸暾驼婉微舞狭鲜祥猩 +绪渲鳕讶燕痒耀寅樱邕幽昃吒毡璋志咒缒涿咨嗳谙翱笆掰瘢梆碑嘣壁镳髌摒逋怊俦矗徂蹉耽悼戥淀笃愕鲕藩鲂绯氛负赅赣葛鲠巩媾孤鸹诡椁涵泓瘊 +糊桦豢幌绘集健酱娇阶斤竞柩聚镌锎磕诳瘌婪蒗唠镭厉琏晾寮伶浏砻瘘吕缦耄玫虻谧淼珉酩摸镎鲶聍衄锘怄畔呸膨披胼珀谱侨惬芹饪蝾洳霎慑肾甥 +扌殊嗣菘锼夙穗薹摊羰韬忝祧恸唾腕罔危紊幄乌贤箱肖械锌惺庥叙鸭沿鸯依婴踊鱼袁钺舴铡绽漳怔置踵轴孜嗷靶稗瓣甏陛播铲琛撑齿雠茨榱痤瘩岱 +蒂碉酊胨蔸睹砘帆吠忿讽富橄戈绠龚遘估绗荭簧击桨巾径韭距莰恪绔诓揆斓稂涝嫘涟魉撂趔粼绫熘蒌卢锣鳗懋魅锰杪苠睨镍胬脬篷蹁螵鲆歉嫱窍氢 +俅痊衽狨麝笙疏蒴瞍祟獭跆炭搪龆梃彤钍椭惘蜗污惜瞎陷襄杏鸺谖驯鸦颜炀谒衣颖蛹冤崭瘴谪铮止锺骓恣阼蔼鹌鏊豹鼻笾飚邴埠锸怅宸驰璀矬迨滴 +篼妒樊钫诽戤筻缟鞲涫闺撼骅浣讳级缰骄镜臼拒竣剀堀醪黎殓钌躏镏垅耧禄椤螨瑁霉腼喵旎筢耪狍旆犏枰濮妻锖箧擎蚯龋绻荏缛裟劭渗祀螋谡濉挞 +饕惕畋烃捅菟纨魍伍闲湘啸炫哑鞅尧冶医颍酉域渊刖蕴箦渣嶂沼辙蒸职胄珠梓绊褒悖逼镔勃槎婵嫦谌黜辶雌妲玷叼仃氡渎礅舵扼邡狒粪枫付篙搁缑 +倌圭帼悍颢讧狐洹贿夥际稼箭犟借井厩惧鄄珂贶榄崂缧励臁镣躐癃履骡颟弭眄鹋鳘磨睦镊恧烹屁俜骑虔襁翘锲吣罄嚅鲨赡艄婶始署邃闼邰瑭剔酴绾 +魏戊翔囟腥蓄荀涯佯瑶掖莺饔诱樾陨唣樟肇值纣筑镞胙捱桉遨阪雹辫鳔冫晡娼铳瓷褡玳惮堞啶鸫嘟裰幡扉烽苷藁觥篝盥呙酣灏鹤黉鬟隍晦尖豇街荩 +僦锩獗垲轲邝酹奁墚鹩嶙蛉旒鹿杩墁昴寐艨宀牡颞磐锫圃谴磬轫薷缮呻愫鲐螳绦剃殄髫莛堍辋唯龌匣携暄徇岩殃曳姻邮芸鄣钊鹧赈肘淄霭铵粑惫飑 +玻钚昶痴茺笛巅蹀玎峨腓伏槔鸽肱妫蝈嗥壶铧璜恚糨搅杰倔蒈窠圹痨粒遴翎锍虏犸镘艋敉沐猊劈叵弃炝峭嗪鳅觑亻襦煽赊簌燧酞醣鼗屉刎肟悟遐厢 +宵谐忄悻髹婿熏芽掩恙窑益莹慵悠猿龠酝蘸獐蛰斟执舯驻谘骜魃坂狈苄瘭衩馋猖耻傣邸惦耋岽牍讹梵翡葑抚秆郜岣辜鹳邯蕻奂晖颊矫戒襟荆啾橛纩 +暌谰栳檑镰嘹蔺呤鹨屡酶勐縻漠拇怩陧澎譬笸羟樵黥逑蓐讪畲诜视厮嗉谇遢毯镗啕阗瞳鸵芄惟阌雾瑕卸貅恤煊殉娅盐怏谣异胤荧俑佑宇旃蟑祯拯织 +竹镯笫舨鸨钡砭拨姹苌橱绐郸胴蠹跺淝偾酆符绀锆咕鳏埚瀚褐弧遑镬枷谏礓靖阄狷抉捃夼褴铑璃辚绺炉锚蜢麋鲵霈怦粕璞旗镪檎氰楸衢畎溽痧厍眚 +枢饲唢碳逖腆鲦惋违莴稀嫌饷屑陉旭绚宴漾晔荫蝇攸愈蚱嫜赭螽倬辎皑螯灞钣碧煸醭搽潺鬯谶刍鹚啖碘垤耵谔酚沣弗汞觏沽颔斛肓锪急鉴耩绞瑾晶 +灸攫皲愦镧耢蠊檩聆庐雒嵋甍嘧膜苜铌醅啤钋启佥噙颧铷蟮佘蜃势蜀僳桫溻瘫溏悌嗵伟璺巫弦飨霄薰伢厌疡曜痈釉狱垣郧幛蔗诤智诛赀锿廒葆焙窆 +杈阊骋翅锄甙氘缔掂鲷瓞犊垛畈浮擀骼珙掼晷憨薅禾沪徨纪郏荐茳觐鹫蝌铹遛撸倮浼钼坭蟛僻蜣跷锓蕖颥筲娠鼠蔌痰跎琬兀锡狎衔骁荇胥铉汛秧肴 +膺墉宥郓榨仉笊筝纸帚柱渍嫒獒癍煲钸碴觇氅雏埭氮忉癜铞鲽镀哚矾棼砜赋皈焓嚆扈篁秽钬荚践浇缙旌玖珏聩漤羚鎏驴楣礞醚陌仫蹒嘭堑戗诮揿遒 +筌跚滠哂恕觫螗仝韦镶懈擤墟漩浔迓烊腋茵臃铀鸳纭柘臻狰砹弊忭菖杵嫡踮芏剁蘩霏鼢赴疳廾蛊鳇麾继蛟茎赳矩矍岿梨裣泠峁湄谟泮硼丕钷噗丬撬 +赇阒鬈潲猞渖试嘶耥嚏掭鼍蜿慰呜兮黠橡萱蚜蛘吆宜瑛猷谕辕咤谵磔桢旨猪浞籽瑷岙岜龅婢汊廛伥榇裎侈搐刂涤靛缍萼钒榧瀵搿菇鼾瑚蟥诲耠跏键 +截鲸瞌狸鲢瓴骝戮牦镁蘼毪钤憔圊糗诎鄯室戍铴缇砣伪诬牺骧箫泻诩癣琊泱烨伊瀛镛馀爰氲搌蜇植滓鄙鳊徜饬滁糍殚黩蹯篚鲼傅焊阖葫逭癀诙胛艰 +椒劫烬泾菊谲氪篑俚潋棂馏箩莓汨寞襻毗攵乞苘巯蛐辁竖泗坍绨砼豌畏侮媳罅庠潇顼楦氩徉杳椰瘾鹦耘峥绉嘱菝孢蓓弼碥驳羼碜炽樗谛髑噩镄辅坩 +嗝锢蝴锾吉贱礁馑兢桕岢笠楝酃赂茆镅芈沫琵匍黔谯螓謦岖犭砷诗笥鹈茼庹剜胃晤禧腺芗溆醺砑鹞靥夤萦鳙牖轸钲铸诼缁褓敝猹蒇鲳嗤绌椟鹗腹箍 +菡涸惚蕙歼靳迳鬏缂蒉篱囹侣摞铆鹛猕摹攴欺钳犰谂梳郯柝隙硖酰缃蟹曛艳揶艺缨愚恽锗诌株龇鐾镲冁龀蛏弛萏覆毂宄晗诃疾俭届蕨锞喹罹鲮缕幂 +霹蹼愆劬姗矧侍暑驷醍箨烷喂芜枭儇桠衍仪嘤卣裕媛殒鸩秩煮髭碚帛骣笞悱舸刽蚶缳蛔迹笳剪饺竭钅胫噘蝰鲤蔹柃潞猸脒镨鼽祛释赎蛳纬膝舷鲞逍 +揎睚窈蚓疣誉揸榛芝孳勹鹎毙脖铖瘛聃锷鲱镉鸪匦阂季岬缄噤菁驹颏犁闾荦冖氆骞橇癯缌锑渭葙亵镟垭徭铘役萤沅韫哳缜侄籀訾褙枨蹰诋鳄痱咐罟 +庋祜漶卉酵阱锯镢醴氯癖镤锹孰锶钽嘻娴蟓燮碹峋痖阎喑囿渔鼋痄畛址酎贮舶憷箪腐虼煳袈拣儆桷戾蓦鞒钐尸纾汜巍坞淆痃揠雁亿楹莸昀齄脂蛛禚 +眦璧酲魑荻婀肤蛄邗鲩蟪钾皎卺憬钜胪邳璩潸蔬咝沲忤晰榭焰鄞罂狁滞荮锱邶搏亍瘅俘瞽簋琥鸡煎诫赆痉骒漓噜脶茉罴搴鸲鳝饰倏帷捂奚筱盱獯淹 +舀嬴侑郁鸢砧渚嵫啵塍蚩赕骶颚俯铬诂嗬虺寄浃笺炬劂钶俐颅猡凄芡硗姒鹉暹魈勰埙崾翼茔呦虞螈铢痹渤埕缚刿顸鹕荟辑蛱捡詈铝瘰馍鼙荞黢舢鸶 +玺绡鲟晏译鱿舆橼掷瞩秭墀娣苊哿槲隳柬肼雳麓镙蘑褰麴疝抒萎庑檄筵霪滢寓眢伫鸱羝锇斧鳜洄绩獍踞孓痢掳镆歧阡氍驶漱耜苇寤馅缬酗偃堙瘿塬 +稚钵媸觌敷菰缋忌涧铰婧荔滤秣甓缱劁磲谥曙兕薇僖藓楔轺潆浈跸轭芙膈烩饥溅疽莅辂讫芊骟湿澌偎鋈苋枵忆狺璎拄鲻辐崮烀寂痂鹪粳橘沥橹嫫痞 +迄仕塾闱羲俨夷撄浴帜邾耔亳镝腭塥酤岵剂珈饯僬桀刭莒砾悭誓黍浯犀锨奄珧铟蓥喻簸褫觚鹱茴挤蹇狙藜渌蚍箝薯纟妩熄哓嫣鳐茚鼬祗嬖屙阜痼滹 +肌镓翦腈倨俪鹭瘼圮岐掮矢诿蜈嬉蚬邂堰廴蝣蓖饽莪孚轱猢铗弪裾骊貘庀绮逝逶焐岘廨糈禹挚毖箔碲钴冀戬鲛掬砺璐耱仟狮猥跹醑抑娱蛀鹁螭驸牯 +囫锏逦噼琦扦鹜熹痫阉椅铕觯髀傺袱唿鞯飓漉钎蚀姝炜骛砚瑜趾炷鲴醐挢羯澧榈椠娓邬曦籼撷兖毓洙愎踟腑臌戽脊笕讵郦辘砒岍殳迕醯莶榍魇诣屿 +麈菠篪牿冱玑缣醵粝鲈琪摅毅槠畀孵轷謇蚧蛎泸嗜秫玮仵鹇绁谚姨欤妣钹蝠虍睑讦龃嫠舻貔沭帏阋祆躞疫煜炙苎茌釜妓雎纰鳍轼涠淅薤琰蜘礴眵窭 +膂嵬钨筅瀣逸铂缡鸬睥杞怃谊翥鲋裥孑榘娌褛郫拭艉猃妍隅蛭潴舭汲琚噬餍溢榆橥荜蚨讥鹣榉铍蟋鄢懿迂芷嫉疥屦疠栌韪圬翕氙赝贽茱襞趺锔鹂轳 +祺弑猬牾胭驿祉瘃菔棘疖垆豕潍饩疰哔畿硷鲒溧簏柿鼯浠庾咫丶羁蒹卩踽枥氇麒痿皙厣蚁卮黼谫稆淇筮怡驭痔筚氟戟戋呖镥蕲舐洧穸颐栉秕讣楗椐 +碛虱鲔汐郾裔禺匐赍枧犋隈蜥恹谀唳蛴葳谳奕钰鸷蓟毽闫挹聿摭狴赙矶蜊脐蓍沩欷骘铋凫鲣苈葺炻軎舾罨彝淤痣荸锂憩贳烯唁贻妪彘罘踺莳滟桎箅 +跗牮轹萋渝枳滗蝮箕篥亓粞崦绎昱絷黻跻傈綦鲥翊跖呋鲡铈硒鼹胰盂酯绂芑埘屣翌俣帙郛骥鳢鲺觋鹬踯茯悸喱礻矽酽踬幞猁畦饣樨缢轵滏骐禊峪蓠 +葸栀桴笈疬颀鼷讠埴坜蓰竽蜉鹆轾诒饫麸弈腴膣绋瘠镒阈霁桤弋龉稃楫汔鳆乩柒臆圉笄蜞萸阝觊屺饴嵛岌漪觎洎轶窳墼瘗芨刈瘀芰纡翳戢舁齑呓妤 +苡圄虮薏跽怿肀鲫屐旖佶伛瘐殛峄蝓麂嵴熠蓣蒺狳铱羿哜咿鲚剞彐佾痍钇悒殪劓埸圯舣黟癔酏镱衤