From b93645ff43d95cae0be9d56d20373a2529ac8f3a Mon Sep 17 00:00:00 2001 From: Kyuhyun Ko <38392618+airmang@users.noreply.github.com> Date: Tue, 10 Nov 2026 17:38:30 +0900 Subject: [PATCH] fix(packaging): keep every shipped file under 256 KiB (hwpx-plugins #66) The Claude plugin carries the released wheel unpacked, and its directory reads at most 256 KiB of one file. form_fit/_glyph_table.py (454 KiB) and layout/pages.py (325 KiB) passed that, so the plugin's engine has been stuck at 6.8.0 since 2026-10-23. - The glyph tables ship as form_fit/_glyph_table.json.gz (gzip-compressed JSON, 65 KiB), read when hwpx.form_fit._glyph_table is imported. The readable source moves, unchanged, to scripts/glyph_table_source.py (not shipped); scripts/build_glyph_table.py writes the data file from it and tests/test_glyph_table_data.py compares every table value for value. - The lower half of layout/pages.py (constants, the paragraph and table model, the rows of a flowing table) moves, text unchanged, to layout/_page_measure.py. pages.py imports every name it defines and keeps its own imports, so hwpx.layout.pages. resolves as before. - tests/test_distribution_file_sizes.py fails when a file of src/hwpx or of the built wheel reaches 256 KiB and warns past 80% of it. The wheel goes from 206 to 208 files. Advances, widths, line breaks and the page estimates of the 1,214 tracked HWPX files are the same as before. Co-Authored-By: Claude Fable 5.2 --- .gitattributes | 2 + CHANGELOG.md | 6 + CONTRIBUTING.md | 15 + docs/architecture/module-ownership.json | 8 +- pyproject.toml | 3 + scripts/build_glyph_table.py | 117 + scripts/glyph_table_source.py | 12026 +++++++++++++++++++++ src/hwpx/form_fit/_glyph_table.json.gz | Bin 0 -> 66230 bytes src/hwpx/form_fit/_glyph_table.py | 12052 +--------------------- src/hwpx/layout/_page_measure.py | 3009 ++++++ src/hwpx/layout/pages.py | 3012 +----- tests/test_distribution_file_sizes.py | 89 + tests/test_glyph_table_data.py | 58 + tests/test_layout_pages_split.py | 64 + tests/test_product_boundary.py | 4 +- 15 files changed, 15483 insertions(+), 14982 deletions(-) create mode 100644 scripts/build_glyph_table.py create mode 100644 scripts/glyph_table_source.py create mode 100644 src/hwpx/form_fit/_glyph_table.json.gz create mode 100644 src/hwpx/layout/_page_measure.py create mode 100644 tests/test_distribution_file_sizes.py create mode 100644 tests/test_glyph_table_data.py create mode 100644 tests/test_layout_pages_split.py diff --git a/.gitattributes b/.gitattributes index 739bf822..d6f996a5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -14,3 +14,5 @@ # Their bundled copies stay byte-identical to the docs/ originals (scripts/sync_contract_docs.py --check). /src/hwpx/data/contract_docs/recipes-traversal.md text eol=lf /src/hwpx/data/contract_docs/mutation-semantics.md text eol=lf +# Compressed data: never converted. +/src/hwpx/form_fit/_glyph_table.json.gz binary diff --git a/CHANGELOG.md b/CHANGELOG.md index 22b755a6..989d2aba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,12 @@ ### 고침 +- 배포판에 든 파일이 모두 256 KiB 아래로 내려간다. Claude 플러그인은 엔진 배포판을 풀어 싣는데, 플러그인 디렉터리가 파일 + 하나에서 256 KiB까지만 읽어 6.9.0부터 플러그인의 엔진이 6.8.0에 멈춰 있었다(hwpx-plugins #66). FormFit 글리프 + 표(`form_fit/_glyph_table.py`, 454 KiB)는 gzip으로 압축한 JSON 자료 파일 `_glyph_table.json.gz`(65 KiB)로 싣고 + 모듈을 가져올 때 읽는다. 표의 값과 순서는 그대로다. 쪽 수 추정(`layout/pages.py`, 325 KiB)은 아래쪽 절반을 + `layout/_page_measure.py`로 옮겼다. 코드는 한 줄도 바꾸지 않았고 `hwpx.layout.pages`에서 전과 같은 이름을 쓴다. + 배포 파일이 한도에 닿으면 실패하고 80%를 넘으면 경고하는 검사(`tests/test_distribution_file_sizes.py`)를 더했다. - 표 행·열·칸 구조 편집(객체 경로와 `apply_table_ops`)이 쪽을 넘어 나뉜 표의 저장 높이(`hp:sz`)를 그대로 둔다. 한/글은 그런 표에 첫 쪽 조각의 높이만 저장하므로(같은 행의 표가 놓인 자리에 따라 30463·17551·5865로 저장됨) 행 높이 증감을 더할 근거가 없다. 전에는 증감을 그대로 더해, 평가계획 채우기가 13행 표(행 28762, 저장 13222)에서 9행을 지우면 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 746068e5..4a54b970 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -67,3 +67,18 @@ - 점진 변환 범위(현재: `src/hwpx/document.py`, `src/hwpx/oxml/document.py`)는 CI에서 다음 항목으로 검증합니다. - `scripts/check_typing_generics_scope.py`: `List`/`Dict`/`Tuple` 별칭 사용 금지 확인 - `mypy`, `pyright`: 지정된 파일 범위 타입 검사 + +## 배포 파일 크기 + +Claude 플러그인은 릴리스한 wheel을 풀어서 싣고, 플러그인 디렉터리는 파일 하나에서 256 KiB까지만 읽습니다 +(hwpx-plugins `scripts/vendor_claude_engine.py`의 `MAX_FILE_BYTES`). 묶음 전체는 512개 파일까지입니다. + +- `tests/test_distribution_file_sizes.py`는 `src/hwpx`와 빌드한 wheel의 파일이 256 KiB에 닿으면 실패하고, + 80%(약 205 KiB)를 넘으면 경고합니다. 경고가 뜨면 한도에 닿기 전에 나누세요. 파일 수 한도가 있으므로 여러 + 모듈보다 새 모듈 하나로 나누는 편이 낫습니다. +- FormFit 글리프 표는 `scripts/glyph_table_source.py`(읽을 수 있는 Python, 배포하지 않음)에서 고칩니다. 고친 뒤 + `python scripts/build_glyph_table.py`를 돌려 `src/hwpx/form_fit/_glyph_table.json.gz`를 다시 만들고 둘을 함께 + 커밋하세요. `tests/test_glyph_table_data.py`가 두 파일의 표를 값 하나하나 비교합니다. +- 쪽 수 추정은 `layout/pages.py`(공개 이름, 쪽·단 흐름)와 `layout/_page_measure.py`(상수, 문단·표 모델)로 나뉘어 + 있습니다. `_page_measure.py`는 `pages.py`를 참조하지 않고, 거기에 새로 정의한 이름은 `pages.py`의 import + 목록에도 넣습니다(`tests/test_layout_pages_split.py`). diff --git a/docs/architecture/module-ownership.json b/docs/architecture/module-ownership.json index d8aaa4c0..8b8f24dc 100644 --- a/docs/architecture/module-ownership.json +++ b/docs/architecture/module-ownership.json @@ -723,6 +723,12 @@ "approvedBy": "owner-page-estimate-2026-09-29", "rationale": "Experimental page estimate (re-exported from hwpx.experimental): follows each body paragraph onto its page and column from the document alone -- lines from a paragraph's valid layout cache or FormFit line breaking, line and paragraph spacing, page/column breaks and paragraph break rules, equal columns, inline and flowing tables, top-and-bottom objects and footnotes -- and reports anything else as unsupported with a reason. Reads OXML only; writes nothing." }, + { + "path": "src/hwpx/layout/_page_measure.py", + "disposition": "core", + "approvedBy": "owner-audit-fix-2026-11-10 (hwpx-plugins issue 66)", + "rationale": "The lower half of the experimental page estimate, moved out of layout/pages.py unchanged so that no shipped file passes 256 KiB (the most a plugin directory reads of one file): the constants, the paragraph and table model (_Measure, cell rows and lines, object extents) and the rows of a flowing table. Refers to nothing in layout/pages.py, which imports every name it defines and keeps the public names and the flow over pages and columns. Reads OXML only; writes nothing." + }, { "path": "src/hwpx/layout/line_cache.py", "disposition": "core", @@ -739,7 +745,7 @@ "path": "src/hwpx/form_fit/_glyph_table.py", "disposition": "core", "approvedBy": "formfit-glyph-widths", - "rationale": "FormFit glyph widths beyond measure._GLYPHS: per face, the design advance of each glyph of the KS X 1001 symbols, the full-width forms and eight common Unicode blocks, read from the font files, and the face Hancom lays a glyph out from when a face lacks it. Data only; imports nothing." + "rationale": "FormFit glyph widths beyond measure._GLYPHS: per face, the design advance of each glyph of the KS X 1001 symbols, the full-width forms and eight common Unicode blocks, read from the font files, and the face Hancom lays a glyph out from when a face lacks it. Data only: reads the tables from _glyph_table.json.gz beside it (gzip-compressed JSON written by scripts/build_glyph_table.py from the readable scripts/glyph_table_source.py) when imported, so that no shipped file passes 256 KiB; imports only the standard library." }, { "path": "src/hwpx/_trailing_table_text.py", diff --git a/pyproject.toml b/pyproject.toml index cc5d24cf..f41ed5c8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -134,6 +134,9 @@ packages = [ # worse than a longer list. Adding a package here is a deliberate act. [tool.setuptools.package-data] "hwpx" = ["py.typed"] +# FormFit's glyph tables: data, not source, so that no shipped file passes 256 KiB (see +# scripts/build_glyph_table.py and tests/test_distribution_file_sizes.py). +"hwpx.form_fit" = ["_glyph_table.json.gz"] "hwpx.tools" = ["_schemas/*.xsd"] "hwpx.data" = ["Skeleton.hwpx", "contract_docs/*.md"] diff --git a/scripts/build_glyph_table.py b/scripts/build_glyph_table.py new file mode 100644 index 00000000..d18187a4 --- /dev/null +++ b/scripts/build_glyph_table.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: Apache-2.0 +"""Write FormFit's glyph tables as the data file the package ships. + +The tables are kept as readable Python in ``scripts/glyph_table_source.py`` (about 450 KiB and growing), which +does not ship. The package carries them as ``src/hwpx/form_fit/_glyph_table.json.gz`` (gzip-compressed JSON, +about 65 KiB) so that no shipped file passes 256 KiB, the most a Claude plugin directory reads of one file +(hwpx-plugins issue 66). ``hwpx.form_fit._glyph_table`` reads the data file when it is imported. + + python scripts/build_glyph_table.py # after editing the source: rewrite the data file + python scripts/build_glyph_table.py --check # exit 1 when the data file does not hold the source's tables + +The data file is compared by content, not by bytes (zlib builds compress differently), and is rewritten only +when its content differs. ``tests/test_glyph_table_data.py`` compares every table with the source. +""" + +from __future__ import annotations + +import argparse +import gzip +import importlib.util +import json +import pathlib +import sys +from typing import Any + +ROOT = pathlib.Path(__file__).resolve().parent.parent +SOURCE = ROOT / "scripts" / "glyph_table_source.py" +DATA = ROOT / "src" / "hwpx" / "form_fit" / "_glyph_table.json.gz" +SCHEMA = "python-hwpx.glyph-table/v1" +#: The tables, in the order the data file holds them, and the shape of each face's value. +TABLES: dict[str, str] = { + "UNITS_PER_EM": "int", + "FALLBACK": "str", + "VERTICAL_METRICS": "pair", + "LINE_HEIGHTS": "int-by-int", + "HANGUL_ADVANCES": "str-by-int", + "ADVANCES": "str-by-int", + "ITALIC_ADVANCES": "str-by-int", + "BOLD_ITALIC_ADVANCES": "str-by-int", +} + + +def load_source(path: pathlib.Path = SOURCE) -> dict[str, dict[str, Any]]: + """The tables of the source module, by name.""" + + spec = importlib.util.spec_from_file_location("_glyph_table_source", path) + assert spec is not None and spec.loader is not None + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + names = {name for name in vars(module) if name.isupper() and not name.startswith("_")} + if names != set(TABLES): + raise SystemExit(f"{path.name} defines {sorted(names)}; build_glyph_table.TABLES lists {sorted(TABLES)}") + return {name: getattr(module, name) for name in TABLES} + + +def _checked(name: str, kind: str, face: object, value: object) -> Any: + """*value* as the data file holds it, refusing anything the loader would not give back the same.""" + + def fail() -> SystemExit: + return SystemExit(f"{name}[{face!r}] = {value!r:.80} is not {kind}") + + if type(face) is not str: + raise fail() + if kind in ("int", "str"): + if type(value) is not (int if kind == "int" else str): + raise fail() + return value + if kind == "pair": + if type(value) is not tuple or len(value) != 2 or any(type(item) is not int for item in value): + raise fail() + return list(value) + inner = int if kind == "int-by-int" else str + if type(value) is not dict or any(type(k) is not int or type(v) is not inner for k, v in value.items()): + raise fail() + return [[k, v] for k, v in value.items()] + + +def encode(tables: dict[str, dict[str, Any]]) -> bytes: + """The JSON text of *tables*: every table a list of ``[face, value]`` in the source's order.""" + + payload = { + "schema": SCHEMA, + "tables": {name: [[face, _checked(name, kind, face, value)] for face, value in tables[name].items()] + for name, kind in TABLES.items()}, + } + return json.dumps(payload, ensure_ascii=False, separators=(",", ":")).encode("utf-8") + + +def stored(path: pathlib.Path = DATA) -> bytes | None: + """The JSON text the data file holds, or None when it is missing or unreadable.""" + + try: + return gzip.decompress(path.read_bytes()) + except (OSError, EOFError, gzip.BadGzipFile): + return None + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument("--check", action="store_true", help="only compare the data file with the source") + args = parser.parse_args(argv) + text = encode(load_source()) + if stored() == text: + print(f"[OK] {DATA.relative_to(ROOT).as_posix()} holds the source's tables ({DATA.stat().st_size} bytes)") + return 0 + if args.check: + print(f"[FAIL] {DATA.relative_to(ROOT).as_posix()} differs from {SOURCE.relative_to(ROOT).as_posix()}; " + "run python scripts/build_glyph_table.py") + return 1 + DATA.write_bytes(gzip.compress(text, compresslevel=9, mtime=0)) + print(f"[OK] wrote {DATA.relative_to(ROOT).as_posix()} ({DATA.stat().st_size} bytes, {len(text)} of JSON)") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/scripts/glyph_table_source.py b/scripts/glyph_table_source.py new file mode 100644 index 00000000..03aa4c40 --- /dev/null +++ b/scripts/glyph_table_source.py @@ -0,0 +1,12026 @@ +# SPDX-License-Identifier: Apache-2.0 +# Source of the tables hwpx.form_fit._glyph_table loads. Not shipped: after editing, run +# python scripts/build_glyph_table.py +# which writes src/hwpx/form_fit/_glyph_table.json.gz (tests/test_glyph_table_data.py compares the two). +"""Design advances of glyphs beyond ``measure._GLYPHS``, per face, read from the fonts' ``hmtx`` and +``cmap`` tables: the KS X 1001 symbols and full-width forms, and the Latin-1, Latin Extended-A, General +Punctuation, Currency Symbols, Mathematical Operators, Geometric Shapes, Miscellaneous Symbols, Dingbats and +Halfwidth and Fullwidth Forms blocks (Hangul, Hanja and kana left out); for the symbol faces Wingdings and Symbol, the +private-use code points U+F020-F0FF their glyphs are stored at. A face lacking a glyph lays it out at its fallback +face's advance. The table is read from the font files, not written by hand, but for a few glyphs Hancom lays out +at an advance of its own (я in 한컴 고딕, for one), which they carry instead: 함초롬돋움's spacing modifier letters, +general punctuation but the quotation marks and currency symbols take 함초롬바탕's, and 휴먼명조, 휴먼고딕 and +HY헤드라인M carry the advances Hancom Office 2024 lays their glyphs out at where they differ from the font's (the +Greek and Cyrillic letters, and the glyphs they lack). 한컴돋움 carries only the glyphs Hancom Office 2024 lays +out at an advance of its own (the Latin letters and a few others) and takes the rest, its symbols, Greek, Cyrillic +and full-width forms, from 함초롬돋움 as a face lacking them does. 한컴 윤고딕 250 carries the advances Hancom +Office 2024 lays its glyphs out at, as measured, its Cyrillic letters left to its fallback. The Windows Latin faces +(Times New Roman, Arial, Cambria, Constantia, Calibri, Georgia, Verdana, Tahoma, Segoe UI, Consolas and Courier New) +carry the advances Hancom Office 2024 lays their glyphs out at, as measured on the desktop (no font file read): the +Latin-1, Latin Extended-A and Greek letters and common punctuation and symbols, the glyphs they lack at the advance +Hancom gives them all the same; other glyphs in them are left to the class averages. #신명조, 양재백두체B, +양재참숯체B, 한컴 소망 M and B, 한컴 솔잎 M and B and 한컴 윤고딕 740 (in 1000 units per em), and HY동녘B, HY수평선B, +HY태백B, MD이솝체, 궁서 and 태 헤드라인D (in 1024) carry the advances Hancom Office 2024 lays their Latin-1, +Latin Extended-A and Greek letters and common punctuation and symbols out at, as measured on the desktop the same way; +their Hangul syllables are an em, as in a face Hancom replaces with 한컴바탕. The twelve KoPub and KoPubWorld faces +carry, where they differ from the fonts', the advances Hancom Office 2024 lays their glyphs out at, as measured on the +desktop with the fonts installed: the glyphs the fonts lack (∙, ・, kana, Greek and Cyrillic letters among them) at +advances of its own, the same in every KoPub face, and the archaic jamo at nine tenths of the em +(``HANGUL_ADVANCES``). The Greek ano teleia (U+0387), outside the blocks read, carries the advance Hancom Office 2024 lays it out at in each face listed: the +face's own where it has one, else about a sixth of the em. Each text face's ascent and descent are here too, for +the line height of a paragraph that takes it from the font. +""" + +from __future__ import annotations + +#: Units per em of each face below. +UNITS_PER_EM: dict[str, int] = { + "바탕": 1024, + "바탕체": 1024, + "돋움": 1024, + "돋움체": 1024, + "굴림": 1024, + "굴림체": 1024, + "궁서": 1024, + "궁서체": 1024, + "한컴 고딕": 1000, + "함초롬바탕": 1000, + "함초롬돋움": 1000, + "맑은 고딕": 2048, + "Segoe UI Symbol": 2048, + "KoPub돋움체 Light": 1000, + "KoPub돋움체 Medium": 1000, + "KoPub돋움체 Bold": 1000, + "KoPub바탕체 Light": 1000, + "KoPub바탕체 Medium": 1000, + "KoPub바탕체 Bold": 1000, + "KoPubWorld돋움체 Light": 1000, + "KoPubWorld돋움체 Medium": 1000, + "KoPubWorld돋움체 Bold": 1000, + "KoPubWorld바탕체 Light": 1000, + "KoPubWorld바탕체 Medium": 1000, + "KoPubWorld바탕체 Bold": 1000, + "한컴 말랑말랑 Bold": 1000, + "한컴산뜻돋움": 1000, + "휴먼고딕": 1024, + "한컴돋움": 1024, + "HY울릉도M": 1024, + "HY울릉도B": 1024, + "HY중고딕": 1024, + "HY견고딕": 1024, + "HY신명조": 1024, + "HY태백B": 1024, + "HY그래픽": 1024, + "한컴바탕": 1024, + "한컴 윤고딕 230": 1000, + "한컴 윤고딕 240": 1000, + "한컴 윤고딕 250": 1000, + "한컴 윤고딕 720": 1000, + "한컴 윤고딕 760": 1000, + "한컴 윤체 L": 1000, + "한컴 소망 M": 1000, + "한컴 소망 B": 1000, + "한컴 백제 B": 1000, + "한컴 백제 M": 1000, + "한컴 바겐세일 B": 1000, + "한컴 바겐세일 M": 1000, + "새굴림": 1024, + "한컴 말랑말랑 Regular": 1000, + "MD개성체": 1024, + "휴먼명조": 1024, + "HY헤드라인M": 1024, + "Wingdings": 2048, + "Symbol": 2048, + "HY견명조": 1024, + "HY동녘M": 1024, + "HCI Poppy": 1024, + "HCI Hollyhock": 1024, + "한양중고딕": 1000, + "한양신명조": 1000, + "한양견고딕": 4096, + "휴먼옛체": 1024, + "신명 태명조": 2048, + "신명 견고딕": 1000, + "한양그래픽": 2048, + "Times New Roman": 2048, + "Arial": 2048, + "Cambria": 2048, + "Constantia": 2048, + "Calibri": 2048, + "Georgia": 2048, + "Verdana": 2048, + "Tahoma": 2048, + "Segoe UI": 2048, + "Consolas": 2048, + "Courier New": 2048, + "#신명조": 1000, + "양재백두체B": 1000, + "양재참숯체B": 1000, + "한컴 솔잎 M": 1000, + "한컴 솔잎 B": 1000, + "한컴 윤고딕 740": 1000, + "HY동녘B": 1024, + "HY수평선B": 1024, + "MD이솝체": 1024, + "태 헤드라인D": 1024, +} + +#: The face Hancom takes a glyph from when a face does not have it. +FALLBACK: dict[str, str] = { + "바탕": "함초롬바탕", + "궁서": "함초롬바탕", + "바탕체": "함초롬바탕", + "궁서체": "함초롬바탕", + "굴림체": "함초롬바탕", + "돋움체": "함초롬바탕", + "굴림": "함초롬돋움", + "돋움": "함초롬돋움", + "맑은 고딕": "함초롬돋움", + "한컴 고딕": "함초롬돋움", + "함초롬바탕": "Segoe UI Symbol", + "함초롬돋움": "Segoe UI Symbol", + "휴먼명조": "함초롬바탕", + "HY헤드라인M": "함초롬바탕", + "한컴산뜻돋움": "함초롬돋움", + "한컴돋움": "함초롬돋움", + "한컴 윤고딕 250": "함초롬돋움", + "HY중고딕": "함초롬바탕", + "HY견고딕": "함초롬바탕", + "HY신명조": "함초롬바탕", + "새굴림": "함초롬돋움", + "한컴 말랑말랑 Regular": "함초롬바탕", + "HY견명조": "함초롬바탕", + "HY동녘M": "함초롬바탕", + "HY울릉도M": "함초롬바탕", +} + +#: Each text face's ascent and descent (OS/2 usWinAscent, usWinDescent) in its units per em: a paragraph +#: taking its line height from the font (``hh:paraPr@fontLineHeight``) makes its lines that tall. +VERTICAL_METRICS: dict[str, tuple[int, int]] = { + "바탕": (879, 145), + "바탕체": (879, 145), + "궁서": (879, 145), + "궁서체": (879, 145), + "굴림": (879, 145), + "굴림체": (879, 145), + "돋움": (879, 145), + "돋움체": (879, 145), + "한컴 고딕": (1000, 300), + "함초롬바탕": (1070, 230), + "함초롬돋움": (1070, 230), + "맑은 고딕": (2229, 495), + "한컴산뜻돋움": (1000, 300), + "휴먼고딕": (880, 200), + "한컴돋움": (879, 145), + "HY울릉도M": (879, 145), + "HY울릉도B": (879, 145), + "HY중고딕": (879, 145), + "HY견고딕": (879, 145), + "HY신명조": (879, 145), + "HY태백B": (879, 145), + "HY그래픽": (879, 145), + "한컴바탕": (879, 145), + "한컴 윤고딕 230": (1103, 303), + "한컴 윤고딕 240": (1123, 300), + "한컴 윤고딕 720": (943, 253), + "한컴 윤고딕 760": (1039, 267), + "한컴 윤체 L": (1117, 246), + "한컴 소망 M": (1170, 280), + "한컴 소망 B": (1170, 279), + "한컴 백제 B": (1079, 262), + "한컴 백제 M": (1047, 265), + "한컴 바겐세일 B": (1062, 220), + "한컴 바겐세일 M": (1038, 230), + "새굴림": (879, 145), + "한컴 말랑말랑 Regular": (1040, 250), + "한컴 말랑말랑 Bold": (1040, 250), + "MD개성체": (879, 145), + "휴먼명조": (880, 200), + "HY헤드라인M": (879, 145), + "HY견명조": (879, 145), + "HY동녘M": (879, 145), +} + +#: The line heights Hancom Office 2024 lays a line of one face and height out at, in a paragraph taking its line +#: height from the font, where they differ from its ascent and descent each rounded up (measured on the desktop at +#: every 50 HWPUNIT from 500 to 4000, no font file read): height -> line height. Other heights take the formula. +LINE_HEIGHTS: dict[str, dict[int, int]] = { + "한컴 고딕": { + 2600: 3379, 2650: 3444, 2700: 3509, 2750: 3574, 2800: 3639, 2850: 3704, 2900: 3769, 2950: 3834, + 3000: 3899, 3050: 3964, 3100: 4029, 3150: 4094, 3200: 4159, 3250: 4224, 3300: 4289, 3350: 4354, + 3400: 4419, 3450: 4484, 3500: 4549, 3550: 4614, 3600: 4679, 3650: 4744, 3700: 4809, 3750: 4874, + 3800: 4939, 3850: 5004, 3900: 5069, 3950: 5134, 4000: 5199, + }, + "함초롬바탕": { + 1100: 1431, 1200: 1561, 1300: 1691, 1400: 1821, 1500: 1951, 1600: 2082, 1700: 2212, 1800: 2342, + 1900: 2472, 2000: 2602, 2100: 2732, 2150: 2797, 2200: 2862, 2250: 2927, 2300: 2992, 2350: 3057, + 2400: 3122, 2450: 3187, 2500: 3252, 2550: 3317, 2600: 3382, 2650: 3447, 2700: 3512, 2750: 3577, + 2800: 3642, 2850: 3707, 2900: 3772, 2950: 3837, 3000: 3902, 3050: 3967, 3100: 4032, 3150: 4097, + 3200: 4163, 3250: 4228, 3300: 4293, 3350: 4358, 3400: 4423, 3450: 4488, 3500: 4553, 3550: 4618, + 3600: 4683, 3650: 4748, 3700: 4813, 3750: 4878, 3800: 4943, 3850: 5008, 3900: 5073, 3950: 5138, + 4000: 5203, + }, + "함초롬돋움": { + 1100: 1431, 1200: 1561, 1300: 1691, 1400: 1821, 1500: 1951, 1600: 2082, 1700: 2212, 1800: 2342, + 1900: 2472, 2000: 2602, 2100: 2732, 2150: 2797, 2200: 2862, 2250: 2927, 2300: 2992, 2350: 3057, + 2400: 3122, 2450: 3187, 2500: 3252, 2550: 3317, 2600: 3382, 2650: 3447, 2700: 3512, 2750: 3577, + 2800: 3642, 2850: 3707, 2900: 3772, 2950: 3837, 3000: 3902, 3050: 3967, 3100: 4032, 3150: 4097, + 3200: 4163, 3250: 4228, 3300: 4293, 3350: 4358, 3400: 4423, 3450: 4488, 3500: 4553, 3550: 4618, + 3600: 4683, 3650: 4748, 3700: 4813, 3750: 4878, 3800: 4943, 3850: 5008, 3900: 5073, 3950: 5138, + 4000: 5203, + }, + "맑은 고딕": { + 500: 665, 600: 798, 650: 865, 1150: 1531, 1300: 1731, 1550: 2063, 1600: 2130, 1650: 2197, + 1700: 2263, 1750: 2330, 1900: 2529, 2000: 2662, 2100: 2796, 2150: 2862, 2200: 2929, 2250: 2995, + 2300: 3061, 2350: 3128, 2450: 3261, 2500: 3327, 2550: 3395, 2600: 3461, 2650: 3527, 2700: 3594, + 2750: 3660, 2800: 3727, 2850: 3793, 2900: 3860, 2950: 3926, 3000: 3994, 3050: 4060, 3100: 4126, + 3150: 4193, 3200: 4259, 3250: 4326, 3300: 4392, 3350: 4459, 3400: 4525, 3450: 4593, 3500: 4659, + 3550: 4725, 3600: 4792, 3650: 4858, 3700: 4925, 3750: 4991, 3800: 5058, 3850: 5124, 3900: 5192, + 3950: 5258, 4000: 5324, + }, + "한컴산뜻돋움": { + 2600: 3379, 2650: 3444, 2700: 3509, 2750: 3574, 2800: 3639, 2850: 3704, 2900: 3769, 2950: 3834, + 3000: 3899, 3050: 3964, 3100: 4029, 3150: 4094, 3200: 4159, 3250: 4224, 3300: 4289, 3350: 4354, + 3400: 4419, 3450: 4484, 3500: 4549, 3550: 4614, 3600: 4679, 3650: 4744, 3700: 4809, 3750: 4874, + 3800: 4939, 3850: 5004, 3900: 5069, 3950: 5134, 4000: 5199, + }, + "휴먼고딕": { + 550: 580, 600: 633, 750: 791, 800: 844, 850: 896, 900: 949, 950: 1002, 1000: 1054, + 1050: 1107, 1100: 1160, 1150: 1213, 1200: 1265, 1250: 1318, 1300: 1371, 1350: 1424, 1400: 1476, + 1450: 1529, 1500: 1582, 1550: 1635, 1650: 1740, 1700: 1793, 1850: 1951, 1900: 2004, 2050: 2162, + 2100: 2215, 2250: 2373, 2300: 2426, 2450: 2584, 2500: 2636, 2550: 2689, 2600: 2742, 2650: 2795, + 2700: 2847, 2750: 2900, 2800: 2953, 2850: 3006, 2900: 3058, 2950: 3111, 3000: 3164, 3050: 3217, + 3100: 3269, 3150: 3322, 3350: 3533, 3400: 3586, 3550: 3744, 3600: 3797, 3750: 3955, 3800: 4008, + 3950: 4166, 4000: 4219, + }, + "한컴 윤고딕 230": { + 500: 702, 550: 773, 700: 984, 750: 1054, 800: 1124, 850: 1194, 900: 1264, 950: 1335, + 1050: 1476, 1100: 1546, 1150: 1616, 1200: 1686, 1250: 1756, 1300: 1827, 1350: 1897, 1400: 1968, + 1450: 2038, 1500: 2108, 1550: 2178, 1600: 2248, 1650: 2319, 1700: 2389, 1750: 2459, 1800: 2530, + 1850: 2600, 1900: 2670, 1950: 2740, 2000: 2810, 2050: 2881, 2100: 2951, 2150: 3021, 2200: 3092, + 2250: 3162, 2300: 3232, 2350: 3302, 2400: 3373, 2450: 3443, 2500: 3513, 2550: 3583, 2600: 3654, + 2650: 3724, 2700: 3794, 2750: 3865, 2800: 3935, 2850: 4005, 2900: 4075, 2950: 4145, 3000: 4216, + 3050: 4286, 3100: 4356, 3150: 4427, 3200: 4497, 3250: 4567, 3300: 4637, 3350: 4708, 3400: 4778, + 3450: 4848, 3500: 4919, 3550: 4989, 3600: 5059, 3650: 5129, 3700: 5199, 3750: 5270, 3800: 5340, + 3850: 5411, 3900: 5481, 3950: 5551, 4000: 5621, + }, + "한컴 윤고딕 240": { + 700: 996, 750: 1067, 800: 1138, 1050: 1494, 1100: 1565, 1350: 1921, 1400: 1992, 1450: 2063, + 1700: 2419, 1750: 2490, 1800: 2561, 2050: 2917, 2100: 2988, 2350: 3344, 2400: 3415, 2450: 3486, + 2600: 3699, 2650: 3770, 2700: 3841, 2750: 3912, 2800: 3984, 2850: 4055, 2900: 4126, 2950: 4197, + 3000: 4268, 3050: 4339, 3100: 4410, 3150: 4482, 3200: 4553, 3250: 4624, 3300: 4695, 3350: 4766, + 3400: 4837, 3450: 4909, 3500: 4980, 3550: 5051, 3600: 5122, 3650: 5193, 3700: 5264, 3750: 5335, + 3800: 5407, 3850: 5478, 3900: 5549, 3950: 5620, 4000: 5691, + }, + "한컴 윤고딕 720": { + 500: 598, 550: 658, 650: 777, 700: 837, 800: 957, 850: 1017, 950: 1136, 1100: 1316, + 1250: 1495, 1350: 1615, 1400: 1675, 1500: 1794, 1550: 1854, 1700: 2034, 1800: 2153, 1850: 2213, + 2000: 2393, 2100: 2512, 2200: 2631, 2300: 2752, 2350: 2811, 2400: 2871, 2500: 2990, 2600: 3111, + 2700: 3230, 2800: 3349, 3000: 3589, 3050: 3648, 3100: 3708, 3150: 3769, 3300: 3948, 3350: 4007, + 3400: 4067, 3450: 4128, 3600: 4307, 3700: 4426, 4000: 4785, + }, + "한컴 윤고딕 760": { + 500: 653, 550: 718, 600: 783, 650: 848, 700: 914, 750: 979, 800: 1044, 850: 1110, + 900: 1175, 950: 1240, 1050: 1371, 1100: 1436, 1150: 1502, 1200: 1567, 1250: 1632, 1300: 1698, + 1350: 1763, 1400: 1828, 1450: 1894, 1500: 1959, 1550: 2024, 1600: 2090, 1650: 2154, 1700: 2219, + 1750: 2285, 1800: 2350, 1850: 2415, 1900: 2481, 1950: 2546, 2000: 2611, 2050: 2677, 2100: 2742, + 2150: 2807, 2200: 2873, 2250: 2938, 2300: 3003, 2350: 3069, 2400: 3134, 2450: 3199, 2500: 3265, + 2550: 3330, 2600: 3395, 2650: 3460, 2700: 3525, 2750: 3590, 2800: 3655, 2850: 3721, 2900: 3786, + 2950: 3851, 3000: 3917, 3050: 3982, 3100: 4047, 3150: 4113, 3200: 4178, 3250: 4243, 3300: 4309, + 3350: 4374, 3400: 4439, 3450: 4505, 3500: 4570, 3550: 4635, 3600: 4701, 3650: 4766, 3700: 4831, + 3750: 4896, 3800: 4961, 3850: 5026, 3900: 5092, 3950: 5157, 4000: 5222, + }, + "한컴 윤체 L": { + 550: 749, 600: 818, 650: 886, 700: 954, 850: 1159, 900: 1226, 950: 1295, 1050: 1431, + 1200: 1636, 1250: 1704, 1300: 1772, 1350: 1840, 1550: 2113, 1650: 2249, 1700: 2317, 1850: 2522, + 2050: 2794, 2200: 2999, 2350: 3203, 2700: 3680, 2850: 3885, 3000: 4090, 3700: 5045, 3850: 5248, + 4000: 5453, + }, + "한컴 소망 M": { + 550: 797, 650: 942, 750: 1087, 850: 1232, 950: 1377, 1050: 1522, 1150: 1667, 1250: 1812, + 1350: 1957, 1450: 2102, 1550: 2247, 1650: 2392, 1750: 2537, 1900: 2756, 2000: 2901, 2100: 3046, + 2200: 3191, 2300: 3336, 2400: 3481, 2500: 3626, 2600: 3771, 2700: 3916, 2800: 4061, 2900: 4206, + 3000: 4351, 3100: 4496, 3200: 4641, 3300: 4786, 3400: 4931, 3500: 5076, 3600: 5221, 3700: 5366, + 3800: 5511, 3900: 5656, 4000: 5801, + }, + "한컴 소망 B": { + 550: 797, 650: 942, 750: 1086, 800: 1159, 850: 1231, 900: 1304, 950: 1376, 1050: 1521, + 1150: 1666, 1250: 1811, 1350: 1956, 1450: 2101, 1550: 2246, 1650: 2391, 1750: 2536, 1850: 2681, + 1950: 2826, 2000: 2899, 2100: 3044, 2150: 3115, 2250: 3260, 2350: 3405, 2450: 3550, 2550: 3695, + 2650: 3840, 2750: 3985, 2850: 4130, 2950: 4275, 3000: 4348, 3100: 4493, 3200: 4638, 3300: 4783, + 3400: 4928, 3500: 5073, 3650: 5289, 3750: 5434, 3850: 5579, 3950: 5724, 4000: 5797, + }, + "한컴 백제 B": { + 550: 738, 600: 804, 650: 871, 700: 938, 750: 1005, 800: 1072, 850: 1139, 900: 1207, + 950: 1274, 1050: 1408, 1100: 1475, 1150: 1542, 1200: 1609, 1250: 1676, 1300: 1743, 1350: 1810, + 1400: 1877, 1450: 1944, 1550: 2079, 1600: 2146, 1650: 2213, 1700: 2279, 1750: 2346, 1800: 2413, + 1850: 2480, 1900: 2547, 1950: 2614, 2000: 2681, 2050: 2749, 2100: 2816, 2150: 2883, 2200: 2950, + 2250: 3017, 2300: 3084, 2350: 3151, 2400: 3218, 2450: 3285, 2500: 3352, 2550: 3419, 2600: 3486, + 2650: 3554, 2700: 3621, 2750: 3688, 2800: 3754, 2850: 3821, 2900: 3888, 2950: 3955, 3000: 4022, + 3050: 4089, 3100: 4156, 3150: 4223, 3200: 4291, 3250: 4358, 3300: 4425, 3350: 4492, 3400: 4559, + 3450: 4626, 3500: 4693, 3550: 4760, 3600: 4827, 3650: 4894, 3700: 4961, 3750: 5028, 3800: 5096, + 3850: 5163, 3900: 5229, 3950: 5296, 4000: 5363, + }, + "한컴 백제 M": { + 500: 655, 600: 787, 650: 852, 700: 918, 750: 983, 850: 1115, 900: 1180, 950: 1246, + 1050: 1377, 1100: 1443, 1150: 1508, 1200: 1574, 1250: 1640, 1300: 1705, 1350: 1770, 1450: 1902, + 1500: 1967, 1550: 2033, 1600: 2098, 1650: 2164, 1700: 2230, 1750: 2295, 1800: 2360, 1850: 2427, + 1900: 2492, 1950: 2557, 2000: 2623, 2050: 2689, 2100: 2754, 2150: 2820, 2200: 2885, 2250: 2950, + 2300: 3017, 2350: 3082, 2400: 3148, 2450: 3213, 2500: 3279, 2550: 3345, 2600: 3410, 2650: 3475, + 2700: 3542, 2750: 3607, 2800: 3672, 2850: 3738, 2900: 3803, 2950: 3869, 3000: 3935, 3050: 4000, + 3100: 4065, 3150: 4132, 3200: 4197, 3250: 4262, 3300: 4328, 3350: 4394, 3400: 4459, 3450: 4525, + 3500: 4590, 3550: 4656, 3600: 4722, 3650: 4787, 3700: 4852, 3750: 4918, 3800: 4984, 3850: 5049, + 3900: 5115, 3950: 5180, 4000: 5247, + }, + "한컴 바겐세일 B": { + 550: 705, 600: 769, 650: 833, 700: 897, 750: 961, 800: 1025, 850: 1089, 900: 1153, + 950: 1217, 1050: 1346, 1100: 1410, 1150: 1474, 1200: 1538, 1250: 1602, 1300: 1666, 1350: 1730, + 1400: 1794, 1450: 1858, 1500: 1922, 1550: 1986, 1600: 2050, 1650: 2115, 1700: 2179, 1750: 2243, + 1800: 2307, 1850: 2370, 1900: 2434, 1950: 2498, 2000: 2562, 2050: 2626, 2100: 2690, 2150: 2754, + 2200: 2818, 2250: 2882, 2300: 2947, 2350: 3011, 2400: 3075, 2450: 3139, 2500: 3203, 2550: 3267, + 2600: 3331, 2650: 3395, 2700: 3459, 2750: 3523, 2800: 3587, 2850: 3651, 2900: 3715, 2950: 3779, + 3000: 3844, 3050: 3908, 3100: 3972, 3150: 4036, 3200: 4100, 3250: 4164, 3300: 4228, 3350: 4292, + 3400: 4356, 3450: 4420, 3500: 4484, 3550: 4548, 3600: 4612, 3650: 4677, 3700: 4741, 3750: 4805, + 3800: 4869, 3850: 4933, 3900: 4997, 3950: 5061, 4000: 5125, + }, + "한컴 바겐세일 M": { + 800: 1014, 850: 1078, 900: 1141, 950: 1205, 1100: 1396, 1200: 1523, 1300: 1650, 1350: 1712, + 1450: 1839, 1500: 1903, 1600: 2030, 1700: 2157, 1800: 2284, 1850: 2346, 1950: 2473, 2000: 2537, + 2100: 2664, 2150: 2728, 2200: 2791, 2250: 2855, 2300: 2918, 2350: 2982, 2500: 3171, 2550: 3235, + 2600: 3298, 2650: 3362, 2700: 3425, 2750: 3489, 2800: 3552, 2850: 3616, 3000: 3805, 3050: 3869, + 3100: 3932, 3150: 3996, 3200: 4060, 3250: 4123, 3300: 4187, 3350: 4250, 3400: 4313, 3500: 4440, + 3550: 4503, 3600: 4567, 3650: 4630, 3700: 4694, 3750: 4757, 3800: 4821, 3850: 4884, 3900: 4948, + 4000: 5074, + }, + "휴먼명조": { + 550: 580, 600: 633, 750: 791, 800: 844, 850: 896, 900: 949, 950: 1002, 1000: 1054, + 1050: 1107, 1100: 1160, 1150: 1213, 1200: 1265, 1250: 1318, 1300: 1371, 1350: 1424, 1400: 1476, + 1450: 1529, 1500: 1582, 1550: 1635, 1650: 1740, 1700: 1793, 1850: 1951, 1900: 2004, 2050: 2162, + 2100: 2215, 2250: 2373, 2300: 2426, 2450: 2584, 2500: 2636, 2550: 2689, 2600: 2742, 2650: 2795, + 2700: 2847, 2750: 2900, 2800: 2953, 2850: 3006, 2900: 3058, 2950: 3111, 3000: 3164, 3050: 3217, + 3100: 3269, 3150: 3322, 3350: 3533, 3400: 3586, 3550: 3744, 3600: 3797, 3750: 3955, 3800: 4008, + 3950: 4166, 4000: 4219, + }, +} + +#: Per face, the Hangul syllables whose design advance differs from the face's other syllables +#: (``measure._DESIGN``): design advance -> those syllables. +HANGUL_ADVANCES: dict[str, dict[int, str]] = { + "한컴 윤고딕 720": { + 874: "땡", + 879: "꾸땍", + 881: "땝", + }, + "한컴 소망 M": { + 990: "뒹뜅륑튕홴", + 1010: "떡", + }, + "한컴 말랑말랑 Regular": { + 820: ( + "고곡곢곣곤곥곦곧골곩곪곫곬곭곮곯곰곱곲곳곴공곶곷곸곹곺곻교굑굒굓굔굕굖굗굘굙굚굛굜굝굞굟굠굡굢굣굤굥" + "굦굧굨굩굪굫구국굮굯군굱굲굳굴굵굶굷굸굹굺굻굼굽굾굿궀궁궂궃궄궅궆궇규귝귞귟균귡귢귣귤귥귦귧귨귩귪귫" + "귬귭귮귯귰귱귲귳귴귵귶귷그극귺귻근귽귾귿글긁긂긃긄긅긆긇금급긊긋긌긍긎긏긐긑긒긓꼬꼭꼮꼯꼰꼱꼲꼳꼴꼵" + "꼶꼷꼸꼹꼺꼻꼼꼽꼾꼿꽀꽁꽂꽃꽄꽅꽆꽇꾜꾝꾞꾟꾠꾡꾢꾣꾤꾥꾦꾧꾨꾩꾪꾫꾬꾭꾮꾯꾰꾱꾲꾳꾴꾵꾶꾷꾸꾹꾺꾻" + "꾼꾽꾾꾿꿀꿁꿂꿃꿄꿅꿆꿇꿈꿉꿊꿋꿌꿍꿎꿏꿐꿑꿒꿓뀨뀩뀪뀫뀬뀭뀮뀯뀰뀱뀲뀳뀴뀵뀶뀷뀸뀹뀺뀻뀼뀽뀾뀿끀끁" + "끂끃끄끅끆끇끈끉끊끋끌끍끎끏끐끑끒끓끔끕끖끗끘끙끚끛끜끝끞끟노녹녺녻논녽녾녿놀놁놂놃놄놅놆놇놈놉놊놋" + "놌농놎놏놐놑높놓뇨뇩뇪뇫뇬뇭뇮뇯뇰뇱뇲뇳뇴뇵뇶뇷뇸뇹뇺뇻뇼뇽뇾뇿눀눁눂눃누눅눆눇눈눉눊눋눌눍눎눏눐눑" + "눒눓눔눕눖눗눘눙눚눛눜눝눞눟뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄늅늆늇늈늉늊늋늌늍늎늏느늑늒늓는늕늖늗" + "늘늙늚늛늜늝늞늟늠늡늢늣늤능늦늧늨늩늪늫도독돆돇돈돉돊돋돌돍돎돏돐돑돒돓돔돕돖돗돘동돚돛돜돝돞돟됴됵" + "됶됷됸됹됺됻됼됽됾됿둀둁둂둃둄둅둆둇둈둉둊둋둌둍둎둏두둑둒둓둔둕둖둗둘둙둚둛둜둝둞둟둠둡둢둣둤둥둦둧" + "둨둩둪둫듀듁듂듃듄듅듆듇듈듉듊듋듌듍듎듏듐듑듒듓듔듕듖듗듘듙듚듛드득듞듟든듡듢듣들듥듦듧듨듩듪듫듬듭" + "듮듯듰등듲듳듴듵듶듷또똑똒똓똔똕똖똗똘똙똚똛똜똝똞똟똠똡똢똣똤똥똦똧똨똩똪똫뚀뚁뚂뚃뚄뚅뚆뚇뚈뚉뚊뚋" + "뚌뚍뚎뚏뚐뚑뚒뚓뚔뚕뚖뚗뚘뚙뚚뚛뚜뚝뚞뚟뚠뚡뚢뚣뚤뚥뚦뚧뚨뚩뚪뚫뚬뚭뚮뚯뚰뚱뚲뚳뚴뚵뚶뚷뜌뜍뜎뜏뜐뜑" + "뜒뜓뜔뜕뜖뜗뜘뜙뜚뜛뜜뜝뜞뜟뜠뜡뜢뜣뜤뜥뜦뜧뜨뜩뜪뜫뜬뜭뜮뜯뜰뜱뜲뜳뜴뜵뜶뜷뜸뜹뜺뜻뜼뜽뜾뜿띀띁띂띃" + "로록롞롟론롡롢롣롤롥롦롧롨롩롪롫롬롭롮롯롰롱롲롳롴롵롶롷료룍룎룏룐룑룒룓룔룕룖룗룘룙룚룛룜룝룞룟룠룡" + "룢룣룤룥룦룧루룩룪룫룬룭룮룯룰룱룲룳룴룵룶룷룸룹룺룻룼룽룾룿뤀뤁뤂뤃류륙륚륛륜륝륞륟률륡륢륣륤륥륦륧" + "륨륩륪륫륬륭륮륯륰륱륲륳르륵륶륷른륹륺륻를륽륾륿릀릁릂릃름릅릆릇릈릉릊릋릌릍릎릏모목몪몫몬몭몮몯몰몱" + "몲몳몴몵몶몷몸몹몺못몼몽몾몿뫀뫁뫂뫃묘묙묚묛묜묝묞묟묠묡묢묣묤묥묦묧묨묩묪묫묬묭묮묯묰묱묲묳무묵묶묷" + "문묹묺묻물묽묾묿뭀뭁뭂뭃뭄뭅뭆뭇뭈뭉뭊뭋뭌뭍뭎뭏뮤뮥뮦뮧뮨뮩뮪뮫뮬뮭뮮뮯뮰뮱뮲뮳뮴뮵뮶뮷뮸뮹뮺뮻뮼뮽" + "뮾뮿므믁믂믃믄믅믆믇믈믉믊믋믌믍믎믏믐믑믒믓믔믕믖믗믘믙믚믛보복볶볷본볹볺볻볼볽볾볿봀봁봂봃봄봅봆봇" + "봈봉봊봋봌봍봎봏뵤뵥뵦뵧뵨뵩뵪뵫뵬뵭뵮뵯뵰뵱뵲뵳뵴뵵뵶뵷뵸뵹뵺뵻뵼뵽뵾뵿부북붂붃분붅붆붇불붉붊붋붌붍" + "붎붏붐붑붒붓붔붕붖붗붘붙붚붛뷰뷱뷲뷳뷴뷵뷶뷷뷸뷹뷺뷻뷼뷽뷾뷿븀븁븂븃븄븅븆븇븈븉븊븋브븍븎븏븐븑븒븓" + "블븕븖븗븘븙븚븛븜븝븞븟븠븡븢븣븤븥븦븧뽀뽁뽂뽃뽄뽅뽆뽇뽈뽉뽊뽋뽌뽍뽎뽏뽐뽑뽒뽓뽔뽕뽖뽗뽘뽙뽚뽛뾰뾱" + "뾲뾳뾴뾵뾶뾷뾸뾹뾺뾻뾼뾽뾾뾿뿀뿁뿂뿃뿄뿅뿆뿇뿈뿉뿊뿋뿌뿍뿎뿏뿐뿑뿒뿓뿔뿕뿖뿗뿘뿙뿚뿛뿜뿝뿞뿟뿠뿡뿢뿣" + "뿤뿥뿦뿧쀼쀽쀾쀿쁀쁁쁂쁃쁄쁅쁆쁇쁈쁉쁊쁋쁌쁍쁎쁏쁐쁑쁒쁓쁔쁕쁖쁗쁘쁙쁚쁛쁜쁝쁞쁟쁠쁡쁢쁣쁤쁥쁦쁧쁨쁩" + "쁪쁫쁬쁭쁮쁯쁰쁱쁲쁳소속솎솏손솑솒솓솔솕솖솗솘솙솚솛솜솝솞솟솠송솢솣솤솥솦솧쇼쇽쇾쇿숀숁숂숃숄숅숆숇" + "숈숉숊숋숌숍숎숏숐숑숒숓숔숕숖숗수숙숚숛순숝숞숟술숡숢숣숤숥숦숧숨숩숪숫숬숭숮숯숰숱숲숳슈슉슊슋슌슍" + "슎슏슐슑슒슓슔슕슖슗슘슙슚슛슜슝슞슟슠슡슢슣스슥슦슧슨슩슪슫슬슭슮슯슰슱슲슳슴습슶슷슸승슺슻슼슽슾슿" + "쏘쏙쏚쏛쏜쏝쏞쏟쏠쏡쏢쏣쏤쏥쏦쏧쏨쏩쏪쏫쏬쏭쏮쏯쏰쏱쏲쏳쑈쑉쑊쑋쑌쑍쑎쑏쑐쑑쑒쑓쑔쑕쑖쑗쑘쑙쑚쑛쑜쑝" + "쑞쑟쑠쑡쑢쑣쑤쑥쑦쑧쑨쑩쑪쑫쑬쑭쑮쑯쑰쑱쑲쑳쑴쑵쑶쑷쑸쑹쑺쑻쑼쑽쑾쑿쓔쓕쓖쓗쓘쓙쓚쓛쓜쓝쓞쓟쓠쓡쓢쓣" + "쓤쓥쓦쓧쓨쓩쓪쓫쓬쓭쓮쓯쓰쓱쓲쓳쓴쓵쓶쓷쓸쓹쓺쓻쓼쓽쓾쓿씀씁씂씃씄씅씆씇씈씉씊씋오옥옦옧온옩옪옫올옭" + "옮옯옰옱옲옳옴옵옶옷옸옹옺옻옼옽옾옿요욕욖욗욘욙욚욛욜욝욞욟욠욡욢욣욤욥욦욧욨용욪욫욬욭욮욯우욱욲욳" + "운욵욶욷울욹욺욻욼욽욾욿움웁웂웃웄웅웆웇웈웉웊웋유육윢윣윤윥윦윧율윩윪윫윬윭윮윯윰윱윲윳윴융윶윷윸윹" + "윺윻으윽윾윿은읁읂읃을읅읆읇읈읉읊읋음읍읎읏읐응읒읓읔읕읖읗조족졲졳존졵졶졷졸졹졺졻졼졽졾졿좀좁좂좃" + "좄종좆좇좈좉좊좋죠죡죢죣죤죥죦죧죨죩죪죫죬죭죮죯죰죱죲죳죴죵죶죷죸죹죺죻주죽죾죿준줁줂줃줄줅줆줇줈줉" + "줊줋줌줍줎줏줐중줒줓줔줕줖줗쥬쥭쥮쥯쥰쥱쥲쥳쥴쥵쥶쥷쥸쥹쥺쥻쥼쥽쥾쥿즀즁즂즃즄즅즆즇즈즉즊즋즌즍즎즏" + "즐즑즒즓즔즕즖즗즘즙즚즛즜증즞즟즠즡즢즣쪼쪽쪾쪿쫀쫁쫂쫃쫄쫅쫆쫇쫈쫉쫊쫋쫌쫍쫎쫏쫐쫑쫒쫓쫔쫕쫖쫗쬬쬭" + "쬮쬯쬰쬱쬲쬳쬴쬵쬶쬷쬸쬹쬺쬻쬼쬽쬾쬿쭀쭁쭂쭃쭄쭅쭆쭇쭈쭉쭊쭋쭌쭍쭎쭏쭐쭑쭒쭓쭔쭕쭖쭗쭘쭙쭚쭛쭜쭝쭞쭟" + "쭠쭡쭢쭣쮸쮹쮺쮻쮼쮽쮾쮿쯀쯁쯂쯃쯄쯅쯆쯇쯈쯉쯊쯋쯌쯍쯎쯏쯐쯑쯒쯓쯔쯕쯖쯗쯘쯙쯚쯛쯜쯝쯞쯟쯠쯡쯢쯣쯤쯥" + "쯦쯧쯨쯩쯪쯫쯬쯭쯮쯯초촉촊촋촌촍촎촏촐촑촒촓촔촕촖촗촘촙촚촛촜총촞촟촠촡촢촣쵸쵹쵺쵻쵼쵽쵾쵿춀춁춂춃" + "춄춅춆춇춈춉춊춋춌춍춎춏춐춑춒춓추축춖춗춘춙춚춛출춝춞춟춠춡춢춣춤춥춦춧춨충춪춫춬춭춮춯츄츅츆츇츈츉" + "츊츋츌츍츎츏츐츑츒츓츔츕츖츗츘츙츚츛츜츝츞츟츠측츢츣츤츥츦츧츨츩츪츫츬츭츮츯츰츱츲츳츴층츶츷츸츹츺츻" + "코콕콖콗콘콙콚콛콜콝콞콟콠콡콢콣콤콥콦콧콨콩콪콫콬콭콮콯쿄쿅쿆쿇쿈쿉쿊쿋쿌쿍쿎쿏쿐쿑쿒쿓쿔쿕쿖쿗쿘쿙" + "쿚쿛쿜쿝쿞쿟쿠쿡쿢쿣쿤쿥쿦쿧쿨쿩쿪쿫쿬쿭쿮쿯쿰쿱쿲쿳쿴쿵쿶쿷쿸쿹쿺쿻큐큑큒큓큔큕큖큗큘큙큚큛큜큝큞큟" + "큠큡큢큣큤큥큦큧큨큩큪큫크큭큮큯큰큱큲큳클큵큶큷큸큹큺큻큼큽큾큿킀킁킂킃킄킅킆킇토톡톢톣톤톥톦톧톨톩" + "톪톫톬톭톮톯톰톱톲톳톴통톶톷톸톹톺톻툐툑툒툓툔툕툖툗툘툙툚툛툜툝툞툟툠툡툢툣툤툥툦툧툨툩툪툫투툭툮툯" + "툰툱툲툳툴툵툶툷툸툹툺툻툼툽툾툿퉀퉁퉂퉃퉄퉅퉆퉇튜튝튞튟튠튡튢튣튤튥튦튧튨튩튪튫튬튭튮튯튰튱튲튳튴튵" + "튶튷트특튺튻튼튽튾튿틀틁틂틃틄틅틆틇틈틉틊틋틌틍틎틏틐틑틒틓포폭폮폯폰폱폲폳폴폵폶폷폸폹폺폻폼폽폾폿" + "퐀퐁퐂퐃퐄퐅퐆퐇표푝푞푟푠푡푢푣푤푥푦푧푨푩푪푫푬푭푮푯푰푱푲푳푴푵푶푷푸푹푺푻푼푽푾푿풀풁풂풃풄풅" + "풆풇품풉풊풋풌풍풎풏풐풑풒풓퓨퓩퓪퓫퓬퓭퓮퓯퓰퓱퓲퓳퓴퓵퓶퓷퓸퓹퓺퓻퓼퓽퓾퓿픀픁픂픃프픅픆픇픈픉픊픋" + "플픍픎픏픐픑픒픓픔픕픖픗픘픙픚픛픜픝픞픟호혹혺혻혼혽혾혿홀홁홂홃홄홅홆홇홈홉홊홋홌홍홎홏홐홑홒홓효횩" + "횪횫횬횭횮횯횰횱횲횳횴횵횶횷횸횹횺횻횼횽횾횿훀훁훂훃후훅훆훇훈훉훊훋훌훍훎훏훐훑훒훓훔훕훖훗훘훙훚훛" + "훜훝훞훟휴휵휶휷휸휹휺휻휼휽휾휿흀흁흂흃흄흅흆흇흈흉흊흋흌흍흎흏흐흑흒흓흔흕흖흗흘흙흚흛흜흝흞흟흠흡" + "흢흣흤흥흦흧흨흩흪흫" + ), + }, + "한컴 말랑말랑 Bold": { + 820: ( + "고곡곢곣곤곥곦곧골곩곪곫곬곭곮곯곰곱곲곳곴공곶곷곸곹곺곻교굑굒굓굔굕굖굗굘굙굚굛굜굝굞굟굠굡굢굣굤굥" + "굦굧굨굩굪굫구국굮굯군굱굲굳굴굵굶굷굸굹굺굻굼굽굾굿궀궁궂궃궄궅궆궇규귝귞귟균귡귢귣귤귥귦귧귨귩귪귫" + "귬귭귮귯귰귱귲귳귴귵귶귷그극귺귻근귽귾귿글긁긂긃긄긅긆긇금급긊긋긌긍긎긏긐긑긒긓꼬꼭꼮꼯꼰꼱꼲꼳꼴꼵" + "꼶꼷꼸꼹꼺꼻꼼꼽꼾꼿꽀꽁꽂꽃꽄꽅꽆꽇꾜꾝꾞꾟꾠꾡꾢꾣꾤꾥꾦꾧꾨꾩꾪꾫꾬꾭꾮꾯꾰꾱꾲꾳꾴꾵꾶꾷꾸꾹꾺꾻" + "꾼꾽꾾꾿꿀꿁꿂꿃꿄꿅꿆꿇꿈꿉꿊꿋꿌꿍꿎꿏꿐꿑꿒꿓뀨뀩뀪뀫뀬뀭뀮뀯뀰뀱뀲뀳뀴뀵뀶뀷뀸뀹뀺뀻뀼뀽뀾뀿끀끁" + "끂끃끄끅끆끇끈끉끊끋끌끍끎끏끐끑끒끓끔끕끖끗끘끙끚끛끜끝끞끟노녹녺녻논녽녾녿놀놁놂놃놄놅놆놇놈놉놊놋" + "놌농놎놏놐놑높놓뇨뇩뇪뇫뇬뇭뇮뇯뇰뇱뇲뇳뇴뇵뇶뇷뇸뇹뇺뇻뇼뇽뇾뇿눀눁눂눃누눅눆눇눈눉눊눋눌눍눎눏눐눑" + "눒눓눔눕눖눗눘눙눚눛눜눝눞눟뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄늅늆늇늈늉늊늋늌늍늎늏느늑늒늓는늕늖늗" + "늘늙늚늛늜늝늞늟늠늡늢늣늤능늦늧늨늩늪늫도독돆돇돈돉돊돋돌돍돎돏돐돑돒돓돔돕돖돗돘동돚돛돜돝돞돟됴됵" + "됶됷됸됹됺됻됼됽됾됿둀둁둂둃둄둅둆둇둈둉둊둋둌둍둎둏두둑둒둓둔둕둖둗둘둙둚둛둜둝둞둟둠둡둢둣둤둥둦둧" + "둨둩둪둫듀듁듂듃듄듅듆듇듈듉듊듋듌듍듎듏듐듑듒듓듔듕듖듗듘듙듚듛드득듞듟든듡듢듣들듥듦듧듨듩듪듫듬듭" + "듮듯듰등듲듳듴듵듶듷또똑똒똓똔똕똖똗똘똙똚똛똜똝똞똟똠똡똢똣똤똥똦똧똨똩똪똫뚀뚁뚂뚃뚄뚅뚆뚇뚈뚉뚊뚋" + "뚌뚍뚎뚏뚐뚑뚒뚓뚔뚕뚖뚗뚘뚙뚚뚛뚜뚝뚞뚟뚠뚡뚢뚣뚤뚥뚦뚧뚨뚩뚪뚫뚬뚭뚮뚯뚰뚱뚲뚳뚴뚵뚶뚷뜌뜍뜎뜏뜐뜑" + "뜒뜓뜔뜕뜖뜗뜘뜙뜚뜛뜜뜝뜞뜟뜠뜡뜢뜣뜤뜥뜦뜧뜨뜩뜪뜫뜬뜭뜮뜯뜰뜱뜲뜳뜴뜵뜶뜷뜸뜹뜺뜻뜼뜽뜾뜿띀띁띂띃" + "로록롞롟론롡롢롣롤롥롦롧롨롩롪롫롬롭롮롯롰롱롲롳롴롵롶롷료룍룎룏룐룑룒룓룔룕룖룗룘룙룚룛룜룝룞룟룠룡" + "룢룣룤룥룦룧루룩룪룫룬룭룮룯룰룱룲룳룴룵룶룷룸룹룺룻룼룽룾룿뤀뤁뤂뤃류륙륚륛륜륝륞륟률륡륢륣륤륥륦륧" + "륨륩륪륫륬륭륮륯륰륱륲륳르륵륶륷른륹륺륻를륽륾륿릀릁릂릃름릅릆릇릈릉릊릋릌릍릎릏모목몪몫몬몭몮몯몰몱" + "몲몳몴몵몶몷몸몹몺못몼몽몾몿뫀뫁뫂뫃묘묙묚묛묜묝묞묟묠묡묢묣묤묥묦묧묨묩묪묫묬묭묮묯묰묱묲묳무묵묶묷" + "문묹묺묻물묽묾묿뭀뭁뭂뭃뭄뭅뭆뭇뭈뭉뭊뭋뭌뭍뭎뭏뮤뮥뮦뮧뮨뮩뮪뮫뮬뮭뮮뮯뮰뮱뮲뮳뮴뮵뮶뮷뮸뮹뮺뮻뮼뮽" + "뮾뮿므믁믂믃믄믅믆믇믈믉믊믋믌믍믎믏믐믑믒믓믔믕믖믗믘믙믚믛보복볶볷본볹볺볻볼볽볾볿봀봁봂봃봄봅봆봇" + "봈봉봊봋봌봍봎봏뵤뵥뵦뵧뵨뵩뵪뵫뵬뵭뵮뵯뵰뵱뵲뵳뵴뵵뵶뵷뵸뵹뵺뵻뵼뵽뵾뵿부북붂붃분붅붆붇불붉붊붋붌붍" + "붎붏붐붑붒붓붔붕붖붗붘붙붚붛뷰뷱뷲뷳뷴뷵뷶뷷뷸뷹뷺뷻뷼뷽뷾뷿븀븁븂븃븄븅븆븇븈븉븊븋브븍븎븏븐븑븒븓" + "블븕븖븗븘븙븚븛븜븝븞븟븠븡븢븣븤븥븦븧뽀뽁뽂뽃뽄뽅뽆뽇뽈뽉뽊뽋뽌뽍뽎뽏뽐뽑뽒뽓뽔뽕뽖뽗뽘뽙뽚뽛뾰뾱" + "뾲뾳뾴뾵뾶뾷뾸뾹뾺뾻뾼뾽뾾뾿뿀뿁뿂뿃뿄뿅뿆뿇뿈뿉뿊뿋뿌뿍뿎뿏뿐뿑뿒뿓뿔뿕뿖뿗뿘뿙뿚뿛뿜뿝뿞뿟뿠뿡뿢뿣" + "뿤뿥뿦뿧쀼쀽쀾쀿쁀쁁쁂쁃쁄쁅쁆쁇쁈쁉쁊쁋쁌쁍쁎쁏쁐쁑쁒쁓쁔쁕쁖쁗쁘쁙쁚쁛쁜쁝쁞쁟쁠쁡쁢쁣쁤쁥쁦쁧쁨쁩" + "쁪쁫쁬쁭쁮쁯쁰쁱쁲쁳소속솎솏손솑솒솓솔솕솖솗솘솙솚솛솜솝솞솟솠송솢솣솤솥솦솧쇼쇽쇾쇿숀숁숂숃숄숅숆숇" + "숈숉숊숋숌숍숎숏숐숑숒숓숔숕숖숗수숙숚숛순숝숞숟술숡숢숣숤숥숦숧숨숩숪숫숬숭숮숯숰숱숲숳슈슉슊슋슌슍" + "슎슏슐슑슒슓슔슕슖슗슘슙슚슛슜슝슞슟슠슡슢슣스슥슦슧슨슩슪슫슬슭슮슯슰슱슲슳슴습슶슷슸승슺슻슼슽슾슿" + "쏘쏙쏚쏛쏜쏝쏞쏟쏠쏡쏢쏣쏤쏥쏦쏧쏨쏩쏪쏫쏬쏭쏮쏯쏰쏱쏲쏳쑈쑉쑊쑋쑌쑍쑎쑏쑐쑑쑒쑓쑔쑕쑖쑗쑘쑙쑚쑛쑜쑝" + "쑞쑟쑠쑡쑢쑣쑤쑥쑦쑧쑨쑩쑪쑫쑬쑭쑮쑯쑰쑱쑲쑳쑴쑵쑶쑷쑸쑹쑺쑻쑼쑽쑾쑿쓔쓕쓖쓗쓘쓙쓚쓛쓜쓝쓞쓟쓠쓡쓢쓣" + "쓤쓥쓦쓧쓨쓩쓪쓫쓬쓭쓮쓯쓰쓱쓲쓳쓴쓵쓶쓷쓸쓹쓺쓻쓼쓽쓾쓿씀씁씂씃씄씅씆씇씈씉씊씋오옥옦옧온옩옪옫올옭" + "옮옯옰옱옲옳옴옵옶옷옸옹옺옻옼옽옾옿요욕욖욗욘욙욚욛욜욝욞욟욠욡욢욣욤욥욦욧욨용욪욫욬욭욮욯우욱욲욳" + "운욵욶욷울욹욺욻욼욽욾욿움웁웂웃웄웅웆웇웈웉웊웋유육윢윣윤윥윦윧율윩윪윫윬윭윮윯윰윱윲윳윴융윶윷윸윹" + "윺윻으윽윾윿은읁읂읃을읅읆읇읈읉읊읋음읍읎읏읐응읒읓읔읕읖읗조족졲졳존졵졶졷졸졹졺졻졼졽졾졿좀좁좂좃" + "좄종좆좇좈좉좊좋죠죡죢죣죤죥죦죧죨죩죪죫죬죭죮죯죰죱죲죳죴죵죶죷죸죹죺죻주죽죾죿준줁줂줃줄줅줆줇줈줉" + "줊줋줌줍줎줏줐중줒줓줔줕줖줗쥬쥭쥮쥯쥰쥱쥲쥳쥴쥵쥶쥷쥸쥹쥺쥻쥼쥽쥾쥿즀즁즂즃즄즅즆즇즈즉즊즋즌즍즎즏" + "즐즑즒즓즔즕즖즗즘즙즚즛즜증즞즟즠즡즢즣쪼쪽쪾쪿쫀쫁쫂쫃쫄쫅쫆쫇쫈쫉쫊쫋쫌쫍쫎쫏쫐쫑쫒쫓쫔쫕쫖쫗쬬쬭" + "쬮쬯쬰쬱쬲쬳쬴쬵쬶쬷쬸쬹쬺쬻쬼쬽쬾쬿쭀쭁쭂쭃쭄쭅쭆쭇쭈쭉쭊쭋쭌쭍쭎쭏쭐쭑쭒쭓쭔쭕쭖쭗쭘쭙쭚쭛쭜쭝쭞쭟" + "쭠쭡쭢쭣쮸쮹쮺쮻쮼쮽쮾쮿쯀쯁쯂쯃쯄쯅쯆쯇쯈쯉쯊쯋쯌쯍쯎쯏쯐쯑쯒쯓쯔쯕쯖쯗쯘쯙쯚쯛쯜쯝쯞쯟쯠쯡쯢쯣쯤쯥" + "쯦쯧쯨쯩쯪쯫쯬쯭쯮쯯초촉촊촋촌촍촎촏촐촑촒촓촔촕촖촗촘촙촚촛촜총촞촟촠촡촢촣쵸쵹쵺쵻쵼쵽쵾쵿춀춁춂춃" + "춄춅춆춇춈춉춊춋춌춍춎춏춐춑춒춓추축춖춗춘춙춚춛출춝춞춟춠춡춢춣춤춥춦춧춨충춪춫춬춭춮춯츄츅츆츇츈츉" + "츊츋츌츍츎츏츐츑츒츓츔츕츖츗츘츙츚츛츜츝츞츟츠측츢츣츤츥츦츧츨츩츪츫츬츭츮츯츰츱츲츳츴층츶츷츸츹츺츻" + "코콕콖콗콘콙콚콛콜콝콞콟콠콡콢콣콤콥콦콧콨콩콪콫콬콭콮콯쿄쿅쿆쿇쿈쿉쿊쿋쿌쿍쿎쿏쿐쿑쿒쿓쿔쿕쿖쿗쿘쿙" + "쿚쿛쿜쿝쿞쿟쿠쿡쿢쿣쿤쿥쿦쿧쿨쿩쿪쿫쿬쿭쿮쿯쿰쿱쿲쿳쿴쿵쿶쿷쿸쿹쿺쿻큐큑큒큓큔큕큖큗큘큙큚큛큜큝큞큟" + "큠큡큢큣큤큥큦큧큨큩큪큫크큭큮큯큰큱큲큳클큵큶큷큸큹큺큻큼큽큾큿킀킁킂킃킄킅킆킇토톡톢톣톤톥톦톧톨톩" + "톪톫톬톭톮톯톰톱톲톳톴통톶톷톸톹톺톻툐툑툒툓툔툕툖툗툘툙툚툛툜툝툞툟툠툡툢툣툤툥툦툧툨툩툪툫투툭툮툯" + "툰툱툲툳툴툵툶툷툸툹툺툻툼툽툾툿퉀퉁퉂퉃퉄퉅퉆퉇튜튝튞튟튠튡튢튣튤튥튦튧튨튩튪튫튬튭튮튯튰튱튲튳튴튵" + "튶튷트특튺튻튼튽튾튿틀틁틂틃틄틅틆틇틈틉틊틋틌틍틎틏틐틑틒틓포폭폮폯폰폱폲폳폴폵폶폷폸폹폺폻폼폽폾폿" + "퐀퐁퐂퐃퐄퐅퐆퐇표푝푞푟푠푡푢푣푤푥푦푧푨푩푪푫푬푭푮푯푰푱푲푳푴푵푶푷푸푹푺푻푼푽푾푿풀풁풂풃풄풅" + "풆풇품풉풊풋풌풍풎풏풐풑풒풓퓨퓩퓪퓫퓬퓭퓮퓯퓰퓱퓲퓳퓴퓵퓶퓷퓸퓹퓺퓻퓼퓽퓾퓿픀픁픂픃프픅픆픇픈픉픊픋" + "플픍픎픏픐픑픒픓픔픕픖픗픘픙픚픛픜픝픞픟호혹혺혻혼혽혾혿홀홁홂홃홄홅홆홇홈홉홊홋홌홍홎홏홐홑홒홓효횩" + "횪횫횬횭횮횯횰횱횲횳횴횵횶횷횸횹횺횻횼횽횾횿훀훁훂훃후훅훆훇훈훉훊훋훌훍훎훏훐훑훒훓훔훕훖훗훘훙훚훛" + "훜훝훞훟휴휵휶휷휸휹휺휻휼휽휾휿흀흁흂흃흄흅흆흇흈흉흊흋흌흍흎흏흐흑흒흓흔흕흖흗흘흙흚흛흜흝흞흟흠흡" + "흢흣흤흥흦흧흨흩흪흫" + ), + }, + "KoPub돋움체 Light": { + 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", + }, + "KoPub돋움체 Medium": { + 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", + }, + "KoPub돋움체 Bold": { + 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", + }, + "KoPub바탕체 Light": { + 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", + }, + "KoPub바탕체 Medium": { + 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", + }, + "KoPub바탕체 Bold": { + 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", + }, + "KoPubWorld돋움체 Light": { + 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", + }, + "KoPubWorld돋움체 Medium": { + 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", + }, + "KoPubWorld돋움체 Bold": { + 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", + }, + "KoPubWorld바탕체 Light": { + 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", + }, + "KoPubWorld바탕체 Medium": { + 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", + }, + "KoPubWorld바탕체 Bold": { + 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", + }, +} + +#: Per face, design advance -> the glyphs the face lays out at that advance. +ADVANCES: dict[str, dict[int, str]] = { + "신명 태명조": { + 2: "\u302a\u302b", + 322: "˙", + 345: "ː", + 437: "⁏", + 465: "⁚⁝⁞", + 513: "¦", + 527: "˛", + 541: "˚", + 543: "ĺļľł", + 551: "ìíîïĩīĭįı", + 588: "Ι", + 592: "․‧", + 598: "‚‛", + 609: "ª", + 615: "¡", + 617: "ĵ", + 641: "¹", + 656: "⁴ⁿ₁₂₃₄", + 676: "ι", + 687: "‖′‵", + 691: "ÌÍÎÏĨĪĬĮİ", + 717: "¸", + 740: "ţťŧ", + 756: "‣", + 768: "º", + 771: "´", + 773: "˘", + 779: "¨", + 785: "²³", + 790: "ˇ", + 799: "„‟", + 805: "ŀ", + 811: "‹›", + 818: "•", + 838: "ŕŗř", + 854: "⁎", + 863: "¼½¾", + 891: "˝", + 898: "Ĵ‡", + 916: "τ‼", + 932: "śŝşš", + 934: "⁃", + 949: "źżž", + 951: "⁖", + 967: "⁅⁆", + 970: "″‶", + 977: "⚬", + 981: "¶", + 984: "‽", + 988: "çðćĉċč", + 994: ( + "〿。「」、ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑→" + "↓■○" + ), + 996: "§⁑", + 1004: "èéêëēĕėęě", + 1012: "¯", + 1024: ( + "¢»¿【】〔〕〖〗〘〙〚〛・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモ" + "ヤユヨラリルレロワン゙゚ᅠ" + ), + 1027: "«", + 1043: "àáâãäåāăą", + 1047: "₫", + 1059: "₰", + 1060: "её", + 1063: "òóôõöøōŏő", + 1065: "£", + 1067: "⁙", + 1072: "µ", + 1074: "δ", + 1076: "ĸ‸", + 1082: "ij‐‑", + 1088: "⁊", + 1092: "ζξ⚘", + 1094: "сэ", + 1098: "ν", + 1100: "β", + 1102: "з", + 1106: "х", + 1108: "у", + 1110: "μ", + 1113: "ďđ", + 1125: "ь", + 1129: "⚨⚲", + 1131: "ρ", + 1133: "ß", + 1135: "ĝğġģ", + 1137: "ε⁒", + 1141: "ķ", + 1142: "†", + 1147: "ùúûüĥħũūŭůűųа", + 1149: "¤ŷ", + 1156: "ñńņňʼnŋ", + 1160: "ýþÿκ", + 1168: "οо₤", + 1170: "¥б", + 1172: "гт", + 1174: "γ", + 1180: "ÞΡ⚚", + 1186: "‗", + 1203: "Β", + 1208: "η", + 1211: "υ", + 1213: "В", + 1215: "θ", + 1216: "‾", + 1219: "₦", + 1223: "ŹŻŽ", + 1224: "к", + 1227: "в", + 1229: "φ", + 1231: "₠₪", + 1232: "З", + 1242: "Р₲", + 1246: "Ζря‴‷₵", + 1248: "ΕЁБЕ", + 1254: "Γ", + 1256: "₴", + 1264: "χий", + 1274: "ŚŜŞŠГ", + 1278: "⁈", + 1280: "‒", + 1290: "ч", + 1295: "₣", + 1298: "ц⁉", + 1301: "⁄", + 1305: "₱", + 1311: "‥", + 1314: "ΚЯ⁘⁛", + 1321: "ĹĻĽĿŁ", + 1324: "ΤТ⁋⁌⁍", + 1330: "Ь", + 1332: "₭", + 1336: "⁗", + 1340: "₮", + 1342: "н", + 1344: "€", + 1346: "σ", + 1348: "С", + 1350: "⚭", + 1352: "α", + 1354: "ΞЭ", + 1362: "лп₥", + 1364: "ψ⁁₡₢", + 1377: "æК", + 1387: "ÈÉÊËĒĔĖĘĚ", + 1395: "⁕", + 1407: "Ç", + 1414: "ĆĈĊČ", + 1422: "⚥⚦", + 1424: "Δм", + 1426: "ΘΟО", + 1428: "Π", + 1434: "ŔŖŘЧ", + 1440: "ΥΧХ", + 1442: "ΑА", + 1448: "λ", + 1453: "Ŋъ", + 1454: "д", + 1462: "πω", + 1467: "ΗΝН", + 1473: "ИЙ", + 1475: "⚐⚑", + 1477: "Ω", + 1481: "œ", + 1504: "ПЦ", + 1506: "ΛЛ", + 1520: "ĜĞĠĢ", + 1524: "Д", + 1528: "Ψ", + 1530: "ΦФ", + 1532: "ÒÓÔÕÖØŌŎŐ", + 1534: "ÐĎĐ", + 1537: "У", + 1547: "Σ", + 1561: "ŶŸ", + 1575: "₳", + 1576: "‿⁀", + 1577: "ÙÚÛÜÝŢŤŦŨŪŬŮŰŲ", + 1586: "IJ", + 1592: "ÑŃŅŇ", + 1598: "Ķ", + 1600: "ж", + 1606: "ĤĦ", + 1608: "©", + 1614: "®", + 1616: "Ъ", + 1626: "₩", + 1627: "ÀÁÂÃÄÅĀĂĄ", + 1629: "ю", + 1631: "⁔", + 1637: "⁐", + 1639: "⚢", + 1645: "⁓", + 1650: "ы", + 1658: "₨", + 1682: "ΜМ", + 1686: "ŵ", + 1690: "шщ", + 1706: "⁇", + 1729: "⚩", + 1764: "◸◹◺◿", + 1772: "ШЩ", + 1790: "Ы⚣⚤", + 1792: "―", + 1840: "ф⚊⚋⚌⚍⚎⚏", + 1862: "⁂", + 1899: "Œ", + 1903: "Ж", + 1909: "⚮", + 1913: "Æ", + 1942: "Ю", + 1958: "‱", + 1960: "₧", + 1986: ( + "₯℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∊∋∌∍∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡∢∣∤∥" + "∦∧∨∩∪∫∬∭∮∯∰∱∲∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟≠≡" + "≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝" + "⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙" + "⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰" + "⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤" + "┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱▴▵▶▷" + "▸▹►▻▼▽▾▿◀◁◂◃◄◅◈◉◊◌◍◎◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷" + "☀☁☂☃☄☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☙☚☛☝☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂" + "♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽⚀" + "⚁⚂⚃⚄⚅⚆⚇⚈⚉✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷" + "✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❙❚❛❜❝❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻" + "❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻" + "➼➽➾、。〃〄〇〜〝〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘" + "㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝" + "㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'" + "()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abc" + "defghijklmnopqrstuvwxyz{|}~⦅⦆¢£¬ ̄¦¥₩" + ), + 2046: "¬", + 2048: "ſ⁜✀々〆〒〓〞〟가", + 2073: "☜☞", + 2118: "Ŵ", + 2232: "⚯", + 2812: "◻◼◽◾☔☕☘♾♿⚒⚓⚔⚕⚖⚗⚙⚛⚜⚠⚡⚧⚪⚫⚰⚱", + }, + "신명 견고딕": { + 1: "\u302a\u302b", + 195: "ıľ", + 198: "ī", + 200: "į", + 201: "ĵ", + 205: "Ī", + 212: "ìíîïĺļł", + 213: "⁏", + 220: "ĭ", + 226: "Į", + 227: "⁚⁝⁞", + 233: "ÌÍÎÏ", + 237: "¦", + 239: "¹", + 240: "ĩ", + 253: "Ĭİ", + 255: "ţťŧ", + 270: "´Ĩ", + 279: "ŀ", + 292: "‚‛", + 300: "¡", + 310: "ŕŗř", + 312: "˙", + 313: "˚˛", + 330: "¸", + 350: "¨", + 361: "º", + 363: "²", + 364: "³", + 371: "ª", + 375: "ˇ˘Ι„‟", + 384: "¼½", + 385: "¾ij", + 398: "ι", + 417: "⁎", + 438: "˝ζξ", + 457: "с", + 463: "⁖", + 464: "з", + 466: "ŷ", + 468: "ÿ", + 469: "ýþ", + 470: "ð", + 477: "⚬", + 478: "ķ", + 480: "śŝşš", + 483: "¢çćĉċč", + 485: ( + "źżžε〿ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑→" + "↓○" + ), + 486: "υ⁑", + 487: "»", + 488: "«", + 497: "Ĵ", + 498: "ĸ", + 500: ( + "ао‧▮▯◤◥❙❚〖〗〘〙。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマ" + "ミムメモヤユヨラリルレロワン゙゚ᅠ" + ), + 506: "э", + 509: "¯", + 511: "₫", + 515: "¿", + 517: "₰", + 520: "⁙", + 521: "р", + 522: "ρ", + 524: "Þ", + 526: "τ", + 529: "ñĝğġģĥńņňʼnŋ", + 531: "ùúûüďđũūŭůűų⁊", + 532: "èéêëēĕėęě", + 533: "⚘", + 534: "àáâãäåāăą", + 535: "ô", + 537: "З", + 538: "õ", + 539: "óöøōŏő", + 540: "ò", + 542: "δμοσеё", + 544: "α", + 547: "ν", + 548: "я", + 549: "ĹĻĽĿŁ₤", + 551: "⚨⚲", + 555: "⁒", + 556: "г", + 559: "ħ", + 560: "¥", + 561: "µ", + 562: "¶γ", + 563: "κх", + 565: "π", + 574: "б", + 576: "⚚", + 577: "у", + 580: "ь", + 585: "ßŹŻŽ", + 586: "ŢŤŦ", + 592: "¤", + 593: "ч", + 594: "в", + 595: "₦", + 601: "₠₪", + 603: "Ξ", + 605: "к", + 606: "₲", + 608: "₵", + 609: "£Ρ", + 610: "Γ", + 612: "Р", + 613: "₴", + 616: "Ь", + 617: "т", + 619: "ÝŊŶŸ", + 623: "η", + 624: "⁈", + 625: "ĶΖλωГ₣", + 626: "χ", + 632: "ÀÁÂÃÄÅĀĂĄ", + 634: "⁉", + 635: "Ş", + 636: "ŚŜŠ", + 637: "₱", + 640: "и", + 641: "⁘⁛", + 643: "§", + 645: "н", + 646: "⁋⁌⁍", + 649: "ÈÉÊËĒĔĖĘĚ", + 650: "Ч₭", + 652: "⁗", + 654: "Ββ₮", + 658: "Δ₧", + 659: "⚭", + 661: "φ", + 662: "п", + 665: "₥", + 666: "₡₢", + 667: "ΕΥЁБВЕСЭЯ", + 670: "д", + 680: "⁕", + 681: "IJ", + 684: "ΧХ", + 686: "ĎĐц", + 688: "ÙÚÛÜŨŪŬŮŲъ", + 689: "ĤĦ", + 690: "Űψф", + 692: "ÑŃŅŇŔŖŘУ", + 693: "Ð", + 694: "⚥⚦", + 697: "ŵ", + 699: "ÇĆĈĊČ", + 700: "Πл", + 708: "ΘΟθО", + 711: "Т", + 716: "Τ", + 717: "Ω", + 720: "⚐⚑", + 736: "ΦЛФ", + 741: "Ψ", + 749: "ÒÓÔÕÖŌŎŐ", + 750: "ΑΗΚΛΝАИЙН►◄", + 751: "ĜĞĠĢ", + 762: "ж", + 764: "©®", + 769: "₳", + 770: "м", + 774: "♦", + 780: "П", + 781: "Σ", + 787: "Ø", + 794: "Д", + 795: "Ъ", + 796: "⁔", + 798: "ю", + 799: "⁐⚢", + 801: "Ц", + 802: "⁓", + 810: "₨", + 813: "К", + 829: "æ", + 833: "⁇", + 844: "⚩", + 861: "◸◹◺◿", + 872: "œ", + 874: "⚣⚤", + 875: "шы", + 890: "щ", + 898: "⚊⚋⚌⚍⚎⚏", + 900: "Ы", + 904: "Ŵ", + 912: "ΜМ", + 924: "Œ", + 932: "⚮", + 936: "¬", + 950: "Æ", + 970: ( + "₯∊∍≛⋍⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿▢▭▰▻◅◌◍◖◗◚◛◠◡◢◣◧◨◩◪◫◬◭◮◰◱◲◳◴◵◶◷☀☉☊☋☌☍☐☓☖☗" + "☙☚☛☠☡☣☤☥☦☧☩☪☫☬☭☸☹☾☿♁♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♢♰♱♲♳♴♵♶♷♸♹" + "♺♻♼♽⚀⚁⚂⚃⚄⚅⚆⚇⚈⚉✁✃✄✆✇✈✌✍✎✏✐✑✒✓✕✖✘✙✚✛✜✞✟✠✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸" + "✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❛❜❝❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❿➀➁➂➃➄➅➆➇" + "➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➝➞➟➠➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻➼➽➾〝〠〡〢〣〤〥〦〧〨〩" + "〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾⦅⦆¦" + ), + 1000: ( + "ſːЖШЩЮй‐‑‒―‖‗†‡•‣․‥‱′″‴‵‶‷‸‹›‼‽‾‿⁀⁁⁂⁃⁄⁅⁆⁜⁴ⁿ₁₂₃₄₩€℉ℓ№℡™ΩÅ⅓⅔⅛⅜" + "⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∋∌∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡∢∣∤∥∦∧∨∩∪∫∬∭∮∯∰∱∲∳" + "∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≜≝≞≟≠≡≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰" + "≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬" + "⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩" + "⋪⋫⋬⋭⋮⋯⋰⋱⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨ" + "ⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂" + "╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▪▫▬▱▴▵▶▷▸▹▼▽▾▿◀◁◂◃◈◉◊◎◐◑◒◓◔◕◘◙◜◝◞◟◦◯☁☂☃☄☇☈☎" + "☏☑☒☜☝☞☟☢☨☮☯☰☱☲☳☴☵☶☷☺☻☼☽♀♂♠♡♣♤♥♧♨♩♪♫♬♭♮♯✀✂✉✔✗✝✡❶❷❸❹❺❻❼❽❾➜➡、。〃" + "〄々〆〇【】〒〓〔〕〚〛〜〞〟㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯" + "㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱" + "㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝가!"#$%&'()*+,-./0123456789:" + ";<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuv" + "wxyz{|}~¢£¬ ̄¥₩■" + ), + 1089: "⚯", + 1373: "◻◼◽◾☔☕☘♾♿⚒⚓⚔⚕⚖⚗⚙⚛⚜⚠⚡⚧⚪⚫⚰⚱", + }, + "한양그래픽": { + 2: "\u302a\u302b", + 322: "˙", + 345: "ː", + 437: "⁏", + 465: "⁚⁝⁞", + 513: "¦ìíîïīĭįıĵĺļľł", + 527: "˛", + 541: "˚", + 585: "ĩ", + 588: "Ι", + 592: "․‧", + 598: "ÌÍÎÏĨĪĬĮİ", + 641: "ŀ", + 656: "⁴ⁿ₁₂₃₄", + 676: "ι", + 682: "¸ŕŗřţťŧ‚‛", + 687: "‖′‵", + 756: "‣", + 768: "²³´¹ſ", + 773: "˘", + 790: "ˇ", + 811: "‹›", + 818: "•", + 854: "⁎", + 891: "˝", + 897: "ªº", + 898: "‡", + 916: "τ‼", + 934: "⁃", + 939: "‟", + 951: "⁖", + 967: "⁅⁆", + 970: "″‶", + 977: "⚬", + 984: "‽", + 994: ( + "〿。「」、ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑→" + "↓■○" + ), + 996: "⁑", + 1024: ( + "¡¨«¯»ýÿŷźżž„【】〔〕〖〗〘〙〚〛・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハ" + "ヒフヘホマミムメモヤユヨラリルレロワン゙゚ᅠ" + ), + 1047: "₫", + 1059: "₰", + 1060: "её", + 1067: "⁙", + 1074: "δ", + 1076: "‸", + 1082: "‐‑", + 1088: "⁊", + 1092: "ζξ⚘", + 1094: "сэ", + 1098: "ν", + 1100: "β", + 1102: "з", + 1106: "х", + 1108: "у", + 1110: "Ĵķĸśŝşšμ", + 1125: "ь", + 1129: "⚨⚲", + 1131: "ρ", + 1137: "ε⁒", + 1142: "†", + 1147: "а", + 1153: "¤§¶¼½¾", + 1160: "κ", + 1168: "οо₤", + 1170: "б", + 1172: "гт", + 1174: "γ", + 1180: "Ρ⚚", + 1186: "‗", + 1191: "Þ", + 1194: "¢µ¿àáâãäåçèêëùúûüāăąćĉċčēĕėęěĥħijĹĻĽĿŁŢŤŦũūŭůűų", + 1195: "é", + 1203: "Β", + 1208: "η", + 1211: "υ", + 1213: "В", + 1215: "θ", + 1216: "‾", + 1219: "£₦", + 1224: "к", + 1227: "в", + 1229: "φ", + 1231: "₠₪", + 1232: "З", + 1242: "Р₲", + 1246: "Ζря‴‷₵", + 1248: "ΕЁБЕ", + 1254: "Γ", + 1256: "₴", + 1264: "χий", + 1274: "Г", + 1278: "⁈", + 1280: "¥ÝßðñòóôõöøþďđĝğġģńņňŋōŏőŶŸŹŻŽ‒", + 1290: "ч", + 1295: "₣", + 1298: "ц⁉", + 1301: "⁄", + 1305: "₱", + 1311: "‥", + 1314: "ΚЯ⁘⁛", + 1324: "ΤТ⁋⁌⁍", + 1330: "Ь", + 1332: "₭", + 1336: "⁗", + 1340: "₮", + 1342: "н", + 1344: "€", + 1346: "σ", + 1348: "С", + 1350: "⚭", + 1352: "α", + 1354: "ΞЭ", + 1362: "лп₥", + 1364: "ψ⁁₡₢", + 1366: "ÀÁÂÃÄÅÈÉÊËĀĂĄĒĔĖĘĚĶŚŜŞŠ", + 1377: "К", + 1395: "⁕", + 1422: "⚥⚦", + 1424: "Δм", + 1426: "ΘΟО", + 1428: "Π", + 1434: "Ч", + 1440: "¬ΥΧХ", + 1442: "ΑА", + 1448: "λ", + 1450: "ŔŖŘ", + 1453: "ъ", + 1454: "д", + 1462: "πω", + 1467: "ΗΝН", + 1473: "ИЙ", + 1475: "⚐⚑", + 1477: "ʼnΩ", + 1504: "ПЦ", + 1506: "ΛЛ", + 1524: "Д", + 1528: "Ψ", + 1530: "ΦФ", + 1537: "ÇÐÑÙÚÛÜĆĈĊČĎĐĤĦIJŃŅŇŊŨŪŬŮŰŲŵУ", + 1547: "Σ", + 1575: "₳", + 1576: "‿⁀", + 1600: "ж", + 1604: "©®", + 1614: "æ", + 1616: "Ъ", + 1622: "ÒÓÔÕÖØŌŎŐ", + 1626: "₩", + 1629: "ю", + 1631: "⁔", + 1637: "⁐", + 1639: "⚢", + 1645: "⁓", + 1650: "ы", + 1658: "₨", + 1682: "ΜМ", + 1690: "шщ", + 1706: "ĜĞĠĢ⁇", + 1729: "⚩", + 1764: "◸◹◺◿", + 1772: "ШЩ", + 1790: "Ы⚣⚤", + 1792: "œ―", + 1840: "ф⚊⚋⚌⚍⚎⚏", + 1862: "⁂", + 1878: "Ŵ", + 1903: "Ж", + 1909: "⚮", + 1921: "Æ", + 1942: "Ю", + 1958: "‱", + 1960: "₧", + 1986: ( + "₯℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∊∋∌∍∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡∢∣∤∥" + "∦∧∨∩∪∫∬∭∮∯∰∱∲∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟≠≡" + "≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝" + "⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙" + "⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰" + "⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤" + "┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱▴▵▶▷" + "▸▹►▻▼▽▾▿◀◁◂◃◄◅◈◉◊◌◍◎◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷" + "☀☁☂☃☄☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☙☚☛☝☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂" + "♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽⚀" + "⚁⚂⚃⚄⚅⚆⚇⚈⚉✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷" + "✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❙❚❛❜❝❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻" + "❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻" + "➼➽➾、。〃〄〇〜〝〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘" + "㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝" + "㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'" + "()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abc" + "defghijklmnopqrstuvwxyz{|}~⦅⦆¢£¬ ̄¦¥₩" + ), + 2048: "Œ⁜✀々〆〒〓〞〟가", + 2073: "☜☞", + 2232: "⚯", + 2812: "◻◼◽◾☔☕☘♾♿⚒⚓⚔⚕⚖⚗⚙⚛⚜⚠⚡⚧⚪⚫⚰⚱", + }, + "바탕": { + 256: "¦", + 271: "′∙", + 299: "ìíîïĩīĭįıĺļľł‚‛", + 319: "ĵ˙", + 320: "˚˛", + 321: "\u0387", + 339: "‹›", + 341: "´¸∕", + 352: "ŀ", + 368: "²³", + 384: "\u00ad¯¹ÌÍÎÏĨĪĬĮİţťŧſˇ˘Ι•▪▫◦", + 401: "″", + 408: "ι", + 427: "¡ŕŗř", + 429: "ℓ", + 443: "ⁿ", + 448: "˝ζξ", + 468: "с", + 469: "Ĵźżž", + 475: "з", + 480: "ªº", + 497: "ε∫", + 498: "υ", + 512: "\u00a0¢£¤§¨«»¿àáâãäåāăąćĉċčśŝşšао‗„‾⁄∂", + 518: "э", + 532: "ç", + 533: "р", + 535: "ρ", + 539: "τ", + 543: "⅝", + 550: "З", + 555: "µèéêëðñòóôõöøùúûüþďđēĕėęěĝğġģĥħķĸńņňŋōŏőũūŭůűųδμοσеё", + 557: "α", + 560: "ν", + 561: "я", + 562: "₤√", + 569: "г", + 575: "γ", + 576: "¼½¾ijκ⅛⅜⅞", + 577: "х", + 579: "π", + 588: "б", + 591: "у", + 594: "ь", + 597: "ýÿŷ", + 601: "‡", + 607: "ч", + 608: "в†", + 617: "Ξ", + 619: "к", + 624: "Ρ", + 625: "Γ", + 627: "Р", + 628: "∆", + 631: "Ь", + 632: "т", + 638: "η", + 639: "♂", + 640: "¶ßĹĻĽĿŁŚŜŞŠŹŻŽΖλωГ‼₣", + 641: "χ", + 655: "и", + 660: "н", + 666: "Ч", + 670: "Ββ", + 674: "Δ₧", + 677: "φ", + 678: "п", + 683: "¥ÈÉÊËÝÞĆĈĊČĒĔĖĘĚŔŖŘŶŸΕΥЁБВЕСЭЯ", + 684: "∩", + 686: "д", + 690: "Ç€", + 700: "ΧХ", + 702: "ц", + 704: "ʼn―♪", + 705: "ъ", + 707: "ψф", + 709: "У", + 717: "Πл∏", + 725: "ÐÒÓÔÕÖØĎĐĜĞĠĢŌŎŐΘΟθО", + 728: "Т", + 733: "Τ", + 734: "Ω", + 736: "Ω", + 747: "♀", + 754: "ΦЛФ", + 759: "Ψ", + 768: "ÀÁÂÃÄÅÑÙÚÛÜĀĂĤĦIJĶŃŅŇŊŢŤŦŨŪŬŮŰŲΑΗΚΛΝАИЙН↕►◄♠", + 769: "Ą", + 780: "ж", + 781: "♫", + 786: "≈", + 788: "м", + 793: "◊♦", + 799: "П", + 800: "Σ", + 802: "©®", + 804: "¬", + 811: "ŵ", + 812: "♥", + 813: "Д", + 814: "Ъ", + 817: "ю", + 820: "Ц", + 832: "К∑−≠≡≤≥", + 864: "♣", + 865: "æ", + 870: "œ", + 896: "шы", + 911: "щ", + 922: "Ы", + 933: "∞", + 934: "ΜМ", + 936: "▼", + 938: "☼", + 960: "Œ", + 974: "∟", + 981: "Ŵ", + 1024: ( + "ÆːЖШЩЮй‥⁴₁₂₃₄₩℉№℡™Å⅓⅔↔↖↗↘↙⇒⇔∀∃∇∈∋∝∠∥∧∨∪∬∮∴∵∼∽≒≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠" + "⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└" + "┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦" + "▧▨▩▬▶▷▽◀◁◈◎◐◑◘◙☎☏☜☞☺☻♡♤♧♨♩♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖" + "㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛" + "㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%" + "&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a" + "bcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + }, + "바탕체": { + 512: ( + "\u0387\u00a0¢£¥¦©«¬¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöùú" + "ûüýÿĀāĂ㥹ĆćĈĉĊċČčĎďĐĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĨĩĪīĬĭĮįİĴĵĶķĹĺĻļĽľ" + "ŃńŅņŇňŌōŎŏŐőŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſ‗‚‛„•‹" + "›‼‾⁄₣₤₧₩∆−∕∙∟≈▪▫▬►◄◊◘◙◦☺☻☼♦♫" + ), + 993: "✀", + 1024: ( + "¡¤§¨ª\u00ad®²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘ" + "ΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТ" + "УФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄€℉" + "ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝" + "⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑" + "┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣" + "▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑" + "㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖" + "㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝" + "!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\" + "]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + }, + "돋움": { + 256: "¦ìíîïīĭĮįıĵĺļľł", + 299: "ÌÍÎĨĩĪĬİΙ‚‛∙", + 302: "Ï", + 320: "\u0387ŀ˚˛", + 325: "˙", + 330: "²³", + 341: "´¸ŕŗřţťŧ", + 344: "′", + 384: "¹ºſ˘ι•‹›∫▪▫◦", + 413: "ª", + 427: "¡", + 448: "ˇ˝", + 469: "„", + 512: "\u00a0¨«\u00ad¯»¼½¾ýÿijŷźżžζνξУух‗‾⁄ⁿ₧ℓ∕", + 513: "√", + 525: "ь", + 555: "Ĵķśŝşš", + 575: "⅜", + 576: "£¤§¶ĸγεκꆇ⅛⅝⅞∂", + 577: "βз″", + 581: "μ", + 585: "δ", + 588: "э", + 595: "я", + 597: "¢µ¿àáâãäåçèéêëùúûüāăąćĉċčēĕėęěĥħĹĻĽĿŁŢŤŦũūŭůűųΤτυχЗТЧаесчё", + 598: "бг", + 609: "ΓГ₣₤", + 610: "т", + 624: "ъ", + 625: "в", + 628: "∆", + 634: "ц", + 640: "¥ÝßðñòóôõöøþďđĝğġģńņňŋōŏőŶŸŹŻŽΖΥΧαηορσφХор‼♀♂", + 656: "н", + 657: "л", + 661: "п", + 669: "д", + 674: "и", + 678: "й", + 683: "ÀÁÂÃÄÅÈÉÊËÞĀĂĄĒĔĖĘĚŚŜŞŠΑΕΛΡЁАЕРЬ", + 691: "Σ", + 704: "ʼnθλπ―∏♪", + 719: "Π", + 720: "¬", + 722: "Δ", + 725: "ĶŔŖŘΒΚБВКЯ", + 732: "Л", + 736: "∩", + 749: "ψ", + 756: "Э", + 758: "м", + 760: "Ц", + 768: "ÇÑÙÚÛÜĆĈĊČĎĤĦIJŃŅŇŨŪŬŮŰŲŵΗΝΞΩωИЙНПС€Ω↕►◄♠", + 769: "Ŋ", + 770: "ÐĐ", + 781: "♫", + 782: "ф", + 787: "ж", + 789: "ΦФю", + 793: "◊♦", + 798: "ы", + 802: "©®", + 806: "Ъ", + 811: "ÒÓÔÕÖØŌŎŐΘΟО", + 812: "♥", + 814: "Ψ", + 832: "æД∑", + 845: "Ы", + 853: "ĜĞĠĢ−≈≠≡≤≥", + 859: "щ", + 861: "ш", + 864: "♣", + 896: "œΜМ", + 933: "∞", + 936: "▼", + 938: "☼", + 939: "Ŵ", + 957: "Œ", + 960: "ÆЖ", + 981: "₩", + 990: "ШЩ", + 995: "☃", + 1006: "∟", + 1015: "Ю", + 1024: ( + "ː‥⁴₁₂₃₄℉№℡™Å⅓⅔↔↖↗↘↙⇒⇔∀∃∇∈∋∝∠∥∧∨∪∬∮∴∵∼∽≒≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧" + "⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛" + "├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▬▶▷▽" + "◀◁◈◎◐◑◘◙☎☏☜☞☺☻♡♤♧♨♩♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠" + "㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢" + "㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+," + "-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefgh" + "ijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + }, + "돋움체": { + 512: ( + "\u0387\u00a0¢£¥¦©«¬¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöùú" + "ûüýÿĀāĂ㥹ĆćĈĉĊċČčĎďĐĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĨĩĪīĬĭĮįİĴĵĶķĹĺĻļĽľ" + "ŃńŅņŇňŌōŎŏŐőŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſ‗‚‛„•‹" + "›‼‾⁄₣₤₧₩∆−∕∙∟≈▪▫▬►◄◊◘◙◦☺☻☼♦♫" + ), + 993: "✀", + 1024: ( + "¡¤§¨ª\u00ad®²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘ" + "ΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТ" + "УФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄€℉" + "ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝" + "⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑" + "┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣" + "▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑" + "㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖" + "㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝" + "!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\" + "]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + }, + "굴림": { + 256: "¦ìíîïīĭįıĵĺļľł∙", + 293: "ĩ", + 299: "ÌÍÎÏĨĪĬĮİΙ", + 320: "\u0387ŀ˙˚˛", + 341: "¸ŕŗřţťŧ‚‛", + 384: "²³´¹ſˇ˘ι•′‹›∫▪▫◦", + 427: "¡⁄∕", + 448: "ªº˝ⁿ", + 512: "\u00a0¨«\u00ad¯»ýÿŷźżžζνξгух‗„″‾ℓ", + 555: "ĴķĸśŝşšκУк", + 561: "ь", + 562: "√", + 576: "¤§¶¼½¾γεзлчя†‡⅛⅜⅝⅞∂", + 577: "β", + 585: "δд", + 596: "Þ", + 597: "¢µ¿àáâãäåçèéêëùúûüāăąćĉċčēĕėęěĥħijĹĻĽĿŁŢŤŦũūŭůűųΤμτυχТЧаестё", + 609: "£ΓГ₣₤", + 623: "ц", + 628: "∆", + 640: "¥ÝßðñòóôõöøþďđĝğġģńņňŋōŏőŶŸŹŻŽΖΥΧαηορσφЗХбвийнопръэ‼♀♂", + 673: "Ь", + 683: "ÀÁÂÃÄÅÈÉÊËĀĂĄĒĔĖĘĚĶŚŜŞŠΕΚΛΡЁАБЕКР₧", + 704: "ΑΣΨθλπ―∏♪", + 719: "Π", + 720: "¬", + 725: "ŔŖŘΒВЯ", + 729: "Л", + 736: "ы∩", + 738: "ʼn", + 749: "ψ", + 756: "Ц", + 768: "ÇÐÑÙÚÛÜĆĈĊČĎĐĤĦIJŃŅŇŊŨŪŬŮŰŲŵΗΝΩωИЙНСЪЭжмф€Ω↕►◄♠", + 769: "Δ", + 781: "♫", + 790: "П", + 793: "◊♦", + 802: "©®", + 806: "æ", + 811: "ÒÓÔÕÖØŌŎŐΘΟΦО", + 812: "♥", + 832: "ΞДФшщ∑", + 853: "ĜĞĠĢ−≈≠≡≤≥", + 856: "М", + 864: "♣", + 865: "Ы", + 896: "œΜ", + 911: "ю", + 935: "∞", + 936: "▼", + 938: "☼", + 939: "Ŵ₩", + 960: "ÆШЩ", + 989: "Ж", + 995: "☃", + 1006: "∟", + 1024: ( + "ŒːЮ‥⁴₁₂₃₄℉№℡™Å⅓⅔↔↖↗↘↙⇒⇔∀∃∇∈∋∝∠∥∧∨∪∬∮∴∵∼∽≒≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥" + "⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙" + "┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▬▶" + "▷▽◀◁◈◎◐◑◘◙☎☏☜☞☺☻♡♤♧♨♩♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛" + "㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠" + "㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*" + "+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdef" + "ghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + }, + "굴림체": { + 512: ( + "\u0387\u00a0¢£¥¦©«¬¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöùú" + "ûüýÿĀāĂ㥹ĆćĈĉĊċČčĎďĐĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĨĩĪīĬĭĮįİĴĵĶķĹĺĻļĽľ" + "ŃńŅņŇňŌōŎŏŐőŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſ‗‚‛„•‹" + "›‼‾⁄₣₤₧₩∆−∕∙∟≈▪▫▬►◄◊◘◙◦☺☻☼♦♫" + ), + 993: "✀", + 1024: ( + "¡¤§¨ª\u00ad®²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘ" + "ΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТ" + "УФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄€℉" + "ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝" + "⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑" + "┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣" + "▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑" + "㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖" + "㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝" + "!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\" + "]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + }, + "궁서": { + 256: '¦∙', + 296: '․‧', + 320: '˙˚·', + 328: '⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉', + 341: '¸‚‛′', + 343: '‖‵', + 378: '‣', + 379: '‟', + 384: '´ˇ˘˛•‹›∕▪▫◦', + 427: '¡⁄', + 448: '\xad¯', + 512: '\xa0¤¨ª²³¹º¼½¾ĵſ˝ζξ‗„‾ⁿ⅛⅜⅝⅞', + 538: '″ℓ', + 541: '‐‑', + 550: '«»', + 555: 'ìíîïĩīĭįıĺļľŀł', + 557: 'ίι', + 563: '√', + 576: 'έ冇', + 583: '∫', + 597: '¿ÌÍÎÏĨĪĬĮİŕŗřśŝşšţťŧźżžΪ', + 602: 'Ι', + 608: '∂', + 611: '‼', + 612: 'δ', + 614: 'τз', + 620: 'г', + 623: '‴', + 631: 'οо', + 640: '¢§çèéêëðćĉċčēĕėęěĴΰβθςυбестхэё‒♀♂', + 663: 'Ь', + 665: 'ь', + 666: 'н', + 675: 'я', + 683: 'ÞàáâãäåñòóôõöøùúûüýþÿāăąďđĝğġģĥħķĸĹĻĽĿŁńņňʼnŋōŏőũūŭůűųŷΓΡάήαγηκμνρφГРУЧавдкруч₧', + 684: 'п', + 694: '₣', + 704: '£¬µ¶ΔΖΦσЗФЭ―₤∆♪', + 725: 'ÀÁÂÃÄÅÇÈÉÊËÐÒÓÔÕÖØÝĀĂĄĆĈĊČĎĐĒĔĖĘĚŌŎŐŚŜŞŠŢŤŦŶŸŹŻŽΑΒΕΛΟΣΤΥΧΫЁАБВЕОСТХ€', + 726: 'Θ', + 733: 'ий', + 736: '∩', + 738: 'ц', + 742: '¥', + 746: 'π', + 747: 'м', + 748: 'χ', + 751: 'ъ', + 768: 'ÑßĜĞĠĢĤĦĶŃŅŇŊŔŖŘΗΚΝλИЙКНПЦЯ₩℮↕≈►◄♠', + 779: 'л', + 781: '♫', + 782: 'Π', + 786: 'ф', + 792: 'Д', + 793: '◊♦', + 796: 'ω', + 802: '©®', + 810: 'Ξfifl', + 811: 'ÙÚÛÜŨŪŬŮŰŲŵ', + 812: '♥', + 817: 'Лш', + 818: '∏', + 832: 'æΩψжΩ', + 853: 'ŴΜМ−≠≡≤≥', + 862: 'щ', + 864: 'Ъ♣', + 896: 'ы', + 905: 'Ψ', + 909: 'ю', + 919: '∑', + 923: 'ij', + 935: '∞', + 936: '▼', + 938: '☼', + 971: 'œ', + 979: '‱', + 983: '№', + 1024: 'ÆIJŒːЖШЩЫЮ‥⁴₁₂₃₄℉℡™Å⅓⅔↔↖↗↘↙⇒⇔∀∃∇∈∋∝∟∠∥∧∨∪∬∮∴∵∼∽≒≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▬▶▷▽◀◁◈◎◐◑◘◙☎☏☜☞☺☻♡♤♧♨♩♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩', + }, + "궁서체": { + 512: ( + "\u0387\u00a0¢£¥¦©«¬¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöùú" + "ûüýÿĀāĂ㥹ĆćĈĉĊċČčĎďĐĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĨĩĪīĬĭĮįİĴĵĶķĹĺĻļĽľ" + "ŃńŅņŇňŌōŎŏŐőŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſ‗‚‛„•‹" + "›‼‾⁄₣₤₧₩∆−∕∙∟≈▪▫▬►◄◊◘◙◦☺☻☼♦♫" + ), + 993: "✀", + 1024: ( + "¡¤§¨ª\u00ad®²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘ" + "ΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТ" + "УФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄€℉" + "ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝" + "⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑" + "┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣" + "▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑" + "㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖" + "㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝" + "!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\" + "]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + }, + "한컴 고딕": { + 161: "\u0387", + 254: "ι", + 260: "²³¹", + 300: "´", + 317: "Ι", + 378: "ª", + 385: "º", + 436: "⁑", + 446: "¡§¸", + 448: "υ", + 473: "ν", + 477: "ψ", + 478: "\u00ad", + 486: "ː˛′″⁴ⁿ₁₂₃₄∂、。【】〔〕", + 501: "σ", + 525: "κ", + 529: "ε", + 544: "я", + 547: "γ", + 549: "β", + 552: "ρ", + 556: "θ", + 560: "δ", + 572: "Τ", + 575: "μ", + 581: "Υ", + 582: "ο", + 584: "Ζ", + 586: "•", + 588: "ζ", + 593: "λτ", + 595: "αη", + 600: "Λ", + 607: "Χ", + 608: "ξ", + 609: "Γ", + 620: "Σ", + 624: "ΞΦ", + 625: "Ε", + 637: "ω", + 650: "Ωπ", + 653: "ΑΔ", + 656: "φ", + 657: "Ψχ", + 660: "Ρ", + 664: "ΒΚ", + 666: "Π", + 669: "¿", + 672: "―", + 676: "ΘΟ", + 680: "€", + 694: "Η", + 728: "Ν", + 800: "¨¶øþ", + 826: "Μ", + 892: "¤®¼½¾ÆÐØÞßæðŒœ†‡™", + 932: ( + "đĦħıIJijĸĿŀŁłʼnŊŋŦŧˇ˘˙˚˝ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгде" + "жзийклмнопрстуфхцчшщъыьэюё‥℉ℓ№℡ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧" + "∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙ" + "ⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳" + "┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000" + "〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿" + "㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾" + "㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGH" + "IJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + 970: "◉◯☐☑❍", + }, + "함초롬바탕": { + 0: "\u302a\u302b", + 157: "˙", + 161: "·", + 168: "ː", + 257: "˛", + 264: "˚", + 286: "¦", + 287: "ìíîïĩīĭįıĺļΙ", + 288: "ĵ", + 289: "․‧", + 290: "⁚", + 291: "‚‛⁏⁝⁞", + 296: "´", + 300: "\u00a0", + 305: "ÌÍÎÏĨĪĬĮİ", + 313: "\uf09e\uf0a0", + 315: "Ĵ", + 320: "¡²³¹⁴ⁿ₁₂₃₄", + 330: "ι", + 335: "‖′‵", + 336: "ſ", + 356: "ţŧ", + 364: "ł", + 369: "‣", + 374: "¨", + 377: "˘", + 385: "\uf0fa", + 386: "ˇ", + 396: "º‹›", + 399: "•", + 411: "„‟", + 422: "ľ", + 426: "ŀ", + 433: "ª", + 434: "ť", + 435: "˝", + 438: "‡", + 440: "«»", + 447: "τ‼", + 456: "\u00ad⁃", + 458: "\uf027\uf073\uf09f\uf0a7", + 472: "⁅⁆", + 474: "″‶", + 478: "ŕŗř", + 480: "‽", + 483: "\uf0f9", + 485: ( + "〿。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロ" + "ワン゙゚ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑→↓" + "■○" + ), + 486: "źżž⁎⁑", + 496: "śŝşš", + 498: "§", + 500: "【】〔〕〖〗〘〙〚〛\uf07f", + 511: "₫", + 517: "₰", + 518: "её", + 524: "δ", + 525: "‸", + 528: "‐‑", + 531: "⁊\uf07d\uf07e", + 533: "ζξ", + 534: "сэ", + 536: "èéêëēĕėęěν", + 537: "β", + 538: "з⁖", + 540: "х", + 541: "у", + 542: "μ", + 543: "ýÿŷ", + 544: "ß", + 549: "ь\uf047\uf048", + 550: "µ¿", + 552: "çćĉċčρ", + 554: "\uf035", + 555: "ε⁒", + 558: "†⁕", + 560: "ŋа", + 561: "¢", + 562: "ĝğġģ", + 564: "¬", + 566: "κ", + 568: "£", + 569: "àáâãäåāăą", + 570: "ðοо₤", + 571: "б", + 572: "гт", + 573: "γ⁗", + 574: "ij", + 575: "¯Þ", + 576: "Ρ", + 578: "\uf077", + 579: "‗", + 580: "ķ", + 584: "IJ", + 587: "Β\uf041", + 588: "òóôõöōŏő", + 590: "η", + 591: "υ", + 592: "В", + 593: "θ", + 594: "‾", + 595: "₦", + 598: "к", + 599: "в", + 600: "φ", + 601: "₠₪", + 602: "З", + 603: "⁙\uf036", + 605: "ĹĻĽĿ", + 606: "¶Р₲", + 608: "þΖря‴‷₵", + 609: "ΕЁБЕ", + 610: "¤", + 612: "¸Γ", + 613: "₴", + 615: "ĸ", + 617: "χий", + 622: "Г", + 624: "⁈⁘", + 625: "‒", + 626: "ŹŻŽ", + 627: "ÈÉÊËĒĔĖĘĚŚŜŞŠ", + 630: "ч", + 632: "₣", + 634: "ц⁉", + 635: "ñùúûüĥńņňũūŭůűų⁄", + 636: "\uf0fb", + 637: "₱", + 638: "Ł", + 640: "đ‥", + 642: "ĶΚЯ", + 646: "ΤТ⁋⁌⁍", + 649: "Ь", + 650: "₭", + 651: "\uf053", + 654: "₮", + 655: "н", + 656: "€", + 657: "σ", + 658: "С", + 660: "ŔŖŘα\uf04e", + 661: "ΞЭ", + 664: "ŢŤŦ", + 665: "ħлп₥", + 666: "ψ⁁₡₢", + 672: "К", + 674: "\uf043\uf044", + 683: "ĜĞĠĢ", + 684: "ď⁛", + 685: "ÇøĆĈĊČ", + 688: "⁓", + 693: "\uf058", + 695: "Δм", + 696: "ØΘΟО", + 697: "Π", + 700: "Ч\uf032\uf033", + 703: "ΥΧХ", + 704: "ΑА", + 705: "ÝʼnŶŸ", + 706: "ÀÁÂÃÄÅĀĂĄ", + 707: "¥λ", + 709: "ъ", + 710: "д", + 714: "πω", + 716: "ŊΗΝН", + 719: "ĎИЙ", + 720: "ŵ", + 721: "Ω", + 723: "\uf057", + 731: "ÙÚÛÜŨŪŬŮŰŲ", + 732: "ÒÓÔÕÖŌŎŐ", + 734: "ÑĤŃŅŇПЦ", + 735: "ΛЛ", + 744: "Д", + 746: "Ψ", + 747: "ΦФ\uf055\uf056\uf06c\uf06e\uf074", + 750: "У", + 755: "Σ", + 762: "Ħ", + 768: "Ð", + 769: "Đ⁜₳", + 770: "‿⁀⁔", + 776: "\uf0e3\uf0e4\uf0e5\uf0e6", + 780: "\uf069", + 781: "ж", + 783: "\uf0f5\uf0f6\uf0f7\uf0f8", + 787: "\uf0fc", + 789: "Ъ", + 793: "\uf042", + 794: "₩\uf059\uf0d7\uf0d8", + 795: "ю", + 799: "⁐", + 800: "©®", + 806: "ы", + 810: "₨", + 811: "\uf0f1\uf0f2\uf0f4", + 813: "\uf054", + 821: "ΜМ", + 825: "шщ", + 843: "\uf04a\uf04b\uf04c", + 849: "\uf04f", + 865: "ШЩ", + 873: "\uf0eb\uf0ec\uf0ed\uf0ee", + 874: "Ы", + 875: "―", + 877: "œ", + 878: "⁇", + 880: "\uf052", + 885: "\uf05a", + 887: "\uf051", + 891: "æ\uf03b\uf03e\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0", + 893: "\uf029\uf034\uf03c\uf03d\uf049\uf05b\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0fd\uf0fe", + 894: "\uf025", + 896: "\uf05c", + 898: "ф", + 909: "⁂", + 910: "Ŵ", + 911: "\uf03f\uf040", + 921: "Œ", + 929: "Ж\uf066", + 933: "\uf063", + 940: "\uf03a\uf062", + 943: "\uf045\uf046", + 947: "\uf038\uf064", + 948: "Ю", + 953: "\uf06d\uf0a6", + 956: "‱", + 957: "₧", + 959: "Æ", + 963: "\uf060", + 970: ( + "¼½¾\u205f₯℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∊∋∌∍∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡" + "∢∣∤∥∦∧∨∩∪∫∬∭∮∯∰∱∲∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝" + "≞≟≠≡≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙" + "⊚⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕" + "⋖⋗⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬" + "⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠" + "┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱" + "▴▵▶▷▸▹►▻▼▽▾▿◀◁◂◃◄◅◈◉◊◌◍◎◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳" + "◴◵◶◷◸◹◺◻◼◽◾◿☀☁☂☃☄☇☈☉☊☋☌☍☎☏☐☑☒☓☔☕☖☗☘☙☚☛☝☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳" + "☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯" + "♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚇⚈⚉⚊⚋⚌⚍⚎⚏⚐⚑⚒⚓⚔⚕⚖⚗⚘⚙⚚⚛⚜⚠⚡⚢⚣⚤⚥⚦⚧⚨⚩⚪⚫⚬⚭⚮" + "⚯⚰⚱⚲✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸✹✺✻✼" + "✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❙❚❛❜❝❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻❼❽❾❿➀" + "➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻➼➽➾\u3000、" + "。〃〄々〆〇〒〓〜〝〞〟〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖" + "㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛" + "㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%" + "&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a" + "bcdefghijklmnopqrstuvwxyz{|}~⦅⦆ᅠ¢£¬ ̄¦¥₩" + ), + 980: "\uf0df\uf0e0", + 987: "\uf075", + 1000: "\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4", + 1012: "☜☞", + 1025: "\uf065", + 1031: "\uf021", + 1036: "\uf0ff", + 1047: "\uf0c7\uf0c8\uf0c9\uf0ca", + 1051: "\uf06a", + 1054: "\uf05f", + 1060: "\uf078\uf079\uf0f3", + 1065: "\uf068", + 1067: "\uf0e7\uf0e8", + 1073: "\uf037", + 1078: "\uf039", + 1083: "\uf028", + 1089: "\uf050", + 1091: "\uf061", + 1096: "\uf030\uf067", + 1111: "\uf04d", + 1133: "\uf02a\uf02b", + 1145: "\uf022", + 1156: "\uf05e", + 1171: "\uf02c\uf02d", + 1216: "\uf026", + 1253: "\uf0d5\uf0d6", + 1271: "\uf06b", + 1300: "\uf023", + }, + "함초롬돋움": { + 0: "\u302a\u302b", + 157: "˙", + 161: "·", + 168: "ː", + 240: "´", + 257: "˛", + 258: "ĺļ", + 264: "˚", + 268: "ĵ", + 271: "ìíîïĩīĭįı", + 287: "Ι", + 288: "‚‛", + 289: "․‧", + 290: "⁚", + 291: "⁏⁝⁞", + 300: "\u00a0", + 309: "ſ", + 313: "\uf09e\uf0a0", + 317: "ÌÍÎÏĨĪĬĮİ", + 320: "²³¹⁴ⁿ₁₂₃₄", + 330: "ι", + 333: "¡", + 334: "ł", + 335: "‖′‵", + 349: "ţŧ", + 361: "ľ", + 369: "‣", + 373: "¸", + 377: "˘", + 378: "ªť", + 382: "ŀ", + 385: "º\uf0fa", + 386: "ˇ", + 396: "‹›", + 399: "•", + 427: "ŕŗř", + 435: "˝", + 438: "‡", + 447: "τ‼", + 451: "„", + 456: "⁃", + 458: "\uf027\uf073\uf09f\uf0a7", + 464: "¦", + 466: "ýÿŷ", + 472: "⁅⁆", + 474: "″‶", + 478: "\u00ad¯", + 479: "źżž", + 480: "‽", + 483: "\uf0f9", + 485: ( + "〿。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロ" + "ワン゙゚ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑→↓" + "■○" + ), + 486: "§⁎⁑", + 488: "‟", + 489: "ij", + 500: "ð【】〔〕〖〗〘〙〚〛\uf07f", + 511: "₫", + 513: "çćĉċčśŝşš", + 514: "¢¨", + 515: "Ĵ", + 517: "₰", + 518: "её", + 524: "δ", + 525: "‸", + 528: "‐‑", + 531: "¬⁊\uf07d\uf07e", + 533: "ζξ", + 534: "Þсэ", + 535: "«", + 536: "»ν", + 537: "β", + 538: "з⁖", + 540: "х", + 541: "þу", + 542: "μ", + 543: "¶", + 549: "ь\uf047\uf048", + 552: "ρ", + 554: "\uf035", + 555: "¥µε⁒", + 556: "£", + 558: "†⁕", + 559: "ķĸ", + 560: "а", + 563: "àáâãäåāăąĝğġģ", + 566: "κ", + 567: "èéêëēĕėęě", + 570: "¤¿οо₤", + 571: "б", + 572: "Ŧгт", + 573: "ŢŤγ⁗", + 576: "Ρ", + 578: "\uf077", + 579: "‗", + 581: "ÝŶŸ", + 582: "òóôõöøōŏő", + 583: "ß", + 584: "ĹĻĽĿŁŹŻŽ", + 587: "Β\uf041", + 590: "η", + 591: "υ", + 592: "В", + 593: "θ", + 594: "ĥħ‾", + 595: "ñùúûüńņňŋũūŭůűų₦", + 598: "к", + 599: "в", + 600: "φ", + 601: "₠₪", + 602: "З", + 603: "⁙\uf036", + 604: "đ", + 606: "Р₲", + 608: "Ζря‴‷₵", + 609: "ΕЁБЕ", + 612: "Γ", + 613: "₴", + 617: "ŚŜŞŠχий", + 622: "Г", + 624: "⁈⁘", + 625: "ÈÉÊËĒĔĖĘĚ‒", + 630: "ч", + 632: "₣", + 633: "ÇĆĈĊČ", + 634: "ц⁉", + 635: "⁄", + 636: "\uf0fb", + 637: "₱", + 640: "‥", + 642: "ΚЯ", + 645: "ĜĞĠĢ", + 646: "ΤТ⁋⁌⁍", + 649: "Ь", + 650: "₭", + 651: "\uf053", + 654: "ÀÁÂÃÄÅĀĂĄ₮", + 655: "н", + 656: "€", + 657: "σ", + 658: "С", + 660: "α\uf04e", + 661: "ΞЭ", + 662: "ď", + 664: "Ķ", + 665: "лп₥", + 666: "ψ⁁₡₢", + 672: "К", + 674: "\uf043\uf044", + 676: "ÒÓÔÕÖØŌŎŐ", + 683: "ŔŖŘ", + 684: "⁛", + 688: "⁓", + 693: "ʼn\uf058", + 694: "ĤĦ", + 695: "Δм", + 696: "ΘΟО", + 697: "Π", + 700: "Ч\uf032\uf033", + 701: "ÐĎĐ", + 702: "ÙÚÛÜŨŪŬŮŰŲ", + 703: "ΥΧХ", + 704: "ΑА", + 707: "λ", + 709: "ъ", + 710: "д", + 714: "πω", + 716: "ΗΝН", + 719: "ИЙ", + 721: "Ω", + 723: "\uf057", + 728: "ÑŃŅŇŊ", + 734: "ПЦ", + 735: "ΛЛ", + 744: "Д", + 746: "Ψ", + 747: "ΦФ\uf055\uf056\uf06c\uf06e\uf074", + 750: "У", + 755: "Σ", + 760: "ŵ", + 769: "⁜₳", + 770: "‿⁀⁔", + 776: "\uf0e3\uf0e4\uf0e5\uf0e6", + 780: "\uf069", + 781: "ж", + 782: "IJ", + 783: "\uf0f5\uf0f6\uf0f7\uf0f8", + 787: "\uf0fc", + 789: "Ъ", + 793: "\uf042", + 794: "₩\uf059\uf0d7\uf0d8", + 795: "ю", + 799: "⁐", + 806: "ы", + 810: "₨", + 811: "\uf0f1\uf0f2\uf0f4", + 813: "\uf054", + 821: "ΜМ", + 825: "шщ", + 843: "\uf04a\uf04b\uf04c", + 847: "æ", + 849: "\uf04f", + 858: "©®", + 865: "ШЩ", + 873: "\uf0eb\uf0ec\uf0ed\uf0ee", + 874: "Ы", + 875: "―", + 878: "⁇", + 880: "\uf052", + 885: "\uf05a", + 887: "\uf051", + 891: "\uf03b\uf03e\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0", + 893: "\uf029\uf034\uf03c\uf03d\uf049\uf05b\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0fd\uf0fe", + 894: "\uf025", + 896: "\uf05c", + 897: "Ŵ", + 898: "ф", + 909: "⁂", + 911: "\uf03f\uf040", + 929: "Ж\uf066", + 933: "\uf063", + 934: "Œ", + 940: "\uf03a\uf062", + 943: "\uf045\uf046", + 947: "\uf038\uf064", + 948: "Ю", + 950: "œ", + 953: "\uf06d\uf0a6", + 956: "‱", + 957: "₧", + 963: "\uf060", + 967: "Æ", + 970: ( + "¼½¾\u205f₯℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∊∋∌∍∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡" + "∢∣∤∥∦∧∨∩∪∫∬∭∮∯∰∱∲∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝" + "≞≟≠≡≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙" + "⊚⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕" + "⋖⋗⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬" + "⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠" + "┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱" + "▴▵▶▷▸▹►▻▼▽▾▿◀◁◂◃◄◅◈◉◊◌◍◎◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳" + "◴◵◶◷◸◹◺◻◼◽◾◿☀☁☂☃☄☇☈☉☊☋☌☍☎☏☐☑☒☓☔☕☖☗☘☙☚☛☝☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳" + "☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯" + "♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚇⚈⚉⚊⚋⚌⚍⚎⚏⚐⚑⚒⚓⚔⚕⚖⚗⚘⚙⚚⚛⚜⚠⚡⚢⚣⚤⚥⚦⚧⚨⚩⚪⚫⚬⚭⚮" + "⚯⚰⚱⚲✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸✹✺✻✼" + "✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❙❚❛❜❝❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻❼❽❾❿➀" + "➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻➼➽➾\u3000、" + "。〃〄々〆〇〒〓〜〝〞〟〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖" + "㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛" + "㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%" + "&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a" + "bcdefghijklmnopqrstuvwxyz{|}~⦅⦆ᅠ¢£¬ ̄¦¥₩" + ), + 980: "\uf0df\uf0e0", + 987: "\uf075", + 1000: "\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4", + 1012: "☜☞", + 1025: "\uf065", + 1031: "\uf021", + 1036: "\uf0ff", + 1047: "\uf0c7\uf0c8\uf0c9\uf0ca", + 1051: "\uf06a", + 1054: "\uf05f", + 1060: "\uf078\uf079\uf0f3", + 1065: "\uf068", + 1067: "\uf0e7\uf0e8", + 1073: "\uf037", + 1078: "\uf039", + 1083: "\uf028", + 1089: "\uf050", + 1091: "\uf061", + 1096: "\uf030\uf067", + 1111: "\uf04d", + 1133: "\uf02a\uf02b", + 1145: "\uf022", + 1156: "\uf05e", + 1171: "\uf02c\uf02d", + 1216: "\uf026", + 1253: "\uf0d5\uf0d6", + 1271: "\uf06b", + 1300: "\uf023", + }, + "맑은 고딕": { + 330: "·", + 377: "˛", + 416: "˙", + 430: "¸", + 467: "ː", + 473: "‚′", + 490: "¦", + 499: "ł", + 504: "ìíîïı", + 552: "ι", + 553: "ÌÍÎÏΙ", + 590: "´˚", + 592: "¡", + 633: "˘", + 641: "\uf09e\uf0a0", + 645: "∙", + 660: "‹›", + 670: "˝", + 679: "ℓ", + 695: "ŀ", + 706: "ŧ", + 720: "\u00a0", + 729: "⁴", + 732: "¹", + 764: "²³", + 776: "„″", + 778: "ˇ", + 783: "†‡", + 788: "₁₂₃₄", + 790: "\uf0fa", + 801: "г", + 816: "ⁿ", + 821: "ª", + 840: "\u00ad", + 855: "•", + 856: "т", + 864: "¨", + 887: "š", + 895: "‥", + 901: "¯", + 902: "º", + 917: "ε", + 925: "ζ", + 930: "ξ₮", + 932: "з", + 935: "\uf073\uf09f\uf0a7", + 937: "§", + 938: "\uf027", + 942: "¿", + 946: "ž", + 952: "х", + 954: "₰", + 956: "¶", + 968: "çс", + 969: "э", + 983: "ĿŁ", + 985: "ΓГ", + 987: "\uf0f9", + 999: "〔〕", + 1006: "ij", + 1009: "ýÿу", + 1016: "τ", + 1021: "₣", + 1024: "ᅠᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ\uf07f", + 1031: "₭", + 1036: "ĸк", + 1040: "λ", + 1048: "я", + 1052: "ь", + 1053: "«»", + 1059: "ÈÉÊËΕЁЕ", + 1061: "【】", + 1065: "àáâãäåа", + 1066: "Ξ", + 1077: "Σ", + 1084: "γ", + 1087: "\uf07d\uf07e", + 1093: "ŦΤТ", + 1094: "κ", + 1096: "èéêëелё", + 1101: "ν", + 1102: "♩", + 1107: "в₪", + 1112: "Š", + 1116: "∮", + 1119: "∂", + 1122: "∃", + 1125: "\uf047\uf048", + 1128: "¢£¥₤", + 1129: "χ€∫", + 1131: "ßЗ", + 1132: "₡₢", + 1136: "\uf035", + 1140: "д", + 1141: "β", + 1152: "υ", + 1154: "ÝŸΥ", + 1168: "¤", + 1169: "ÞΡР", + 1170: "ð", + 1174: "♭", + 1181: "\uf077", + 1183: "ħч", + 1184: "ñùúûüŋ‼", + 1186: "У", + 1192: "Б", + 1193: "ŽΖ", + 1195: "ΒВ", + 1202: "σ", + 1203: "\uf041", + 1204: "ηЬ", + 1208: "µμнп", + 1209: "ΚК", + 1213: "б", + 1214: "ий", + 1217: "◌", + 1224: "δ", + 1226: "ρ", + 1227: "òóôõöøοо", + 1228: "θ₫", + 1229: "₱", + 1230: "þр", + 1231: "đΧХ", + 1234: "ъ", + 1235: "Я", + 1236: "\uf036", + 1253: "ц", + 1262: "ʼn", + 1280: "♀", + 1288: "α", + 1292: "∑", + 1294: "Э", + 1300: "ÇС", + 1304: "₠\uf0fb", + 1309: "π", + 1313: "Λ", + 1322: "IJ", + 1333: "\uf053", + 1347: "Δ", + 1348: "ÀÁÂÃÄÅΑА", + 1350: "₦", + 1352: "\uf04e", + 1365: "√", + 1366: "∠∴∵", + 1380: "Ч", + 1382: "\uf043\uf044", + 1401: "∥∧∨∼∽≒≡", + 1406: "Л", + 1409: "♪", + 1419: "\uf058", + 1425: "Å∀", + 1428: "ф", + 1434: "\uf032\uf033", + 1435: "¬", + 1436: "≠≤≥", + 1439: "ÙÚÛÜ", + 1446: "Д", + 1460: "∇", + 1463: "φ", + 1464: "♂", + 1465: "м", + 1469: "Ð", + 1476: "Ъы", + 1482: "\uf057", + 1484: "ĦΗН", + 1491: "ΠП", + 1511: "Ф", + 1530: "\uf055\uf056\uf06c\uf06e\uf074", + 1534: "⁈⁉", + 1549: "Ц", + 1553: "ж", + 1564: "₩", + 1567: "ÑŊΝ", + 1568: "ИЙ", + 1570: "ψ", + 1576: "Φ", + 1580: "∏", + 1584: "ÒÓÔÕÖØΘΟО", + 1585: "ΩΩ", + 1591: "\uf0e3\uf0e4\uf0e5\uf0e6", + 1598: "\uf069", + 1601: "\uf0f5\uf0f6\uf0f7\uf0f8", + 1609: "\uf0fc", + 1624: "Ψ\uf042", + 1625: "™", + 1628: "\uf059\uf0d7\uf0d8", + 1629: "Ы", + 1661: "\uf0f1\uf0f2\uf0f4", + 1665: "\uf054", + 1672: "ш", + 1695: "ω", + 1699: "ю", + 1716: "∝", + 1718: "∞", + 1721: "щ", + 1728: "\uf04a\uf04b\uf04c", + 1739: "\uf04f", + 1748: "æ", + 1781: "₨", + 1788: "\uf0eb\uf0ec\uf0ed\uf0ee", + 1797: "Æ", + 1802: "₥\uf052", + 1804: "Ж", + 1814: "\uf05a", + 1817: "\uf051", + 1825: ( + "\uf029\uf034\uf03b\uf03c\uf03d\uf03e\uf049\uf05b\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7" + "\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0\uf0fd\uf0fe" + ), + 1829: "\uf025", + 1836: "\uf05c", + 1862: "\uf03f\uf040", + 1870: "⅞", + 1872: "©®", + 1876: "¼", + 1878: "ΜМ", + 1884: "⁇", + 1903: "\uf066", + 1909: "♬", + 1911: "\uf063", + 1925: "\uf03a\uf062", + 1929: "\uf045\uf046", + 1931: "⅛", + 1937: "\uf064", + 1940: "\uf038", + 1945: "¾", + 1946: "℉℡⅓⅔↔↕↖↗↘↙⇒⇔∈∋∩∪∬≪≫⊂⊃⊆⊇⊙⊥⌒", + 1950: "½œ", + 1952: "\uf06d\uf0a6", + 1954: "Œ", + 1974: "\uf060", + 1982: "☃", + 1986: "Ш", + 2007: "\uf0df\uf0e0", + 2010: "⅜", + 2012: "⅝", + 2022: "\uf075", + 2047: "Щ", + 2048: ( + "―⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎" + "┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊" + "╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♠♡♣♤♥♧♨\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘" + "㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝" + "㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'" + "()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abc" + "defghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4" + ), + 2097: "\uf065", + 2111: "\uf021", + 2119: "\uf0ff", + 2134: "Ю", + 2145: "\uf0c7\uf0c8\uf0c9\uf0ca", + 2149: "\uf06a", + 2160: "\uf05f", + 2171: "\uf078\uf079\uf0f3", + 2178: "\uf068", + 2186: "\uf0e7\uf0e8", + 2197: "\uf037", + 2208: "\uf039", + 2219: "\uf028", + 2231: "\uf050", + 2234: "\uf061", + 2246: "\uf030\uf067", + 2275: "\uf04d", + 2306: "₧", + 2320: "\uf02a\uf02b", + 2342: "\uf022", + 2347: "№", + 2354: "₯", + 2369: "\uf05e", + 2398: "\uf02c\uf02d", + 2492: "\uf026", + 2566: "\uf0d5\uf0d6", + 2603: "\uf06b", + 2662: "\uf023", + }, + "Segoe UI Symbol": { + 561: "\u202f", + 569: "\u0387", + 621: "❟", + 1024: "❕❗", + 1067: "❠", + 1128: "⚳⚴⚵⚷⚸", + 1401: "⚹⚺⚻⚼", + 1671: "⚝", + 1764: "⚾⛳⛵⛶⛽", + 1847: "⚽", + 1987: "⚶", + 2048: ( + "⚞⚟⚿⛀⛁⛂⛃⛄⛅⛆⛇⛈⛉⛊⛋⛌⛍⛎⛏⛐⛑⛒⛓⛔⛕⛖⛗⛘⛙⛚⛛⛜⛝⛞⛟⛠⛡⛢⛣⛤⛥⛦⛧⛨⛩⛪⛫⛬⛭⛮⛯⛰⛱⛲⛴⛷⛸⛹⛺⛻" + "⛼⛾⛿✀✅✊✋✨❌❎❓❔➕➖➗➰➿" + ), + }, + "Wingdings": { + 641: "\uf09e\uf0a0", + 789: "\uf0fa", + 937: "\uf073\uf09f\uf0a7", + 938: "\uf027", + 987: "\uf0f9", + 1086: "\uf07d\uf07e", + 1124: "\uf047\uf048", + 1135: "\uf035", + 1183: "\uf077", + 1203: "\uf041", + 1233: "\uf036", + 1301: "\uf0fb", + 1332: "\uf053", + 1352: "\uf04e", + 1381: "\uf043\uf044", + 1420: "\uf058", + 1431: "\uf032\uf033", + 1480: "\uf057", + 1529: "\uf055\uf056\uf06c\uf06e\uf074", + 1589: "\uf0e3\uf0e4\uf0e5\uf0e6", + 1597: "\uf069", + 1601: "\uf0f5\uf0f6\uf0f7\uf0f8", + 1609: "\uf0fc", + 1624: "\uf042", + 1627: "\uf059\uf0d7\uf0d8", + 1660: "\uf0f1\uf0f2\uf0f4", + 1665: "\uf054", + 1727: "\uf04a\uf04b\uf04c", + 1739: "\uf04f", + 1787: "\uf0eb\uf0ec\uf0ed\uf0ee", + 1803: "\uf052", + 1813: "\uf05a", + 1819: "\uf051", + 1825: ( + "\uf03b\uf03e\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9" + "\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7\uf0b8\uf0b9" + "\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db" + "\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0" + ), + 1826: ( + "\uf029\uf034\uf03c\uf03d\uf049\uf05b\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087" + "\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0fd\uf0fe" + ), + 1830: "\uf025", + 1834: "\uf05c", + 1863: "\uf03f\uf040", + 1902: "\uf066", + 1911: "\uf063", + 1924: "\uf03a", + 1927: "\uf062", + 1929: "\uf045\uf046", + 1937: "\uf064", + 1941: "\uf038", + 1951: "\uf06d\uf0a6", + 1974: "\uf060", + 2006: "\uf0df\uf0e0", + 2020: "\uf075", + 2048: ( + "\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1" + "\uf0d2\uf0d3\uf0d4" + ), + 2099: "\uf065", + 2110: "\uf021", + 2119: "\uf0ff", + 2146: "\uf0c7\uf0c8\uf0c9\uf0ca", + 2150: "\uf06a", + 2159: "\uf05f", + 2171: "\uf078\uf079\uf0f3", + 2181: "\uf068", + 2186: "\uf0e7\uf0e8", + 2196: "\uf037", + 2208: "\uf039", + 2220: "\uf028", + 2230: "\uf050", + 2233: "\uf061", + 2245: "\uf030\uf067", + 2275: "\uf04d", + 2319: "\uf02a\uf02b", + 2344: "\uf022", + 2368: "\uf05e", + 2399: "\uf02c\uf02d", + 2492: "\uf026", + 2566: "\uf0d5\uf0d6", + 2603: "\uf06b", + 2665: "\uf023", + 2751: "\uf031", + 2752: "\uf024", + 2951: "\uf02e", + 2956: "\uf02f", + }, + "Symbol": { + 342: "\uf0a4", + 410: "\uf07c", + 506: "\uf0a2", + 512: "\uf020\uf02c\uf02e\uf0d7", + 561: "\uf0f2", + 569: "\uf02f\uf03a\uf03b", + 674: "\uf069\uf0e1\uf0f1", + 682: "\uf021\uf028\uf029\uf049\uf05b\uf05d", + 786: "\uf0e6\uf0e7\uf0e8\uf0e9\uf0ea\uf0eb\uf0f6\uf0f7\uf0f8\uf0f9\uf0fa\uf0fb", + 819: "\uf0b0", + 842: "\uf067\uf0b2", + 899: "\uf027\uf056\uf065\uf074", + 909: "\uf03f", + 942: "\uf0b7", + 983: "\uf07b\uf07d", + 1010: "\uf078", + 1012: "\uf064\uf07a\uf0b6\uf0e0\uf0ec\uf0ed\uf0ee\uf0ef\uf0fc\uf0fd\uf0fe", + 1024: "\uf023\uf02a\uf030\uf031\uf032\uf033\uf034\uf035\uf036\uf037\uf038\uf039\uf05f\uf060\uf0a6", + 1067: "\uf066\uf06e\uf071", + 1124: ( + "\uf024\uf02b\uf02d\uf03c\uf03d\uf03e\uf040\uf062\uf063\uf06b\uf06c\uf06f\uf070\uf072\uf07e\uf0a3" + "\uf0b1\uf0b3\uf0b4\uf0b8\uf0b9\uf0ba\uf0bb\uf0d6" + ), + 1139: "\uf052", + 1180: "\uf06d\uf075", + 1212: "\uf053", + 1235: "\uf047\uf068\uf06a\uf073\uf0ad\uf0af\uf0bd\uf0d9\uf0da\uf0dd\uf0df", + 1251: "\uf045\uf054\uf05a", + 1253: "\uf044", + 1270: "\uf0a1", + 1292: "\uf04a\uf061", + 1321: "\uf058", + 1348: "\uf05e\uf0bf", + 1366: "\uf042", + 1405: "\uf04c\uf077\uf079\uf0c1\uf0f3\uf0f4\uf0f5", + 1413: "\uf055", + 1460: "\uf022\uf076\uf0a5\uf0b5\uf0c9\uf0ca\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d1\uf0d8\uf0e5", + 1479: "\uf041\uf043\uf048\uf04b\uf04e\uf04f", + 1518: "\uf051", + 1542: "\uf0a7\uf0a8\uf0a9\uf0aa", + 1563: "\uf046", + 1573: "\uf050\uf057\uf0c4\uf0c5\uf0c7\uf0c8\uf0d0", + 1593: "\uf026", + 1610: "\uf0e4", + 1618: "\uf0d2\uf0d3\uf0e2\uf0e3", + 1628: "\uf059\uf0c2", + 1686: "\uf0c0\uf0c6\uf0d5", + 1706: "\uf025", + 1767: "\uf05c", + 1821: "\uf04d", + 1823: "\uf0d4", + 2021: "\uf0ac\uf0ae\uf0c3\uf0dc\uf0de", + 2048: "\uf0bc\uf0be", + 2134: "\uf0ab\uf0db", + }, + "HY헤드라인M": { + 1: "\u302a\u302b", + 165: "·", + 228: "ι", + 256: "¦", + 276: "‚‛", + 285: "Ι", + 298: "ìíîïįĵĺļ", + 321: "\uf09e\uf0a0", + 360: "ĩīĭ", + 374: "г", + 379: "„‟", + 384: "¯ÌÍÎÏĨĪĬĮİţſ", + 393: "ľ", + 395: "\uf0fa", + 406: "τ", + 426: "ŕŗř", + 448: "к", + 452: "ζ", + 457: "ε", + 459: "ξ", + 469: "Ĵт\uf027\uf073\uf09f\uf0a7", + 470: "з", + 481: "źżž", + 495: "\uf0f9", + 496: "ť", + 512: ( + "«»àáâãäåāăąćĉċčśŝşšγκλνсух・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニ" + "ヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚ᅠ\uf07f" + ), + 523: "э", + 532: "ç", + 534: "чь", + 538: "χ", + 544: "в\uf07d\uf07e", + 554: "µèéêëñòóôõöùúûüēĕėęěĝğġģĥķńņňōŏőũūŭůűų", + 555: "Гпя", + 560: "υ", + 563: "\uf047\uf048", + 564: "Γ", + 566: "н", + 568: "\uf035", + 570: "δηθοаеорё", + 572: "ий", + 583: "ρ", + 587: "бц", + 589: "β", + 590: "μ", + 592: "α\uf077", + 597: "ýÿŷК", + 598: "дл", + 602: "\uf041", + 618: "\uf036", + 619: "З", + 626: "ΖΤТ", + 632: "σ", + 633: "Σ", + 640: "ĹĻĽŚŜŞŠъ", + 651: "У", + 652: "\uf0fb", + 664: "φ", + 666: "Ξ", + 667: "\uf053", + 672: "БЛЬ", + 676: "\uf04e", + 682: "ÈÉÊËÝĆĈĊČĒĔĖĘĚŔŖŘŶŸ", + 683: "ΑΒΕΚΡΥΧАВЕРХЧ", + 684: "ΔΛЁ", + 685: "ж", + 690: "Ç", + 691: "\uf043\uf044", + 693: "ď", + 694: "Д", + 705: "м", + 707: "π", + 710: "\uf058", + 717: "\uf032\uf033", + 725: "ÒÓÔÕÖĎĐĜĞĠĢŌŎŐ", + 730: "ψ", + 736: "ИЙПЭы", + 740: "ΗΝΠНСЯ", + 741: "\uf057", + 758: "Ц", + 765: "\uf055\uf056\uf06c\uf06e\uf074", + 766: "Ω", + 768: "ÀÁÂÃÄÅÑÙÚÛÜĀĂĄĤĶŃŅŇŢŤŨŪŬŮŰŲю", + 779: "Ф", + 795: "\uf0e3\uf0e4\uf0e5\uf0e6", + 797: "ΘΟО", + 799: "\uf069", + 800: "ω", + 802: "©\uf0f5\uf0f6\uf0f7\uf0f8", + 806: "\uf0fc", + 810: "ŵ", + 811: "Ъ", + 812: "\uf042", + 814: "\uf059\uf0d7\uf0d8", + 817: "Φ", + 822: "ш", + 831: "\uf0f1\uf0f2\uf0f4", + 833: "\uf054", + 843: "фщ", + 853: "ΜМ", + 856: "Ψ", + 864: "\uf04a\uf04b\uf04c", + 870: "\uf04f", + 894: "\uf0eb\uf0ec\uf0ed\uf0ee", + 901: "\uf052", + 907: "Ы\uf05a", + 911: "\uf051", + 913: ( + "\uf029\uf034\uf03b\uf03c\uf03d\uf03e\uf049\uf05b\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7" + "\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0\uf0fd\uf0fe" + ), + 915: "\uf025", + 918: "\uf05c", + 933: "\uf03f\uf040", + 939: "Ш", + 946: "Ж", + 952: "\uf066", + 956: "\uf063", + 960: "Щ", + 963: "\uf03a\uf062", + 966: "\uf045\uf046", + 970: "\uf038\uf064", + 976: "\uf06d\uf0a6", + 981: "Ŵ", + 987: "\uf060", + 1004: "\uf0df\uf0e0", + 1011: "\uf075", + 1024: ( + "¡¢£¤¥§¨ª¬\u00ad®²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝―‖†‡" + "‥′″‾⁴ⁿ₁₂₃₄₩€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡" + "≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦ" + "ⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀" + "╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◉◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃々〆【】〒〓〔〕〜" + "〞〟㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿" + "㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾" + "㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGH" + "IJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + "\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4" + ), + 1035: "Ю", + 1050: "\uf065", + 1056: "\uf021", + 1061: "\uf0ff", + 1073: "\uf0c7\uf0c8\uf0c9\uf0ca", + 1075: "\uf06a", + 1080: "\uf05f", + 1086: "\uf078\uf079\uf0f3", + 1091: "\uf068", + 1093: "\uf0e7\uf0e8", + 1099: "\uf037", + 1104: "\uf039", + 1110: "\uf028", + 1116: "\uf050", + 1117: "\uf061", + 1123: "\uf030\uf067", + 1138: "\uf04d", + 1160: "\uf02a\uf02b", + 1171: "\uf022", + 1184: "\uf05e", + 1201: "\uf02c\uf02d", + 1246: "\uf026", + 1283: "\uf0d5\uf0d6", + 1302: "\uf06b", + 1333: "\uf023", + }, + "휴먼명조": { + 1: "\u302a\u302b", + 164: "·", + 228: "ι", + 256: "¦", + 276: "‚‛", + 284: "Ι", + 296: "⁚", + 298: "ìíîïįĵĺļ", + 321: "\uf09e\uf0a0", + 360: "ĩīĭ", + 374: "г", + 380: "„‟", + 384: "¯ÌÍÎÏĨĪĬĮİţſ", + 393: "\uf0fa", + 394: "ľ", + 404: "τ", + 426: "ŕŗř", + 448: "к", + 452: "ζ", + 456: "ε", + 458: "ξ", + 467: "\uf073\uf09f\uf0a7", + 470: "Ĵзт", + 471: "\uf027", + 482: "źżž", + 486: "‶", + 495: "\uf0f9", + 496: "ť", + 512: ( + "¢£«»àáâãäåāăąćĉċčśŝşšγκλνсух・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテト" + "ナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚ᅠ\uf07f" + ), + 522: "э", + 532: "ç", + 534: "чь", + 538: "χ", + 544: "в\uf07d\uf07e", + 550: "⁖", + 554: "µèéêëñòóôõöùúûüēĕėęěĝğġģĥķńņňōŏőũūŭůűųГпя", + 560: "υ", + 563: "\uf047\uf048", + 564: "Γ", + 566: "н", + 568: "\uf035", + 570: "δηθοаеорё", + 572: "ий⁕", + 582: "ρ", + 586: "бц", + 590: "βμ", + 592: "α\uf077", + 596: "К", + 598: "ýÿŷдл", + 602: "\uf041", + 615: "\uf036", + 618: "З", + 620: "₲", + 626: "ΖΤТ", + 632: "σ", + 634: "Σ", + 640: "ĹĻĽŚŜŞŠъ", + 650: "У⁉\uf0fb", + 664: "φ", + 666: "Ξ", + 667: "\uf053", + 672: "БЛЬ", + 676: "\uf04e", + 682: "¥ÈÉÊËÝĆĈĊČĒĔĖĘĚŔŖŘŶŸЧ", + 684: "ΑΒΔΕΚΛΡΥΧЁАВЕРХ", + 686: "ж", + 689: "\uf043\uf044", + 690: "Ç", + 694: "ďД", + 704: "м", + 706: "π", + 710: "\uf058", + 717: "\uf032\uf033", + 726: "ÒÓÔÕÖĎĐĜĞĠĢŌŎŐ", + 730: "ψ", + 736: "ИЙПЭы", + 740: "ΗΝΠНСЯ", + 741: "\uf057", + 758: "Ц", + 765: "\uf055\uf056\uf06c\uf06e\uf074", + 766: "Ω", + 768: "ÀÁÂÃÄÅÑÙÚÛÜĀĂĄĤĶŃŅŇŢŤŨŪŬŮŰŲю", + 778: "Ф", + 795: "\uf0e3\uf0e4\uf0e5\uf0e6", + 796: "ΘΟО", + 799: "\uf069\uf0f5\uf0f6\uf0f7\uf0f8", + 800: "ω", + 802: "©®", + 804: "¬\uf0fc", + 810: "ŵЪ", + 812: "\uf042", + 814: "₩\uf059\uf0d7\uf0d8", + 818: "Φ", + 822: "ш", + 830: "₨", + 831: "\uf0f1\uf0f2\uf0f4", + 833: "\uf054", + 842: "фщ", + 854: "ΜМ", + 856: "Ψ", + 864: "\uf04a\uf04b\uf04c", + 870: "\uf04f", + 894: "\uf0eb\uf0ec\uf0ed\uf0ee", + 900: "⁇", + 901: "\uf052", + 905: "\uf05a", + 906: "Ы", + 911: "\uf051", + 913: "\uf03b\uf03e\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0", + 915: "\uf029\uf034\uf03c\uf03d\uf049\uf05b\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0fd\uf0fe", + 916: "\uf025", + 918: "\uf05c", + 933: "\uf03f\uf040", + 938: "Ш", + 946: "Ж", + 952: "\uf066", + 956: "\uf063", + 960: "Щ", + 963: "\uf03a\uf045\uf046\uf062", + 968: "\uf064", + 970: "\uf038", + 976: "\uf06d\uf0a6", + 982: "Ŵ", + 987: "\uf060", + 994: ( + "₯∁∄∅∆∉∊∌∍∎∐−∓∔∕∖∗∘∙∛∜∟∡∢∣∤∦∭∯∰∱∲∳∶∷∸∹∺∻∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≓" + "≔≕≖≗≘≙≚≛≜≝≞≟≢≣≦≧≨≩≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊄⊅⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊚" + "⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗" + "⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿▢▪▫▬▭▮▯▰▱▴▵▸▹►▻▾▿◂◃◄" + "◅◉◊◌◍◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷◸◹◺◻◼◽◾◿☀☁☂☃☄☇☈☉☊" + "☋☌☍☐☑☒☓☔☕☖☗☘☙☚☛☝☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♁♃♄♅♆♇♈♉♊♋♌" + "♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♢♦♫♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚇⚈⚉⚊⚋⚌⚍⚎⚏⚐⚑⚒⚓" + "⚔⚕⚖⚗⚘⚙⚚⚛⚜⚠⚡⚢⚣⚤⚥⚦⚧⚨⚩⚪⚫⚬⚭⚮⚯⚰⚱⚲✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣" + "✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❙❚❛❜❝❞❡❢❣❤❥❦❧❨" + "❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧" + "➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻➼➽➾〄〇〜〝〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾⦅⦆¦" + ), + 1004: "\uf0df\uf0e0", + 1011: "\uf075", + 1024: ( + "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝―†‡‥′″⁴ⁿ₁" + "₂₃₄℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙" + "⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍" + "┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉" + "╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃々〆【】〒〓〔〕〞〟㈀㈁㈂㈃㈄㈅㈆㈇㈈" + "㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍" + "㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉" + "㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRS" + "TUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc" + "\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4" + ), + 1034: "Ю", + 1050: "\uf065", + 1056: "\uf021", + 1061: "\uf0ff", + 1075: "\uf0c7\uf0c8\uf0c9\uf0ca", + 1076: "\uf06a", + 1080: "\uf05f", + 1086: "\uf078\uf079\uf0f3", + 1089: "\uf068", + 1095: "\uf0e7\uf0e8", + 1099: "\uf037", + 1104: "\uf039", + 1110: "\uf028", + 1116: "\uf050\uf061", + 1123: "\uf030\uf067", + 1138: "\uf04d", + 1160: "\uf02a\uf02b", + 1171: "\uf022", + 1184: "\uf05e", + 1201: "\uf02c\uf02d", + 1246: "\uf026", + 1283: "\uf0d5\uf0d6", + 1302: "\uf06b", + 1331: "\uf023", + }, + "한컴산뜻돋움": { + 161: "·", + 254: "ι", + 260: "²³¹", + 264: "\u00a0", + 300: "´", + 313: "\uf09e\uf0a0", + 317: "Ι", + 378: "ª", + 385: "º\uf0fa", + 436: "⁑", + 446: "¡§¸", + 448: "υ", + 458: "\uf027\uf073\uf09f\uf0a7", + 461: "г", + 473: "ν", + 477: "ψ", + 478: "\u00ad", + 483: "\uf0f9", + 486: "ː˛′″⁴ⁿ₁₂₃₄∂、。【】〔〕", + 490: "сэ", + 500: "\uf07f", + 501: "σ", + 507: "б", + 510: "т", + 525: "κ", + 528: "х", + 529: "ε", + 530: "у", + 531: "\uf07d\uf07e", + 532: "з", + 536: "ь", + 539: "к", + 540: "д", + 547: "γа", + 549: "β\uf047\uf048", + 552: "ρ", + 554: "\uf035", + 556: "θ", + 559: "её", + 560: "δ", + 566: "вя", + 568: "У", + 572: "Τ", + 575: "μ", + 577: "о", + 578: "\uf077", + 581: "Υ", + 582: "ο", + 584: "Ζ", + 586: "Рж•", + 587: "Г\uf041", + 588: "ζр", + 593: "λτ", + 595: "αη", + 596: "ЁЕъ", + 597: "ч", + 600: "Λ", + 603: "\uf036", + 606: "З", + 607: "Χпц", + 608: "ξ", + 609: "Γ", + 617: "Хийн", + 618: "л", + 620: "Σ", + 621: "Т", + 622: "Б", + 624: "ΞΦ", + 625: "Ε", + 627: "ВЬ", + 628: "К", + 636: "\uf0fb", + 637: "ω", + 639: "СЭ", + 644: "А", + 645: "Я", + 650: "Ωπ", + 651: "\uf053", + 653: "ΑΔ", + 656: "φ", + 657: "Ψχ", + 660: "Ρ\uf04e", + 664: "ΒΚ", + 666: "Π", + 667: "Ъф", + 669: "¿", + 672: "―", + 674: "\uf043\uf044", + 676: "ΘΟ", + 680: "€", + 688: "ПЧ", + 689: "Д", + 690: "Ц", + 693: "\uf058", + 694: "Η", + 695: "ы", + 697: "Л", + 700: "\uf032\uf033", + 710: "ИЙ", + 718: "Н", + 723: "\uf057", + 728: "Ν", + 730: "м", + 742: "ю", + 747: "\uf055\uf056\uf06c\uf06e\uf074", + 752: "ЖО", + 755: "шщ", + 761: "Ф", + 776: "\uf0e3\uf0e4\uf0e5\uf0e6", + 780: "\uf069", + 783: "\uf0f5\uf0f6\uf0f7\uf0f8", + 787: "\uf0fc", + 793: "\uf042", + 794: "\uf059\uf0d7\uf0d8", + 800: "¨¶øþ", + 807: "Ю", + 811: "\uf0f1\uf0f2\uf0f4", + 813: "\uf054", + 819: "Ы", + 826: "Μ", + 843: "\uf04a\uf04b\uf04c", + 849: "\uf04f", + 873: "\uf0eb\uf0ec\uf0ed\uf0ee", + 880: "\uf052", + 884: "М", + 885: "\uf05a", + 887: "\uf051", + 891: "\uf03b\uf03e\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0", + 892: "¤©®¼½¾ÆÐØÞßæðŒœ†‡™", + 893: "\uf029\uf034\uf03c\uf03d\uf049\uf05b\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0fd\uf0fe", + 894: "\uf025", + 896: "\uf05c", + 904: "ШЩ", + 911: "\uf03f\uf040", + 929: "\uf066", + 932: ( + "đĦħıIJijĸĿŀŁłʼnŊŋŦŧˇ˘˙˚˝‥℉ℓ№℡ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬" + "∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞ" + "ⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸" + "┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000〃〓㈀㈁㈂" + "㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄" + "㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃" + "㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLM" + "NOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + 933: "\uf063", + 940: "\uf03a\uf062", + 943: "\uf045\uf046", + 947: "\uf038\uf064", + 953: "\uf06d\uf0a6", + 963: "\uf060", + 970: "◉◯☐☑❍", + 980: "\uf0df\uf0e0", + 987: "\uf075", + 1000: "\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4", + 1025: "\uf065", + 1031: "\uf021", + 1036: "\uf0ff", + 1047: "\uf0c7\uf0c8\uf0c9\uf0ca", + 1051: "\uf06a", + 1054: "\uf05f", + 1060: "\uf078\uf079\uf0f3", + 1065: "\uf068", + 1067: "\uf0e7\uf0e8", + 1073: "\uf037", + 1078: "\uf039", + 1083: "\uf028", + 1089: "\uf050", + 1091: "\uf061", + 1096: "\uf030\uf067", + 1111: "\uf04d", + 1133: "\uf02a\uf02b", + 1145: "\uf022", + 1156: "\uf05e", + 1171: "\uf02c\uf02d", + 1216: "\uf026", + 1253: "\uf0d5\uf0d6", + 1271: "\uf06b", + 1300: "\uf023", + }, + "휴먼고딕": { + 1: "\u302a\u302b", + 164: "\u0387", + 228: "ι", + 256: "¦", + 276: "‚‛", + 284: "Ι", + 296: "․‧⁚", + 298: "ìíîïįĵĺļ⁏⁝⁞", + 344: "‖‵", + 360: "ĩīĭ", + 374: "г", + 378: "‣", + 380: "„‟", + 384: "¯ÌÍÎÏĨĪĬĮİţſ", + 394: "ľ", + 404: "τ", + 406: "‹›", + 408: "•", + 426: "ŕŗř", + 448: "к", + 452: "ζ", + 456: "ε", + 458: "ξ‼", + 466: "⁃", + 470: "Ĵзт", + 482: "źżž", + 484: "⁅⁆", + 486: "‶", + 492: "‽", + 496: ( + "ť〿。「」、ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑" + "→↓■○" + ), + 498: "⁎⁑", + 512: ( + "¢£«»àáâãäåāăąćĉċčśŝşšγκλνсух〖〗〘〙〚〛・ヲァィゥェォャュョッーアイウエオカキクケコサシスセ" + "ソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚ᅠ" + ), + 522: "э", + 524: "₫", + 530: "₰", + 532: "ç", + 534: "чь", + 538: "χ‸", + 540: "‐‑", + 544: "в⁊", + 550: "⁖", + 554: "µèéêëñòóôõöùúûüēĕėęěĝğġģĥķńņňōŏőũūŭůűųГпя", + 560: "υ", + 564: "Γ", + 566: "н", + 568: "⁒", + 570: "δηθοаеорё", + 572: "ий⁕", + 582: "ρ", + 584: "₤", + 586: "бц⁗", + 590: "βμ", + 592: "α‗", + 596: "К", + 598: "ýÿŷдл", + 608: "‾", + 610: "₦", + 616: "₠₪", + 618: "З⁙", + 620: "₲", + 622: "‴‷₵", + 626: "ΖΤТ", + 628: "₴", + 632: "σ", + 634: "Σ", + 638: "⁈⁘", + 640: "ĹĻĽŚŜŞŠŹŻŽъ‒", + 648: "₣", + 650: "У⁄⁉", + 652: "₱", + 662: "⁋⁌⁍", + 664: "φ", + 666: "Ξ₭", + 670: "₮", + 672: "БЛЬ€", + 680: "₥", + 682: "¥ÈÉÊËÝĆĈĊČĒĔĖĘĚŔŖŘŶŸЧ⁁₡₢", + 684: "ΑΒΔΕΚΛΡΥΧЁАВЕРХ", + 686: "ж", + 690: "Ç", + 694: "ďД", + 700: "⁛", + 704: "м⁓", + 706: "π", + 726: "ÒÓÔÕÖĎĐĜĞĠĢŌŎŐ", + 730: "ψ", + 736: "ИЙПЭы", + 740: "ΗΝΠНСЯ", + 758: "Ц", + 766: "Ω", + 768: "ÀÁÂÃÄÅÑÙÚÛÜĀĂĄĤĶŃŅŇŢŤŨŪŬŮŰŲю", + 778: "Ф", + 788: "‿⁀⁔⁜₳", + 796: "ΘΟО", + 800: "ω", + 802: "©®", + 804: "¬", + 810: "ŵЪ", + 814: "₩", + 818: "Φ⁐", + 822: "ш", + 830: "₨", + 842: "фщ", + 854: "ΜМ", + 856: "Ψ", + 900: "⁇", + 906: "Ы", + 930: "⁂", + 938: "Ш", + 946: "Ж", + 960: "Щ", + 978: "‱", + 980: "₧", + 982: "Ŵ", + 994: ( + "₯∁∄∅∆∉∊∌∍∎∐−∓∔∕∖∗∘∙∛∜∟∡∢∣∤∦∭∯∰∱∲∳∶∷∸∹∺∻∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≓" + "≔≕≖≗≘≙≚≛≜≝≞≟≢≣≦≧≨≩≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊄⊅⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊚" + "⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗" + "⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿▢▪▫▬▭▮▯▰▱▴▵▸▹►▻▾▿◂◃◄" + "◅◉◊◌◍◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷◸◹◺◻◼◽◾◿☀☁☂☃☄☇☈☉☊" + "☋☌☍☐☑☒☓☔☕☖☗☘☙☚☛☝☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♁♃♄♅♆♇♈♉♊♋♌" + "♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♢♦♫♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚇⚈⚉⚊⚋⚌⚍⚎⚏⚐⚑⚒⚓" + "⚔⚕⚖⚗⚘⚙⚚⚛⚜⚠⚡⚢⚣⚤⚥⚦⚧⚨⚩⚪⚫⚬⚭⚮⚯⚰⚱⚲✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣" + "✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❙❚❛❜❝❞❡❢❣❤❥❦❧❨" + "❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧" + "➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻➼➽➾〄〇〜〝〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾⦅⦆¦" + ), + 1024: ( + "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝―†‡‥′″⁴ⁿ₁" + "₂₃₄℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙" + "⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍" + "┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉" + "╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍" + "㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒" + "㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖" + "㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" + "YZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + 1034: "Ю", + }, + "한컴돋움": { + 218: "⁏", + 232: "⁚⁝⁞", + 235: "ìíïįı", + 236: "ĺļ", + 241: "ī", + 256: "¦îĵ", + 265: "ÌÍÏĪĬĮİ", + 268: "ł", + 270: "ĭ", + 297: "Î", + 298: "Ĩĩ‚‛", + 311: "❟", + 320: "ľŀ", + 321: "ţŧ", + 328: "ŕŗř", + 329: "²³", + 341: "´¸", + 352: "ſ", + 384: "¹º", + 413: "ª", + 425: "¡", + 427: "ť⁎", + 469: "„‟", + 475: "⁖", + 488: "⚬", + 492: "ýŷźżž", + 496: "Ĵ", + 512: "\u00a0¨«\u00ad¯»¼½¾ÿij\u202f・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚ᅠ", + 522: "ķĸ", + 527: "śŝşš", + 533: "⁙", + 546: "⚘", + 553: "ĹĻĽĿ", + 564: "⚨⚲", + 573: "¢çèéêëēĕėęĥħ", + 574: "£¤§¶", + 582: "ñùúûüńņňʼnŋũūŭůűų", + 587: "Ł", + 590: "⚚", + 597: "µ¿àáâãäåāăąćĉċčěŢŤŦ", + 613: "ğġģ", + 614: "ÝðòóôõöøþōŏőŶŸ", + 619: "ŹŻŽ", + 640: "¥ßđĝ", + 644: "ÈÉÊËĒĔĖĘĚ", + 655: "ŚŜŞŠ", + 657: "⁘⁛", + 668: "⁗", + 671: "Ķ", + 675: "⚭", + 681: "ÀÁÂÃÄÅÞĀĂĄ", + 684: "ŔŖŘ", + 697: "⁕", + 701: "⚹⚺⚻⚼", + 711: "⚥⚦", + 712: "ÑŃŅŇŊ", + 720: "¬", + 737: "ĆĈĊČ⚐⚑", + 741: "ĤĦ", + 742: "ÐÙÚÛÜďŨŪŬŮŰŲŵ", + 768: "ÇÒÓÔÕÖØĎĜĞĠĢIJŌŎŐ", + 769: "Đ", + 802: "©®", + 815: "⁔", + 819: "⚢", + 822: "⁓", + 830: "æ", + 853: "⁇", + 864: "⚩", + 882: "◸◹◺◿", + 895: "⚣⚤", + 896: "œ", + 915: "Ŵ", + 920: "⚊⚋⚌⚍⚎⚏", + 954: "⚮", + 957: "Œ", + 958: "Æ", + 994: "⚶", + 1024: "⁜々〆〒〓〞〟", + 1116: "⚯", + 1406: "◻◼◽◾☔☕☘♾♿⚒⚓⚔⚕⚖⚗⚙⚛⚜⚠⚡⚧⚪⚫⚰⚱⚽⚾⛄⛅⛈⛎⛏⛑⛓⛔⛩⛪⛰⛱⛲⛳⛴⛵⛷⛸⛹⛺⛽✅✊✋✨❌❎❓❔❕❗➕➖➗➰➿", + }, + "HY울릉도M": { + 165: "\u0387", + 512: ( + "\u00a0¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöù" + "úûüýÿ" + ), + 1024: ( + "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘΙ" + "ΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТУ" + "ФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄℉ℓ№" + "℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟" + "⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓" + "└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥" + "▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓" + "㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘" + "㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"" + "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^" + "_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + }, + "HY울릉도B": { + 512: ( + "\u00a0¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöù" + "úûüýÿ" + ), + 1024: ( + "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘΙ" + "ΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТУ" + "ФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄℉ℓ№" + "℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟" + "⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓" + "└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥" + "▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖" + "㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛" + "㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%" + "&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a" + "bcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + }, + "HY중고딕": { + 165: "·", + 321: "\uf09e\uf0a0", + 395: "\uf0fa", + 469: "\uf027\uf073\uf09f\uf0a7", + 495: "\uf0f9", + 512: ( + "\u00a0¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöù" + "úûüýÿ\uf07f" + ), + 544: "\uf07d\uf07e", + 563: "\uf047\uf048", + 568: "\uf035", + 592: "\uf077", + 602: "\uf041", + 618: "\uf036", + 652: "\uf0fb", + 667: "\uf053", + 676: "\uf04e", + 691: "\uf043\uf044", + 710: "\uf058", + 717: "\uf032\uf033", + 741: "\uf057", + 765: "\uf055\uf056\uf06c\uf06e\uf074", + 795: "\uf0e3\uf0e4\uf0e5\uf0e6", + 799: "\uf069", + 802: "\uf0f5\uf0f6\uf0f7\uf0f8", + 806: "\uf0fc", + 812: "\uf042", + 814: "\uf059\uf0d7\uf0d8", + 831: "\uf0f1\uf0f2\uf0f4", + 833: "\uf054", + 864: "\uf04a\uf04b\uf04c", + 870: "\uf04f", + 894: "\uf0eb\uf0ec\uf0ed\uf0ee", + 901: "\uf052", + 907: "\uf05a", + 911: "\uf051", + 913: ( + "\uf029\uf034\uf03b\uf03c\uf03d\uf03e\uf049\uf05b\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7" + "\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0\uf0fd\uf0fe" + ), + 915: "\uf025", + 918: "\uf05c", + 933: "\uf03f\uf040", + 952: "\uf066", + 956: "\uf063", + 963: "\uf03a\uf062", + 966: "\uf045\uf046", + 970: "\uf038\uf064", + 976: "\uf06d\uf0a6", + 987: "\uf060", + 1004: "\uf0df\uf0e0", + 1011: "\uf075", + 1024: ( + "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘΙ" + "ΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТУ" + "ФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄℉ℓ№" + "℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟" + "⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓" + "└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥" + "▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓" + "㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘" + "㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"" + "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^" + "_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4" + ), + 1050: "\uf065", + 1056: "\uf021", + 1061: "\uf0ff", + 1073: "\uf0c7\uf0c8\uf0c9\uf0ca", + 1075: "\uf06a", + 1080: "\uf05f", + 1086: "\uf078\uf079\uf0f3", + 1091: "\uf068", + 1093: "\uf0e7\uf0e8", + 1099: "\uf037", + 1104: "\uf039", + 1110: "\uf028", + 1116: "\uf050", + 1117: "\uf061", + 1123: "\uf030\uf067", + 1138: "\uf04d", + 1160: "\uf02a\uf02b", + 1171: "\uf022", + 1184: "\uf05e", + 1201: "\uf02c\uf02d", + 1246: "\uf026", + 1283: "\uf0d5\uf0d6", + 1302: "\uf06b", + 1333: "\uf023", + }, + "HY견고딕": { + 165: "\u0387", + 512: ( + "\u00a0¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöù" + "úûüýÿ" + ), + 1024: ( + "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘΙ" + "ΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТУ" + "ФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄℉ℓ№" + "℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟" + "⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓" + "└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥" + "▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓" + "㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘" + "㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"" + "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^" + "_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + }, + "HY신명조": { + 165: "\u0387", + 512: ( + "\u00a0¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöù" + "úûüýÿ" + ), + 1024: ( + "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘΙ" + "ΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТУ" + "ФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄℉ℓ№" + "℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟" + "⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓" + "└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥" + "▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓" + "㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘" + "㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"" + "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^" + "_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + }, + "HY태백B": { + 228: 'ι', + 276: '‚‛', + 285: 'Ι', + 294: 'Ϊ', + 296: '․‧', + 298: 'įĵĺļ', + 328: '⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉', + 343: '‖‵', + 346: 'ί', + 360: 'ĩīĭ', + 378: '‣', + 379: '„‟', + 384: 'ĨĪĬĮİţſ', + 393: 'ľ', + 405: 'τ', + 406: '‹›', + 409: '•', + 426: 'ŕŗř', + 452: 'ζ', + 457: 'ε', + 458: '‼', + 459: 'ξ', + 469: 'Ĵ', + 481: 'źżž', + 496: 'ť', + 512: '\xa0¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöùúûüýÿāăąćĉċčśŝşšγκλν', + 513: 'ς', + 538: 'χ', + 541: '‐‑', + 554: 'ēĕėęěĝğġģĥķńņňōŏőũūŭůűų', + 560: 'υ', + 564: 'Γ', + 570: 'δηθο', + 577: 'έ', + 583: 'ρ', + 588: 'fi', + 589: 'β', + 590: 'μ', + 592: 'α', + 593: '‗', + 597: 'ŷ', + 603: 'fl', + 604: 'ή', + 605: 'ΰ', + 608: '‾', + 623: '‴', + 626: 'ΖΤ', + 632: 'σ', + 633: 'Σ', + 640: 'ĹĻĽŚŜŞŠŹŻŽ‒', + 650: '⁄', + 664: 'φ', + 666: 'Ξ', + 672: '€', + 682: 'ĆĈĊČĒĔĖĘĚŔŖŘŶŸ', + 683: 'ΑΒΕΚΡΥΧ', + 684: 'ΔΛά', + 693: 'ď', + 707: 'π', + 720: 'Ϋ', + 725: 'ĎĐĜĞĠĢŌŎŐ', + 730: 'ψ', + 740: 'ΗΝΠ', + 766: 'Ω', + 768: 'ĀĂĄĤĶŃŅŇŢŤŨŪŬŮŰŲ', + 797: 'ΘΟ', + 800: 'ω', + 810: 'ŵ', + 813: '₩', + 817: 'Φ', + 853: 'Μ', + 856: 'Ψ', + 979: '‱', + 981: 'Ŵ', + 993: '℮−∕∙≈◊', + 1024: '¡¤§¨ª\xad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩', + }, + "HY그래픽": { + 512: ( + "\u00a0¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöù" + "úûüýÿ" + ), + 1024: ( + "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘΙ" + "ΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТУ" + "ФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄℉ℓ№" + "℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟" + "⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓" + "└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥" + "▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓" + "㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘" + "㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"" + "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^" + "_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + }, + "한컴바탕": { + 165: "\u0387", + 166: "˙", + 178: "․‧", + 224: "ː˚", + 229: "⁃", + 256: "¦", + 267: "‐", + 276: "˛‚‛′‵", + 298: "ìíîïįıĵĺļł", + 328: "⁅⁆", + 332: "‹›", + 336: "˘", + 341: "´¸‖", + 360: "ĩīĭ", + 363: "˝", + 365: "⁁", + 368: "²³", + 369: "‑", + 377: "ŀ", + 379: "„‟", + 384: "\u00ad¯¹ÌÍÎÏĨĪĬĮİţŧſΙ", + 393: "ľ", + 404: "‸", + 408: "ι", + 425: "ˇ", + 426: "¡ŕŗř", + 430: "з", + 441: "‒", + 445: "а", + 447: "″", + 451: "г", + 452: "‼", + 461: "ε", + 465: "ь", + 467: "⁊", + 469: "Ĵ", + 471: "сэ⁴ⁿ₁₂₃₄", + 474: "•", + 477: "‣", + 480: "ªº", + 481: "źżž", + 485: "в‶", + 492: "её†‡‽⁑⁒", + 493: "я", + 496: "ť", + 502: "ζξт", + 512: ( + "\u00a0¢£¤§¨«»¿àáâãäåāăąćĉċčśŝşš\u202f⁇⁎⁏⁓⁔⁕⁖⁗⁘⁙⁚⁛⁜⁝⁞\u205f∘∙\u3000⦅⦆。「」、・ヲァィゥェォャ" + "ュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚ᅠᄀᄁᆪᄂᆬᆭᄃᄄ" + "ᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑→↓■○" + ), + 516: "ко", + 521: "χ", + 523: "б", + 527: "Злч", + 532: "ç", + 534: "ρъ", + 538: "ijτ", + 542: "р", + 543: "υ", + 547: "у", + 549: "д", + 550: "п", + 553: "αх", + 554: "µèéêëðñòóôõöøùúûüþēĕėęěĝğġģĥħķĸńņňŋōŏőũūŭůűųδκνοσ", + 561: "‗", + 562: "đ", + 565: "‴‷", + 573: "ийнц", + 574: "γ", + 575: "¼½¾", + 577: "Р", + 579: "π", + 580: "‥", + 585: "μ", + 594: "ηЬ", + 597: "ýÿŷ", + 600: "φ", + 604: "БГ", + 616: "Ξ", + 625: "Γ", + 628: "ЁЕ", + 636: "Т", + 638: "θ", + 640: "¶ßĹĻĽŁŚŜŞŠŹŻŽΖΡλω⁋⁌⁍", + 641: "ф‾", + 655: "м", + 670: "βВ", + 674: "Δ", + 677: "СЭ", + 682: "¥ÈÉÊËÝÞĆĈĊČĒĔĖĘĚŔŖŘŶŸΒΕΥΧ", + 683: "ʼn", + 690: "Ç€", + 693: "ďы", + 707: "ψКЧЯ", + 708: "Л", + 715: "Ъ", + 717: "Π", + 725: "ÐÒÓÔÕÖØĎĐĜĞĠĢŌŎŐΘΟ", + 734: "ж", + 736: "Д", + 738: "У", + 742: "Ω", + 743: "О", + 752: "⁄", + 753: "ĿΦ", + 757: "Х", + 759: "IJΨ", + 768: "ÀÁÂÃÄÅÑÙÚÛÜĀĂĄĤĦĶŃŅŇŊŢŤŦŨŪŬŮŰŲΑΗΚΛΝΤАИЙНПЦю", + 788: "Ф", + 790: "шщ", + 800: "Σ", + 802: "©®", + 804: "¬", + 810: "ŵ", + 817: "⁈⁉", + 823: "‿⁀⁐", + 849: "œ", + 865: "æ", + 903: "Ы", + 918: "М", + 938: "Μ", + 940: "Œ", + 962: "Ж", + 981: "Ŵ", + 1024: ( + "ÆШЩЮ―‱⁂℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∊∋∌∍∎∏∐∑−∓∔∕∖∗√∛∜∝∞∟∠∡" + "∢∣∤∥∦∧∨∩∪∫∬∭∮∯∰∱∲∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝" + "≞≟≠≡≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙" + "⊚⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕" + "⋖⋗⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬" + "⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠" + "┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱" + "▴▵▶▷▸▹►▻▼▽▾▿◀◁◂◃◄◅◈◉◊◌◍◎◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳" + "◴◵◶◷◸◹◺◻◼◽◾◿☀☁☂☃☄☇☈☉☊☋☌☍☎☏☐☑☒☓☔☕☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱" + "☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭" + "♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚇⚈⚉⚊⚋⚌⚍⚎⚏⚐⚑⚒⚓⚔⚕⚖⚗⚘⚙⚚⚛⚜⚝⚞⚟⚠⚡⚢⚣⚤⚥⚦⚧⚨⚩" + "⚪⚫⚬⚭⚮⚯⚰⚱⚲⚳⚴⚵⚶⚷⚸⚹⚺⚻⚼⚽⚾⚿⛀⛁⛂⛃⛄⛅⛆⛇⛈⛉⛊⛋⛌⛍⛎⛏⛐⛑⛒⛓⛔⛕⛖⛗⛘⛙⛚⛛⛜⛝⛞⛟⛠⛡⛢⛣⛤⛥" + "⛦⛧⛨⛩⛪⛫⛬⛭⛮⛯⛰⛱⛲⛳⛴⛵⛶⛷⛸⛹⛺⛻⛼⛽⛾⛿✀✁✂✃✄✅✆✇✈✉✊✋✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡" + "✢✣✤✥✦✧✨✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝" + "❞❟❠❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➕➖➗➘➙" + "➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➰➱➲➳➴➵➶➷➸➹➺➻➼➽➾➿、。〃〄々〆〇【】〒〓〔〕〖〗〘〙〚〛〜〝〞" + "〟〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾〿㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣" + "㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥" + "㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./" + "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijk" + "lmnopqrstuvwxyz{|}~¢£¬ ̄¦¥₩" + ), + }, + "한컴 윤고딕 230": { + 275: "ː", + 280: "′", + 308: "ÌÍÎÏìíîïĬĭĮįİıĺļ", + 318: "ĵ", + 326: "ſ", + 330: "〔〕", + 340: "´¸˘˙˚˛", + 350: "\u00a0", + 354: "ţŧ", + 360: "²³¹⁴ⁿ₁₂₃₄", + 374: "ª", + 390: "()[]", + 400: "¦", + 402: "Ĩĩ", + 411: "Īī", + 420: "ˇ˝", + 429: "ŕŗř", + 438: "º", + 442: "ľ", + 450: "【】{}", + 460: "∂", + 470: "″", + 488: "ł", + 493: "ť", + 500: "¨¯", + 515: "\u00ad", + 543: "Ĵ", + 546: "ij", + 560: "ŀ", + 566: "źżž", + 575: "śŝşš", + 577: "¶", + 600: "ýÿŷ", + 611: "£ĹĻĽĿ", + 616: "¢çćĉċč", + 621: "ķĸ", + 628: "ð", + 629: "¤èéêëòóôõöøēĕėęěōŏő", + 630: "‥", + 634: "ŹŻŽ", + 640: "µùúûüũūŭůűų", + 645: "ŢŤŦ", + 649: "ñńņňŋ", + 650: "ĥħ", + 664: "ÈÉÊËĒĔĖĘĚŚŜŞŠ", + 675: "þĝğġģ", + 678: "àáâãäåāăąđ", + 680: "¥ÝÞŶŸ", + 682: "Ł", + 685: "¬", + 693: "ŔŖŘ", + 700: "αβγδεζηθικλμνξοπρστυφχψωабвгдежзийклмнопрстуфхцчшщъыьэюяё", + 702: "ß", + 714: "Ķ", + 733: "ÀÁÂÃÄÅÙÚÛÜĀĂĄĎĐŨŪŬŮŰŲ", + 742: "«»", + 743: "ĤĦ", + 744: "ʼn", + 752: "ÑŃŅŇŊ", + 773: "ÇĆĈĊČ", + 782: "Ð", + 788: "ď", + 791: "IJ", + 792: "ĜĞĠĢ", + 794: "ÒÓÔÕÖØŌŎŐ", + 799: "ŵ", + 900: ( + "¡§®¼½¾¿ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫ" + "ЬЭЮЯ―†‡€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂" + "⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━" + "│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅" + "╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍" + "㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒" + "㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖" + "㏘㏛㏜㏝!"#$%&'*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "\^_`abcdefghijklmnopqrstuvwxyz|~¢£¬ ̄¥₩" + ), + 906: "©", + 913: "Ŵ", + 979: "Œ", + 1022: "œ", + 1027: "Ææ", + }, + "한컴 윤고딕 240": { + 248: "ː", + 252: "′", + 297: "〔〕", + 308: "ÌÍÎÏìíîïĬĭĮįİıĺļ", + 318: "ĵ", + 326: "ſ", + 340: "´¸˘˙˚˛", + 350: "\u00a0", + 354: "ţŧ", + 360: "²³¹⁴ⁿ₁₂₃₄", + 374: "ª", + 390: "()[]", + 400: "¦", + 402: "Ĩĩ", + 411: "Īī", + 414: "∂", + 420: "ˇ˝", + 423: "″", + 429: "ŕŗř", + 438: "º", + 442: "ľ", + 450: "【】{}", + 480: "/", + 488: "ł", + 493: "ť", + 500: "¯", + 515: "\u00ad", + 546: "ij", + 560: "ŀ", + 564: "Ĵ", + 566: "źżž", + 575: "§śŝşš", + 577: "¶", + 600: "ýÿŷ", + 611: "£ĹĻĽĿ", + 616: "¢çćĉċč", + 621: "ķĸ", + 628: "ð", + 629: "¤èéêëòóôõöøēĕėęěōŏő", + 630: "‥", + 634: "ŹŻŽ", + 640: "µùúûüũūŭůűų", + 645: "ŢŤŦ", + 649: "ñńņňŋ", + 650: "ĥħ", + 664: "ÈÉÊËĒĔĖĘĚŚŜŞŠ", + 675: "þĝğġģ", + 678: "àáâãäåāăąđ", + 680: "¥ÝÞŶŸ", + 682: "Ł", + 685: "¬", + 693: "ŔŖŘ", + 700: "αβγδεζηθικλμνξοπρστυφχψω", + 702: "ß", + 714: "Ķ", + 733: "ÀÁÂÃÄÅÙÚÛÜĀĂĄĎĐŨŪŬŮŰŲ", + 742: "«»", + 743: "ĤĦ", + 744: "ʼn", + 752: "ÑŃŅŇŊ", + 773: "ÇĆĈĊČ", + 782: "Ð", + 788: "ď", + 791: "IJ", + 792: "ĜĞĠĢ", + 794: "ÒÓÔÕÖØŌŎŐ", + 799: "ŵ", + 800: "абвгдежзийклмнопрстуфхцчшщъыьэюяё", + 900: ( + "¡¨®¼½¾¿ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫ" + "ЬЭЮЯ―†‡€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂" + "⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━" + "│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅" + "╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍" + "㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒" + "㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖" + "㏘㏛㏜㏝!"#$%&'*+,-.0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\" + "^_`abcdefghijklmnopqrstuvwxyz|~¢£¬ ̄¥₩" + ), + 906: "©", + 913: "Ŵ", + 979: "Œ", + 1022: "œ", + 1027: "Ææ", + }, + "한컴 윤고딕 250": { + 222: "ι", + 248: "ː", + 252: "′", + 270: "‚‛", + 278: "Ι", + 289: "․", + 297: "〔〕", + 308: "ÌÍÎÏìíîïĬĭĮįİıĺļ", + 318: "ĵ", + 326: "ſ", + 335: "‖‵", + 340: "´¸˘˙˚˛", + 350: "\u00a0", + 354: "ţŧ", + 360: "²³¹⁴ⁿ₁₂₃₄", + 370: "„‟", + 374: "ª", + 390: "()[]", + 395: "τ", + 396: "‹›", + 399: "•", + 400: "¦", + 402: "Ĩĩ", + 411: "Īī", + 414: "∂", + 420: "ˇ˝", + 423: "″", + 429: "ŕŗř", + 438: "º", + 441: "ζ", + 442: "ľ", + 446: "ε", + 447: "‼", + 448: "ξ", + 450: "【】{}", + 474: "‶", + 486: "⁎⁑", + 488: "ł", + 493: "ť", + 500: "¨¯γκλν〖〗〘〙", + 515: "\u00ad", + 525: "χ", + 528: "‐", + 546: "ij", + 547: "υ", + 551: "Γ", + 556: "ηθο", + 557: "δ", + 560: "ŀ", + 564: "Ĵ", + 566: "źżž", + 569: "ρ", + 575: "§śŝşšβ", + 576: "μ", + 577: "¶", + 578: "α", + 600: "ýÿŷ", + 608: "‴", + 611: "£ĹĻĽĿΖΤ", + 616: "¢çćĉċč", + 617: "σ", + 618: "Σ", + 621: "ķĸ", + 628: "ð", + 629: "¤èéêëòóôõöøēĕėęěōŏő", + 630: "‥", + 634: "ŹŻŽ⁉", + 640: "µùúûüũūŭůűų", + 645: "ŢŤŦ", + 646: "⁌⁍", + 648: "φ", + 649: "ñńņňŋ", + 650: "ĥħΞ", + 664: "ÈÉÊËĒĔĖĘĚŚŜŞŠ", + 667: "ΑΒΕΚΡΥΧ", + 668: "ΔΛ", + 675: "þĝğġģ", + 678: "àáâãäåāăąđ", + 680: "¥ÝÞŶŸ", + 682: "Ł", + 685: "¬", + 690: "π", + 693: "ŔŖŘ", + 702: "ß", + 713: "ψ", + 714: "Ķ", + 722: "ΗΝΠ", + 733: "ÀÁÂÃÄÅÙÚÛÜĀĂĄĎĐŨŪŬŮŰŲ", + 742: "«»", + 743: "ĤĦ", + 744: "ʼn", + 748: "Ω", + 752: "ÑŃŅŇŊ", + 770: "⁔", + 773: "ÇĆĈĊČ", + 778: "ΘΟ", + 781: "ω", + 782: "Ð", + 788: "ď", + 791: "IJ", + 792: "ĜĞĠĢ", + 794: "ÒÓÔÕÖØŌŎŐ", + 798: "Φ", + 799: "ŵ", + 833: "Μ", + 835: "Ψ", + 878: "⁇", + 900: ( + "¡®¼½¾¿―†‡€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕ" + "ⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽" + "◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋" + "㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'*+,-./0123456789:;<=>?" + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ\^_`abcdefghijklmnopqrstuvwxyz|~¢£¬ ̄¥₩" + ), + 906: "©", + 909: "⁂", + 913: "Ŵ", + 970: ( + "∆∉∌∓∟∢∦∶∷≃≅≈≐≑≓≚≢≦≧≮≯≰≱≲≳≶≷≹≺≻⊀⊁⊄⊅⊊⊋⊕⊖⊗⊣⊤⊻⊼⋎⋏⋚⋛⋮⋯▭▱▵▹▿◃◉◊◌◍◦◯◻◼☐☕☝☟☯♦♯✖✚✠✣✱✽✿❀❁❇❍❖❶❷❸❹❺❻❼❽❾❿➊➋➌➍➎➏➐➑" + "➒➓➔➛➜➞➡➤➲➵〠〶¦" + ), + 979: "Œ", + 1000: "〒〞〟", + 1022: "œ", + 1027: "Ææ", + }, + "한컴 윤고딕 720": { + 134: "˙", + 203: "˛", + 207: "ː∶", + 226: "˚", + 232: "ı", + 234: "ĺļ", + 236: "ìíį", + 240: "‚․", + 241: "Ι", + 242: "ι", + 248: "ÌÍĮİ", + 288: "´′", + 290: "\u00a0", + 296: "‛", + 327: "ŧ", + 333: "ŕŗř", + 338: "˘", + 340: "ţ", + 341: "ſ", + 350: "、。", + 355: "ĵ", + 360: "˝", + 373: "¸ˇ", + 380: "¦‵‶⁑", + 384: "ł", + 399: "§", + 400: "²³¹⁴ⁿ₁₂₃₄", + 410: "„", + 432: "śŝşš", + 436: "τ", + 440: "″", + 448: "‹›", + 450: "ÎÏîïĨĩĬĭľŀť‟", + 452: "з", + 461: "ν", + 470: "〞〟", + 471: "ª", + 480: "º", + 487: "т", + 490: "⁌⁍", + 491: "я", + 495: "ij", + 500: "źżž〘〙", + 502: "çćĉċč", + 505: "б【】〔〕〖〗", + 508: "с", + 511: "Ĵķ", + 513: "κ", + 515: "ĸк", + 520: "ь", + 522: "ε", + 524: "ă", + 525: "ýÿŷ", + 526: "àáâãäåāąа", + 533: "υгℓ", + 534: "х", + 535: "γ", + 536: "ρу", + 537: "β", + 539: "Ŀ", + 540: "ĹĻĽχ", + 541: "èéêëēĕėęěеё", + 542: "У", + 544: "¨θ", + 547: "Τ", + 548: "δ", + 549: "Ŧ", + 550: "ĪīŚŜŞŠ", + 552: "р", + 555: "Т", + 559: "ŢŤ", + 560: "э", + 563: "μ", + 567: "ŶŸΥΧ", + 569: "Ζв", + 571: "ΓΞΣ", + 573: "Ε", + 574: "о", + 575: "ðч", + 577: "ζХ", + 579: "Ý", + 581: "ŹŻŽЗн", + 582: "ñĥńņň", + 583: "µαη", + 584: "òóôõöōŏő", + 585: "ÈÉÊËĒĔĖĘĚЁЕЬ", + 589: "ĝğġģ‥", + 590: "¯", + 591: "Г", + 592: "Ρ", + 593: "л", + 596: "ξЧ", + 598: "ùúûüũūŭůűų", + 600: "Ω", + 602: "ß", + 603: "λ", + 604: "Р", + 607: "Þο", + 608: "ŋп", + 612: "Φ", + 614: "Κ", + 617: "ц", + 619: "øΒΠ", + 623: "П", + 625: "ΔΛψ", + 626: "ĶКЯ", + 627: "þ", + 630: "\u00ad‐", + 631: "БВъ", + 633: "σ", + 635: "ŔŖŘ", + 638: "π", + 640: "Łм", + 645: "ΨΩφ", + 656: "ий", + 657: "ÇĆĈĊČСЭ", + 660: "ωд", + 661: "ÀÁÂÃÄÅ", + 665: "Α", + 672: "Η", + 674: "Ν", + 677: "ĀĂĄА", + 680: "Л", + 681: "Ц", + 683: "ĎĐŃŊ", + 684: "ÙÚÛÜĤħŨŪŬŮŰŲН", + 686: "ÑŅŇИЙ", + 701: "ĜĞĠĢ", + 708: "ʼn", + 712: "IJ", + 716: "ж", + 720: "¬¬", + 726: "ш", + 728: "ŵ", + 730: "đю", + 740: "щ", + 749: "Ш", + 750: "ÒÓÔÕÖďŌŎŐО", + 757: "Ħ", + 758: "Д", + 761: "ΘΟ", + 773: "ØФ", + 779: "Ð", + 785: "ы", + 791: "Щ", + 797: "Ъ", + 816: "Μ", + 828: "М", + 845: "Ŵ", + 850: "©®", + 870: "Ы", + 880: ( + "¡¢£¤¥«¶»¼½¾¿Ææ―‖†‡•‴‼⁂⁇⁉⁎⁔€℉№℡™Å⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∆∇∈∉∋∌∏∑∓√∝" + "∞∟∠∢∥∦∧∨∩∪∫∬∮∴∵∷∼∽≃≅≈≐≑≒≓≚≠≡≢≤≥≦≧≪≫≮≯≰≱≲≳≶≷≹≺≻⊀⊁⊂⊃⊄⊅⊆⊇⊊⊋⊣⊤⊥⊻" + "⊼⋎⋏⋚⋛⋮⋯⌒─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻" + "┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▭▱▵▶▷▹▼▽▿◀◁◃◈◊◌◍◎◐◑◦◻◼☎☏☕☜☝☞☟☯♀♂♠♡♣♤" + "♥♦♧♨♩♪♬♭♯✖✚✠✣✱✽✿❀❁❇❍❖➔➛➜➞➡➤➵\u3000〃〒〓〠㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝" + "㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'" + "()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abc" + "defghijklmnopqrstuvwxyz{|}~¢£ ̄¦¥₩" + ), + 882: "Ю", + 900: "Ж", + 915: "ф", + 917: "Œ", + 955: "œ", + 1015: "☐➲", + 1033: ( + "⊕⊖⊗⊙⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ◉◯❶❷" + "❸❹❺❻❼❽❾❿➊➋➌➍➎➏➐➑➒➓〶㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫" + "㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿" + ), + }, + "한컴 윤고딕 760": { + 210: "˙", + 215: "˛", + 220: "․", + 250: "ː∶", + 254: "ι", + 274: "‚", + 282: "ìíįıļ", + 290: "‛", + 295: "Ι", + 297: "ÌÍĮİ", + 300: "\u00a0", + 310: "´", + 319: "ĺ", + 320: "˚", + 331: "′", + 348: "˘", + 350: "、。", + 374: "ſ", + 380: "˝‵‶", + 385: "¸", + 390: "⁑〖〗", + 396: "ţŧ", + 407: "ˇ", + 417: "ŕŗ", + 420: "ĵ", + 425: "ĭ", + 430: "Ĭ", + 435: "‹›", + 440: "§", + 443: "¦", + 445: "î", + 450: "ř", + 452: "ï", + 458: "Î", + 460: "ĩ", + 464: "ŀ", + 470: "„‟〞〟", + 473: "з", + 474: "Ĩ", + 475: "Ï", + 480: "²³¹⁴ⁿ₁₂₃₄", + 484: "ľ", + 493: "τ", + 495: "śŝşš", + 500: "ªº", + 510: "【】〔〕〘〙", + 515: "ь", + 520: "⁌⁍", + 526: "″", + 535: "к", + 540: "ł", + 544: "¨", + 548: "г", + 550: "бя", + 554: "ε", + 555: "κ", + 556: "υ", + 557: "Ĵ", + 560: "Īī", + 564: "ijх", + 568: "źżž", + 569: "в", + 574: "çćĉċčсэ", + 575: "ρ", + 578: "ť", + 582: "ĸ", + 584: "ķβ", + 590: "Γ", + 594: "ýÿŷУу", + 597: "àáâãäåāăąа", + 598: "δℓ", + 602: "т", + 607: "Þα", + 608: "ξ", + 616: "ĹĻĽĿ", + 617: "ν", + 619: "èéêëēĕėęěенё", + 625: "μσ", + 626: "ð", + 627: "ŚŜŞŠζ", + 628: "п", + 629: "þ", + 631: "Εъ", + 634: "ο", + 637: "ŢŤŦψТ", + 638: "θ", + 640: "ßч", + 641: "γ", + 643: "З‥", + 645: "Σц", + 650: "\u00ad¯Г‐", + 652: "Ζ", + 655: "Υ", + 657: "òóôõöøōŏőηо", + 658: "д", + 659: "ÝĥŶŸŹŻŽХ", + 663: "ħΧЧ", + 665: "ΡΤ", + 667: "ÈÉÊËĒĔĖĘĚΞЁЕ", + 668: "µñùúûüńņňŋũūŭůűų", + 673: "ĝğġģ", + 675: "Ь", + 678: "λий", + 679: "м", + 683: "πφ", + 685: "χ", + 686: "р", + 687: "ΒР", + 689: "л", + 695: "Ł", + 710: "IJ", + 711: "ш", + 712: "ĶК", + 713: "Π", + 715: "ω", + 717: "БВ", + 718: "Κ", + 721: "ŔŖŘЯ", + 726: "đΨ", + 730: "ж", + 733: "ΑΩ", + 738: "Ω", + 745: "ÇĆĈĊČΔСЭ", + 747: "щ", + 750: "Η", + 752: "Ν", + 755: "Ц", + 760: "Пы", + 762: "Λ", + 764: "Ñ", + 767: "ÀÁÂÃÄÅĀĂĄŊА", + 770: "Д", + 774: "ÙÚÛÜĎŨŪŬŮŰŲ", + 775: "ŃŅŇИЙ", + 776: "ĤН", + 790: "Л", + 793: "ĜĞĠĢ", + 800: "Φ", + 806: "ď", + 807: "ʼn", + 810: "ÐШЪ", + 813: "Θ", + 815: "ю", + 822: "ŵ", + 827: "Ħ", + 832: "Ο", + 836: "ĐФ", + 841: "ÒÓÔÕÖØŌŎŐО", + 860: "Щ", + 890: "Ы", + 897: "Μ", + 912: "Å", + 918: "©®", + 919: "ф", + 920: "М", + 960: ( + "¡¢£¤¥«¬¶»¼½¾¿―‖†‡•‴‼⁂⁇⁉⁎⁔€℉№℡™⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∆∇∈∉∋∌∏∑∓√∝∞∟" + "∠∢∥∦∧∨∩∪∫∬∮∴∵∷∼∽≃≅≈≐≑≒≓≚≠≡≢≤≥≦≧≪≫≮≯≰≱≲≳≶≷≹≺≻⊀⊁⊂⊃⊄⊅⊆⊇⊊⊋⊣⊤⊥⊻⊼⋎" + "⋏⋚⋛⋮⋯⌒─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽" + "┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▭▱▶▷▼▽◀◁◈◊◌◍◎◐◑◻☎☏☕☜☝☞☟☯♀♂♠♡♣♤♥♧♨♩♪♬♭♯" + "✖✚✠✣✱✽✿❀❁❇❍❖➔➛➜➞➡➤➵\u3000〃〒〓〠㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦" + "㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0" + "123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkl" + "mnopqrstuvwxyz{|}~¢£¬ ̄¦¥₩" + ), + 965: "Ŵ", + 970: "Ю", + 977: "æ", + 991: "Æ", + 998: "▵▹▿◃◦", + 1003: "Œ", + 1018: "◼♦", + 1057: "œ", + 1060: "Ж", + 1118: ( + "⊕⊖⊗⊙⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ◉◯☐❶" + "❷❸❹❺❻❼❽❾❿➊➋➌➍➎➏➐➑➒➓➲〶㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩" + "㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿" + ), + }, + "한컴 윤체 L": { + 194: "İıļ", + 212: "ː", + 216: "′", + 223: "ÌÍ", + 231: "í", + 240: "´ì", + 244: "¦", + 252: "Įį", + 254: "〔〕", + 271: "ĺ", + 300: "¸ľ˙˛[]", + 320: "\u00a0{}", + 339: "Ïîï", + 345: "Î", + 349: "²³¹ĵ₁₂₃", + 350: "()", + 354: "∂", + 360: "⁴ⁿ₄", + 362: "ŕŗřţŧſ″", + 397: "¡", + 402: "¶", + 407: "ĩ", + 408: "ij", + 420: "Ĩ", + 430: "ˇ˘˚˝", + 431: "ª", + 436: "Ĭĭ", + 450: "【】", + 453: "śŝşš", + 463: "º", + 464: "\u00ad", + 475: "Īī", + 484: "ť", + 490: "§", + 496: "źżž", + 500: "¨", + 501: "ŀ", + 516: "ĹĻĽĿ", + 524: "Þ", + 535: "ÈÉÊËĒĔĖĘĚ", + 548: "«»", + 552: "ł", + 553: "ŋ", + 554: "ðñùúûüĥńņňũūŭůűŹŻŽ", + 560: "‥", + 562: "ß", + 563: "Ŧ", + 564: "ŢŤ", + 574: "ýþÿķĸŔŖŘŚŜŞŠŷ", + 578: "ų", + 583: "Ķ", + 592: "ÙÚÛÜŨŪŬŮŰŲ", + 595: "¢çćĉċč", + 602: "Ĵ", + 611: "òóôõöøōŏő", + 612: "èéêëēĕėęěĤ", + 624: "¤µ", + 631: "ÑĝğġģŃŅŇŊ", + 633: "£", + 641: "àáâãäåāăą", + 665: "¯", + 670: "Ď", + 677: "IJ", + 680: "Ł", + 681: "Ħ", + 688: "¥¿ÝħŶŸ", + 714: "¬", + 737: "Ð", + 743: "ʼn", + 746: "ÀÁÂÃÄÅ", + 758: "ď", + 776: "ĀĂĄđ", + 800: "αβγδεζηθικλμνξοπρστυφχψω", + 804: "ÇĆĈĊČĐŵ", + 823: "ĜĞĠĢ", + 824: "¼½¾", + 834: "ÒÓÔÕÖØŌŎŐ", + 850: ( + "©®ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯа" + "бвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇" + "∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵" + "ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩" + "┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡" + "♣♤♥♧♨♩♪♬♭\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰" + "㉱㉲㉳㉴㉵㉶㉷㉸㉹㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳" + "㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'*+,-./0123456789:;<=>?" + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ\^_`abcdefghijklmnopqrstuvwxyz|~¢" + "£¬ ̄¥₩" + ), + 877: "Ŵ", + 914: "Æ", + 940: "Œ", + 970: "æ", + 1000: "㉺", + 1100: "œ", + }, + "한컴 소망 M": { + 222: 'ι', + 238: '¦', + 270: '‚‛', + 275: 'ː', + 278: 'Ι', + 280: '′', + 287: 'Ϊ', + 289: '․‧', + 320: '⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉', + 330: '〔〕', + 335: '‖‵', + 338: 'ί', + 355: 'ĵ', + 360: '˙˚', + 369: '‣', + 370: '„‟', + 380: '¸˛', + 390: '()[]', + 395: 'τ', + 396: '‹›', + 399: '•', + 400: '´', + 401: 'ìíîïĺļ', + 420: '§²³¹ÌÍÎÏĨĪīĬĭĮįİı⁴ⁿ₁₂₃₄', + 436: 'ĩ', + 441: 'ζ', + 446: 'ε', + 447: '‼', + 448: 'ξ', + 450: '\xa0ſ【】{}', + 458: 'ľ', + 460: '∂', + 470: '″', + 474: 'ª', + 475: 'ţŧ', + 476: 'º', + 500: 'ˇ˘˝γκλν', + 501: 'ς', + 510: 'ť', + 511: '\xad', + 525: 'χ', + 528: '‐‑', + 542: '¶', + 544: '¨‥', + 547: 'υ', + 551: 'Γ', + 556: 'ηθο', + 557: 'δ', + 560: 'ij', + 563: 'έ', + 565: 'ŕŗř', + 569: 'ρ', + 574: 'ŀ', + 575: 'β', + 576: 'μ', + 577: 'ł', + 578: 'α', + 579: '‗', + 590: 'ή', + 591: 'ΰ', + 594: '‾', + 608: '‴', + 610: 'śŝşš', + 611: 'ΖΤ', + 617: 'σ', + 618: 'Σ', + 619: '«»', + 625: '‒', + 630: 'Ĵ', + 635: '⁄', + 641: 'µ', + 648: 'φ', + 650: 'Ξ', + 655: 'źżž', + 667: 'ΑΒΕΚΡΥΧ', + 668: '¢ΔΛά', + 675: 'çćĉċč', + 689: 'ß', + 690: 'π', + 695: 'èéêëēĕėęě', + 701: 'ð', + 703: 'Ϋ', + 707: 'òóôõöøōŏő', + 713: 'ψ', + 714: 'ĥ', + 716: 'Þ', + 721: 'ŚŜŞŠ', + 722: 'ΗΝΠ', + 725: 'àáâãäåāăą', + 737: 'ýÿŷ', + 740: 'ĹĻĽĿ', + 748: 'Ω', + 750: 'ÈÉÊËĒĔĖĚ', + 757: '£', + 765: 'ĝğġģ', + 769: 'ħ', + 770: '¬¯', + 773: 'þ', + 774: 'ñńņňŋ', + 776: 'ùúûüũūŭůűų', + 778: 'ΘΟ', + 780: 'ķĸ', + 781: 'Ęω', + 786: 'ŹŻŽ', + 794: '₩', + 798: 'Φ', + 800: 'ŢŤŦабвгдежзийклмнопрстуфхцчшщъыьэюяё', + 813: 'đ', + 815: 'ŔŖŘ', + 818: 'ď', + 819: 'Ł', + 833: 'Μ', + 835: 'Ψ', + 841: 'Ð', + 857: 'ÇĆĈĊČ', + 860: 'ĎĶ', + 861: 'ĤĦ', + 865: 'ÑŃŅŇŊ', + 871: 'ʼn', + 875: '¥', + 879: 'Đ', + 880: 'ÙÚÛÜÝŨŪŬŮŰŲŶŸ¥', + 890: 'ÒÓÔÕÖØŌŎŐ', + 900: 'ĜĞĠĢ', + 918: 'IJ', + 934: 'ÀÁÂÃÄÅĀĂĄ', + 947: 'ŵ', + 956: '‱', + 970: '℮−∕∙≈◊', + 1000: '¡¤©®¼½¾¿ŴЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ―†‡€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\^_`abcdefghijklmnopqrstuvwxyz|~¢£¬ ̄₩', + 1048: 'Œ', + 1075: 'œ', + 1097: 'æ', + 1107: 'Æ', + }, + "한컴 소망 B": { + 222: 'ι', + 238: '¦', + 270: '‚‛', + 275: 'ː', + 278: 'Ι', + 280: '′', + 287: 'Ϊ', + 289: '․‧', + 320: '⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉', + 330: '〔〕', + 335: '‖‵', + 338: 'ί', + 360: '˙˚', + 369: 'ĵ‣', + 370: '„‟', + 380: '¸˛', + 390: '()[]', + 395: 'τ', + 396: '‹›', + 399: '•', + 400: '´', + 420: '§²³¹⁴ⁿ₁₂₃₄', + 425: 'ìíîïĩīĭįıĺļ', + 441: 'ζ', + 446: 'ε', + 447: '‼', + 448: 'ξ', + 450: '\xa0ÌÍÎÏĨĪĬĮİſ【】{}', + 460: '∂', + 470: '″', + 474: 'ª', + 476: 'º', + 483: 'ľ', + 500: '˝γκλν', + 501: 'ς', + 509: 'ţťŧ', + 511: '\xad', + 525: 'χ', + 528: '‐‑', + 542: '¶', + 547: 'υ', + 550: 'ˇ˘', + 551: 'Γ', + 556: 'ηθο', + 557: 'δ', + 563: 'έ', + 569: 'ρ', + 574: 'ŀ', + 575: 'β', + 576: 'μ', + 577: 'ł', + 578: 'α', + 579: '‗', + 585: 'ŕŗř', + 590: 'ή', + 591: 'ΰ', + 594: '‾', + 608: '‴', + 611: 'ΖΤ', + 614: '¨', + 617: 'σ', + 618: 'Σ', + 619: '«»ij', + 620: '‥', + 625: '‒', + 630: 'Ĵśŝşš', + 635: '⁄', + 648: 'φ', + 650: 'Ξ', + 655: 'źżž', + 663: 'µ', + 667: 'ΑΒΕΚΡΥΧ', + 668: '¢ΔΛά', + 675: 'çćĉċč', + 690: 'π', + 699: 'èéêëēĕėęě', + 700: 'ß', + 701: 'ð', + 703: 'Ϋ', + 713: 'òóôõöøōŏőψ', + 716: 'Þ', + 721: 'ŚŜŞŠ', + 722: 'ΗΝΠ', + 725: 'àáâãäåāăą', + 737: 'ÿŷ', + 740: 'ĹĻĽĿŁ', + 748: 'Ω', + 750: 'ÈÉÊËĒĔĖĚ', + 757: '£ĸ', + 765: 'ĝğġģ', + 769: 'ĥ', + 770: '¬¯', + 771: 'ý', + 773: 'þ', + 774: 'ñùúûüńņňŋũūŭůűų', + 778: 'ΘΟ', + 780: 'ķ', + 781: 'Ęω', + 786: 'ŹŻŽ', + 794: '₩', + 798: 'Φ', + 800: 'ŢŤŦабвгдежзийклмнопрстуфхцчшщъыьэюяё', + 813: 'đ', + 815: 'ŔŖŘ', + 818: 'ď', + 825: 'ħ', + 833: 'Μ', + 835: 'Ψ', + 841: 'Ð', + 857: 'ÇĆĈĊČ', + 860: 'ĎĶ', + 861: 'ĤĦ', + 865: 'ÑŃŅŇŊ', + 871: 'ʼn', + 875: '¥', + 879: 'Đ', + 880: 'ÙÚÛÜÝŨŪŬŮŰŲŶŸ', + 890: 'ÒÓÔÕÖØŌŎŐ', + 910: 'ĜĞĠĢ', + 934: 'ÀÁÂÃÄÅĀĂĄ', + 940: 'IJ', + 947: 'ŵ', + 956: '‱', + 970: '℮−∕∙≈◊', + 1000: '¡¤©®¼½¾¿ŴЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ―†‡€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\^_`abcdefghijklmnopqrstuvwxyz|~¢£¬ ̄¥₩', + 1053: 'Œ', + 1075: 'œ', + 1097: 'æ', + 1107: 'Æ', + }, + "한컴 백제 B": { + 200: "˙", + 234: "ìíîïıː", + 238: "¦′", + 244: "ÌÍÎÏİĺļ", + 281: "〔〕", + 287: "´", + 308: "Į", + 315: "į", + 350: "²³¸¹˛⁴ⁿ₁₂₃₄", + 360: "ˇ˚˝", + 390: "()[]", + 391: "∂", + 398: "ţŧ", + 399: "ĵ", + 400: "″", + 401: "ľ", + 404: "ŀ", + 414: "Ĭ", + 417: "ĭ", + 425: "\u00ad", + 431: "ſ", + 432: "ĨĴ", + 434: "§", + 436: "ĩ", + 440: "ij", + 450: "ī˘‥【】{}", + 456: "ł", + 458: "Ī", + 470: "ŕŗř", + 474: "ª", + 476: "º", + 484: "Þ", + 487: "ĹĻĽĿ", + 519: "ŢŤŦ", + 530: "ť", + 541: "ýÿŷ", + 553: "śŝşš", + 567: "IJ", + 574: "ÝŶŸźżž", + 577: "«¯»", + 585: "¶", + 589: "ŹŻŽ", + 596: "çćĉċč", + 600: "Ł", + 607: "ÀÁÂÃÄÅĀĂķ", + 610: "èéêëēĕėęě", + 611: "ðŚŜŞŠ", + 621: "ÈÉÊËĒĔĖĚ", + 629: "ĸ", + 635: "òóôõöøōŏő", + 637: "µ", + 640: "Ķ", + 642: "ùúûüũūŭůű", + 644: "¥", + 651: "ñńņňŋ", + 657: "ĝğġģĥ", + 660: "ßĘ", + 662: "àáâãäåþāăĤŔŖŘ", + 677: "ÙÚÛÜŨŪŬŮŰŲ", + 683: "ų", + 684: "ÑŃŅŇŊ", + 691: "ħ", + 695: "Ď", + 700: "αβγδεζηθικλμνξοπρστυφχψωабвгдежзийклмнопрстуфхцчшщъыьэюяё", + 701: "¤", + 704: "Ħ", + 709: "ą", + 717: "ÇĆĈĊČ", + 733: "¬", + 735: "ÐĄĐ", + 740: "đ", + 742: "ĜĞĠĢ", + 764: "ʼn", + 770: "©", + 772: "ÒÓÔÕÖØŌŎŐ", + 782: "ď", + 816: "ŵ", + 838: "Ŵ", + 850: ( + "¡¢£¨®¼½¾¿ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩ" + "ЪЫЬЭЮЯ―†‡€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪" + "≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ" + "─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃" + "╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋" + "㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐" + "㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐" + "㏓㏖㏘㏛㏜㏝!"#$%&'*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" + "YZ\^_`abcdefghijklmnopqrstuvwxyz|~¢£¬ ̄¥₩" + ), + 894: "Æ", + 932: "Œ", + 1040: "æ", + 1057: "œ", + }, + "한컴 백제 M": { + 200: "˙", + 234: "ìíîïıː", + 238: "¦′", + 244: "ÌÍÎÏİĺļ", + 281: "〔〕", + 287: "´", + 292: "Įį", + 321: "Ĵ", + 350: "²³¸¹˛⁴ⁿ₁₂₃₄", + 360: "ˇ˚˝", + 385: "ſ", + 390: "()[]", + 391: "∂", + 398: "ţŧ", + 399: "ĵ", + 400: "˘″", + 401: "ľ", + 404: "ŀ", + 414: "Ĭ", + 417: "ĭ", + 425: "\u00ad", + 430: "ij", + 432: "Ĩ", + 434: "§", + 436: "ĩ", + 450: "ī‥【】{}", + 456: "ł", + 458: "Ī", + 470: "ŕŗř", + 474: "ª", + 476: "º", + 484: "Þ", + 487: "ĹĻĽĿ", + 519: "ŢŤŦ", + 532: "ť", + 541: "ýÿŷ", + 553: "śŝşš", + 554: "IJĸ", + 574: "ÝŶŸźżž", + 577: "«¯»", + 585: "¶", + 589: "ŹŻŽ", + 596: "çćĉċč", + 600: "Ł", + 607: "ÀÁÂÃÄÅĀĂķ", + 610: "èéêëēĕėęě", + 611: "ðŚŜŞŠ", + 621: "ÈÉÊËĒĔĖĘĚ", + 635: "òóôõöøōŏő", + 637: "µ", + 640: "Ķ", + 642: "ùúûüũūŭůű", + 644: "¥", + 651: "ñńņňŋ", + 657: "ĝğġģĥ", + 660: "ß", + 662: "àáâãäåþāăĤŔŖŘ", + 671: "ÙÚÛÜŨŪŬŮŰŲ", + 683: "ų", + 684: "ÑŃŅŇŊ", + 691: "ħ", + 695: "Ď", + 700: "αβγδεζηθικλμνξοπρστυφχψωабвгдежзийклмнопрстуфхцчшщъыьэюяё", + 701: "¤", + 704: "ÇĦ", + 709: "ą", + 717: "ĆĈĊČ", + 727: "đ", + 733: "¬", + 735: "ÐĄĐ", + 742: "ĜĞĠĢ", + 764: "ʼn", + 770: "©", + 772: "ÒÓÔÕÖØŌŎŐ", + 782: "ď", + 816: "ŵ", + 838: "Ŵ", + 850: ( + "¡¢£¨®¼½¾¿ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩ" + "ЪЫЬЭЮЯ―†‡€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪" + "≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ" + "─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃" + "╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋" + "㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐" + "㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐" + "㏓㏖㏘㏛㏜㏝!"#$%&'*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" + "YZ\^_`abcdefghijklmnopqrstuvwxyz|~¢£¬ ̄¥₩" + ), + 887: "Æ", + 905: "Œ", + 1040: "æ", + 1057: "œ", + }, + "한컴 바겐세일 B": { + 226: "¦", + 240: "´", + 278: "ĺļ", + 280: "′", + 281: "ìíîīĭįı", + 292: "ÌÍÎÏĨĪĬĮİ", + 293: "ï", + 310: "ĵ", + 320: "Ĵ()", + 330: "〔〕", + 350: "[]{}", + 359: "ſ", + 360: "ţ", + 365: "ĩ", + 370: "ŧ", + 380: "²³¹⁴ⁿ₁₂₃₄", + 400: "¸˙˚˛", + 411: "ł", + 423: "ľ", + 430: "ˇ˘˝", + 450: "【】", + 455: "ŕŗř", + 460: "∂", + 462: "źżž", + 470: "″", + 474: "ť", + 475: "śŝşš", + 492: "º", + 493: "¢çćĉċč", + 494: "ŀ", + 496: "\u00ad", + 498: "§", + 500: "«»", + 524: "¨", + 537: "Þ", + 542: "ĹĻĽĿ", + 544: "þ", + 549: "èéêëēĕėęě", + 554: "ðýŷ", + 560: "ŹŻŽ", + 566: "òóôõöøĥōŏő", + 570: "ñńņňŋ", + 571: "µùúûüķĸũūŭůűų", + 573: "ÈÉÊËĒĔĖĘĚ", + 577: "ŚŜŞŠ", + 581: "Ł", + 586: "đ", + 588: "ªàáâãäåāăąĝğġģ", + 590: "ŢŤŦ", + 591: "ßij", + 600: "‥", + 603: "ħ", + 608: "¶", + 612: "IJ", + 621: "¬", + 630: "Ķ", + 635: "ŔŖŘ", + 642: "ÇĆĈĊČ", + 644: "ÀÁÂÃÄÅĀĂĄ", + 650: "¥ÝŶŸ", + 657: "ĜĞĠĢ", + 658: "ÑĤĦŃŅŇŊ", + 660: "≠", + 667: "ÙÚÛÜŨŪŬŮŰŲ", + 680: "ĎĐ", + 690: "ʼn", + 700: "αβγδεζηθικλμνξοπρστυφχψωабвгдежзийклмнопрстуфхцчшщъыьэюяё", + 701: "ÒÓÔÕÖØŌŎŐ", + 706: "¯", + 718: "Ð", + 724: "ŵ", + 727: "ď", + 800: ( + "¡£¤®¼½¾¿ːΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩ" + "ЪЫЬЭЮЯ―†‡€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≡≤≥≪≫" + "⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─" + "━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄" + "╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌" + "㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑" + "㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓" + "㏖㏘㏛㏜㏝!"#$%&'*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXY" + "Z\^_`abcdefghijklmnopqrstuvwxyz|~¢£¬ ̄¥₩" + ), + 830: "©", + 874: "Œ", + 881: "Ŵ", + 904: "æ", + 908: "œ", + 922: "Æ", + }, + "한컴 바겐세일 M": { + 226: "¦", + 240: "´", + 275: "ː", + 278: "ĺļ", + 280: "′", + 281: "ìíîīĭįı", + 292: "ÌÍÎÏĨĪĬĮİ", + 293: "ï", + 305: "¡", + 310: "ĵ", + 320: "Ĵ()", + 330: "〔〕", + 335: "¸", + 337: "˙", + 338: "˛", + 346: "˚", + 350: "[]{}", + 359: "ſ", + 360: "ţ", + 365: "ĩ", + 370: "ŧ", + 380: "²³¹⁴ⁿ₁₂₃₄", + 411: "ł", + 420: "˝", + 423: "ľ", + 450: "【】", + 455: "ŕŗř", + 460: "∂", + 462: "źżž", + 468: "ˇ˘", + 470: "″", + 474: "ť", + 475: "śŝşš", + 484: "¿", + 492: "º", + 493: "¢çćĉċč", + 494: "ŀ", + 496: "¨\u00ad", + 498: "§", + 500: "«»", + 512: "‥", + 537: "Þ", + 542: "ĹĻĽĿ", + 544: "þ", + 549: "èéêëēĕėęě", + 554: "ðýÿŷ", + 560: "ŹŻŽ", + 561: "¤", + 566: "òóôõöøĥōŏő", + 570: "ñńņňŋ", + 571: "µùúûüķĸũūŭůűų", + 573: "ÈÉÊËĒĔĖĘĚ", + 577: "ŚŜŞŠ", + 581: "Ł", + 586: "đ", + 588: "ªàáâãäåāăąĝğġģ", + 590: "ŢŤŦ", + 591: "ßij", + 603: "ħ", + 608: "¶", + 612: "IJ", + 621: "¬", + 628: "≠", + 630: "Ķ", + 635: "ŔŖŘ", + 642: "ÇĆĈĊČ", + 644: "ÀÁÂÃÄÅĀĂĄ", + 650: "¥ÝŶŸ", + 657: "ĜĞĠĢ", + 658: "ÑĤĦŃŅŇŊ", + 667: "ÙÚÛÜŨŪŬŮŰŲ", + 680: "ĎĐ", + 690: "ʼn", + 700: "αβγδεζηθικλμνξοπρστυφχψωабвгдежзийклмнопрстуфхцчшщъыьэюяё", + 701: "ÒÓÔÕÖØŌŎŐ", + 706: "¯", + 718: "Ð", + 724: "ŵ", + 727: "ď", + 800: ( + "£¼½¾ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮ" + "Я―†‡€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≡≤≥≪≫⊂⊃⊆⊇⊙" + "⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍" + "┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉" + "╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑" + "㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖" + "㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝" + "!"#$%&'*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\^_`" + "abcdefghijklmnopqrstuvwxyz|~¢£¬ ̄¥₩" + ), + 830: "©®", + 874: "Œ", + 881: "Ŵ", + 904: "æ", + 908: "œ", + 922: "Æ", + }, + "새굴림": { + 256: "¦ìíîïīĭįıĵĺļľł∙", + 293: "ĩ", + 299: "ÌÍÎÏĨĪĬĮİΙ", + 320: "\u0387ŀ˙˚˛", + 341: "¸ŕŗřţťŧ‚‛", + 384: "²³´¹ſˇ˘ι•′‹›∫▪▫◦", + 427: "¡⁄∕", + 448: "ªº˝ⁿ", + 512: "\u00a0¨«\u00ad¯»ýÿŷźżžζνξгух‗„″‾ℓ", + 555: "ĴķĸśŝşšκУк", + 561: "ь", + 562: "√", + 576: "¤§¶¼½¾γεзлчя†‡⅛⅜⅝⅞∂", + 577: "β", + 585: "δд", + 596: "Þ", + 597: "¢µ¿àáâãäåçèéêëùúûüāăąćĉċčēĕėęěĥħijĹĻĽĿŁŢŤŦũūŭůűųΤμτυχТЧаестё", + 609: "£ΓГ", + 623: "ц", + 628: "∆", + 640: "¥ÝßðñòóôõöøþďđĝğġģńņňŋōŏőŶŸŹŻŽΖΥΧαηορσφЗХбвийнопръэ‼♀♂", + 673: "Ь", + 683: "ÀÁÂÃÄÅÈÉÊËĀĂĄĒĔĖĘĚĶŚŜŞŠΕΚΛΡЁАБЕКР", + 704: "ΑΣΨθλπ―∏♪", + 719: "Π", + 720: "¬", + 725: "ŔŖŘΒВЯ", + 729: "Л", + 736: "ы∩", + 738: "ʼn", + 749: "ψ", + 756: "Ц", + 768: "ÇÐÑÙÚÛÜĆĈĊČĎĐĤĦIJŃŅŇŊŨŪŬŮŰŲŵΗΝΩωИЙНСЪЭжмф€Ω↕►◄♠", + 769: "Δ", + 781: "♫", + 790: "П", + 793: "◊♦", + 802: "©®", + 806: "æ", + 811: "ÒÓÔÕÖØŌŎŐΘΟΦО", + 812: "♥", + 832: "ΞДФшщ∑", + 853: "ĜĞĠĢ−≈≠≡≤≥", + 856: "М", + 864: "♣", + 865: "Ы", + 896: "œΜ", + 911: "ю", + 935: "∞", + 936: "▼", + 938: "☼", + 939: "Ŵ", + 960: "ÆШЩ", + 989: "Ж", + 1006: "∟", + 1024: ( + "ŒːЮ‥⁴₁₂₃₄℉№℡™Å⅓⅔↔↖↗↘↙⇒⇔∀∃∇∈∋∝∠∥∧∨∪∬∮∴∵∼∽≒≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥" + "⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙" + "┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▬▶" + "▷▽◀◁◈◎◐◑◘◙☎☏☜☞☺☻♡♤♧♨♩♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛" + "㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠" + "㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*" + "+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdef" + "ghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + }, + "한컴 말랑말랑 Regular": { + 161: "\u0387", + 208: "′", + 226: "¡", + 235: "ıι", + 300: "\u00a0", + 330: "ː∶", + 357: "г", + 368: "˙", + 378: "″", + 379: "Ι", + 390: "∫", + 400: "²³´¸¹ˇ˘˚˛⁴ⁿ", + 405: "ŀ", + 420: "、。", + 426: "ŧ", + 428: "¨˝", + 440: "εзть₁₂₃₄", + 451: "ξ", + 460: "łζв", + 465: "я", + 468: "ij", + 470: "¿", + 476: "ч", + 484: "\u00adх", + 490: "∮", + 495: "п", + 500: "Г‖∥", + 502: "и", + 508: "λ", + 510: "§ℓ", + 517: "й", + 520: "ªºγτ【】〔〕", + 524: "ĸκк", + 529: "ĿΓ", + 530: "Σ", + 531: "ŦΤТ", + 534: "ΕЁЕ∃", + 535: "У", + 536: "ц", + 537: "н", + 540: "лъ", + 541: "с", + 545: "ν", + 547: "∂", + 550: "υ†‡≤≥", + 560: "δ", + 562: "д", + 564: "э", + 565: "β", + 568: "Ζ", + 570: "ßЗ", + 574: "у", + 577: "ŋη", + 580: "θ≡", + 587: "ΒБВЬ‥", + 590: "ΡР", + 592: "её", + 595: "μ", + 598: "ΦФ", + 600: "ð∑", + 602: "Я", + 606: "ΚК", + 608: "οо", + 610: "Ł", + 615: "Ξ", + 619: "Ч", + 620: "π∠", + 622: "ø", + 624: "б", + 626: "ΧχХ", + 629: "þΥαρар", + 630: "Δ", + 639: "ж", + 640: "∬", + 650: "£¶≒£", + 652: "ħ", + 660: "φы", + 670: "ИЙ≠", + 673: "¥¥", + 676: "СЭ", + 678: "ʼn", + 680: "Ŋ", + 685: "Þ", + 687: "ΑΛА∀", + 690: "ΗΝНш", + 693: "Å", + 694: "ΨΩΩ", + 696: "¤", + 699: "ΠП", + 700: "∏", + 706: "Ц", + 707: "đ", + 710: "Л", + 714: "ψ", + 717: "щ", + 720: "σ", + 740: "ωД", + 741: "Ъ", + 750: "⊥", + 780: "∧∨∩∪", + 783: "«»≪≫", + 790: "Ħю", + 793: "IJ", + 800: "Ð⌒", + 808: "€", + 810: "Ø", + 823: "ΘΟО", + 838: "м", + 860: "Ж", + 862: "Ы", + 870: "⊆⊇", + 880: ( + "¢¬¼½¾ÆŒ―℉№℡™⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∇∈√∝∞∴∵∼∽⊂⊃⊙⋯─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├" + "┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀" + "◁◈◉◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000〃〓!"#$%&'()*+,-./0123456789:;<=>?@AB" + "CDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~" + "¢¬ ̄₩" + ), + 923: "æ", + 924: "Ш", + 940: "∋", + 960: "Щ", + 961: "ΜМ", + 992: "ф", + 1000: ( + "©®⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ㈀㈁㈂㈃㈄㈅" + "㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊" + "㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆" + "㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝" + ), + 1023: "œ", + 1051: "Ю", + }, + "MD개성체": { + 972: ( + "⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ、。㈀㈁㈂㈃㈄㈅" + "㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻!"#$%&'()" + "*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdef" + "ghijklmnopqrstuvwxyz{|} ̄₩" + ), + 1024: ( + "\u00a0¡¢£¤¥¦§¨©ª«¬\u00ad®¯²³´µ¶¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞß" + "àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ" + ), + }, + "한컴 말랑말랑 Bold": { + 230: "ι", + 258: "′", + 270: "¡", + 276: "ı", + 300: "\u00a0", + 330: "ː∶", + 368: "˙", + 369: "г", + 394: "Ι", + 400: "²³´¸¹ˇ˘˚˛⁴ⁿ₁₂₃₄", + 410: "∫", + 420: "、。", + 428: "¨˝", + 434: "ŀ", + 436: "ŧ", + 437: "т", + 448: "″", + 460: "εз", + 462: "ь", + 471: "ł", + 479: "я", + 480: "ζξ", + 486: "ч", + 487: "в", + 500: "\u00adх‖∥", + 507: "¿", + 510: "§", + 514: "∮", + 517: "ий", + 520: "【】〔〕", + 522: "п", + 526: "ΓГ", + 530: "ªºΕЁЕ∃", + 532: "ij", + 533: "λ", + 535: "ĸκк", + 536: "ℓ", + 537: "н", + 544: "τ", + 545: "γъ", + 547: "ц", + 550: "†‡≤≥", + 551: "ŦΤТ", + 552: "сэ", + 553: "У", + 554: "л", + 557: "∂", + 560: "δ", + 564: "ν", + 569: "Ζ", + 570: "Συ", + 572: "д", + 579: "З", + 582: "χ", + 585: "ΒβБВЬ", + 587: "η", + 588: "у", + 590: "ΡРеё", + 592: "ŋ", + 596: "θ", + 598: "‥≡", + 600: "ßð∑", + 601: "Я", + 605: "ΚК", + 610: "Ł", + 612: "ΦФ", + 620: "Ŀ∠", + 622: "οо", + 623: "μ", + 629: "Ξ", + 630: "ΥΧХ", + 632: "Ч", + 639: "αρар", + 649: "øб", + 650: "¶", + 651: "þ", + 653: "ж", + 656: "π", + 658: "ħ", + 664: "φ", + 668: "≒", + 674: "ы", + 680: "£∬£", + 682: "ИЙ", + 683: "ʼn", + 684: "ΑΛА∀", + 685: "Þ", + 688: "≠", + 689: "СЭ", + 690: "П", + 696: "¤Δ", + 697: "ш", + 700: "¥ΗΝН¥", + 710: "ŊΠ", + 712: "∏", + 722: "đ", + 726: "Ц", + 727: "щ", + 728: "Л", + 730: "ΩσΩ", + 734: "Ψψ", + 735: "Ъ", + 750: "⊥", + 769: "Д", + 770: "ω", + 783: "«»≪≫", + 790: "∧∨∩∪", + 800: "⌒", + 802: "ю", + 809: "IJ", + 812: "Ð", + 816: "Ø", + 819: "€", + 820: "Ħ", + 848: "ΘΟОм", + 876: "⊆⊇", + 880: ( + "¢¬¼½¾Æ―℉№℡™Å⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∇∈∝∞∴∵∼∽⊂⊃⊙⋯─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝" + "┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁" + "◈◉◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000〃〓!"#$%&'()*+,-./0123456789:;<=>?@ABC" + "DEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢" + "¬ ̄₩" + ), + 899: "Ы", + 904: "Ж", + 934: "Ш", + 940: "∋", + 943: "æ", + 950: "Œ", + 972: "ΜМ", + 979: "Щ", + 980: "√", + 992: "ф", + 1000: ( + "©®⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ㈀㈁㈂㈃㈄㈅" + "㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊" + "㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆" + "㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝" + ), + 1027: "œ", + 1068: "Ю", + }, + "KoPub돋움체 Light": { + 160: "·", + 167: "⁄", + 223: "ι", + 260: "𐤟", + 280: "²³¹⁴ⁿ₁₂₃₄", + 289: "․", + 290: "ìíîǐỉị", + 294: "ˮ", + 300: "¡", + 312: "\uf09e\uf0a0", + 319: "º", + 335: "‖", + 352: "ī", + 365: "г", + 385: "\uf0fa", + 396: "τ", + 400: "•‣", + 438: "к", + 440: "ζ", + 447: "εξ", + 450: "§¸ː˛′″∂、。【】〔〕", + 451: "з", + 458: "т\uf0a7\uf027\uf073\uf09f", + 483: "\uf0f9", + 485: "「」■", + 486: "¿", + 500: "γκλνсухàáâãäāăǎạảấầẩẫậắằẳặ・\U000f0800\U000f0854\U000f0855\uf07f", + 506: "¢", + 510: "э", + 520: "¥", + 521: "чь", + 525: "χ", + 527: "‐", + 531: "в\uf07d\uf07e", + 533: "£«»", + 540: "èéêñòóôõöùúûüēěōũūơưǒǔǚǜẹẻẽếềểễệọỏốồổỗộớờởỡợụủ", + 542: "Гпя", + 547: "υ", + 549: "\uf047\uf048", + 550: "Γ", + 552: "н", + 554: "\uf035", + 556: "δηθοаеорё", + 559: "ий", + 565: "ứừửữự", + 569: "ρ", + 570: "−", + 573: "бц", + 576: "βμ", + 578: "α\uf077", + 583: "Кдлỷ", + 587: "\uf041", + 589: "ʹ", + 600: "ß◦", + 603: "\uf036", + 604: "З", + 610: "ΖΤ", + 611: "Т", + 616: "σ", + 618: "Σ", + 625: "‒ъ", + 635: "У", + 636: "\uf0fb", + 647: "φ", + 650: "Ξ", + 651: "\uf053", + 656: "БЛЬ", + 660: "\uf04e", + 667: "ΑΒΔΕΚΛΡΥΧЁАВЕРХЧÉ", + 669: "ж", + 674: "Ç\uf043\uf044", + 677: "Д", + 688: "м", + 690: "π", + 693: "\uf058", + 700: "\uf032\uf033", + 706: "©", + 707: "Đ", + 712: "ψ", + 719: "ИЙПЭы", + 722: "НСЯ", + 723: "ΗΝΠ\uf057", + 740: "Ц", + 747: "Ω\uf055\uf056\uf06c\uf06e\uf074", + 750: "юÀÁÄÜ", + 760: "Ф", + 776: "\uf0e3\uf0e4\uf0e5\uf0e6", + 778: "ΘΟО", + 780: "ω\uf069", + 783: "\uf0f5\uf0f6\uf0f7\uf0f8", + 787: "\uf0fc", + 792: "Ъ", + 793: "\uf042", + 794: "\uf059\uf0d7\uf0d8", + 798: "Φ", + 799: "¼½¾⅓⅔⅛⅜⅝⅞", + 802: "ш", + 811: "\uf0f1\uf0f2\uf0f4", + 813: "\uf054", + 823: "фщ", + 832: "Μ", + 833: "М", + 836: "Ψ", + 843: "\uf04a\uf04b\uf04c", + 849: "\uf04f", + 873: "\uf0eb\uf0ec\uf0ed\uf0ee", + 880: "\uf052", + 885: "Ы\uf05a", + 887: "\uf051", + 891: "\uf03b\uf03e\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0", + 893: "\uf029\uf034\uf03c\uf03d\uf049\uf05b\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0fd\uf0fe", + 894: "\uf025", + 896: "\uf05c", + 900: ( + "¤¨ª\u00ad®´¶ÆÐØÞæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ↔↕↖↗↘↙⇒⇔" + "∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱" + "⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥" + "┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞" + "♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌" + "㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑" + "㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓" + "㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVW" + "XYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩ぁあぃいぅうぇえぉおかがきぎく" + "ぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりる" + "れろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピ" + "フブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ" + ), + 911: "\uf03f\uf040", + 917: "Ш", + 923: "Ж", + 929: "\uf066", + 933: "\uf063", + 938: "Щ", + 940: "\uf03a\uf062", + 943: "\uf045\uf046", + 947: "\uf038\uf064", + 953: "\uf06d\uf0a6", + 963: "\uf060", + 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", + 980: "\uf0df\uf0e0", + 987: "\uf075", + 1000: "・ー\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4", + 1010: "Ю", + 1025: "\uf065", + 1031: "\uf021", + 1036: "\uf0ff", + 1047: "\uf0c7\uf0c8\uf0c9\uf0ca", + 1051: "\uf06a", + 1054: "\uf05f", + 1060: "\uf078\uf079\uf0f3", + 1065: "\uf068", + 1067: "\uf0e7\uf0e8", + 1073: "\uf037", + 1078: "\uf039", + 1083: "\uf028", + 1089: "\uf050", + 1091: "\uf061", + 1096: "\uf030\uf067", + 1111: "\uf04d", + 1133: "\uf02a\uf02b", + 1145: "\uf022", + 1156: "\uf05e", + 1171: "\uf02c\uf02d", + 1216: "\uf026", + 1253: "\uf0d5\uf0d6", + 1271: "\uf06b", + 1300: "\uf023", + }, + "KoPub돋움체 Medium": { + 160: "·", + 167: "⁄", + 223: "ι", + 260: "𐤟", + 280: "²³¹⁴ⁿ₁₂₃₄", + 289: "․", + 290: "ìíîǐỉị", + 294: "ˮ", + 300: "¡", + 312: "\uf09e\uf0a0", + 319: "º", + 335: "‖", + 352: "ī", + 365: "г", + 396: "τ", + 400: "•‣", + 438: "к", + 440: "ζ", + 447: "εξ", + 450: "§¸ː˛′″∂、。【】〔〕", + 451: "з", + 458: "т\uf0a7", + 485: "「」■", + 486: "¿", + 500: "γκλνсухàáâãäāăǎạảấầẩẫậắằẳặ・\U000f0800\U000f0854\U000f0855", + 506: "¢", + 510: "э", + 520: "¥", + 521: "чь", + 525: "χ", + 527: "‐", + 531: "в", + 533: "£«»", + 540: "èéêñòóôõöùúûüēěōũūơưǒǔǚǜẹẻẽếềểễệọỏốồổỗộớờởỡợụủ", + 542: "Гпя", + 547: "υ", + 550: "Γ", + 552: "н", + 556: "δηθοаеорё", + 559: "ий", + 565: "ứừửữự", + 569: "ρ", + 570: "−", + 573: "бц", + 576: "βμ", + 578: "α", + 583: "Кдлỷ", + 589: "ʹ", + 600: "ß◦", + 604: "З", + 610: "ΖΤ", + 611: "Т", + 616: "σ", + 618: "Σ", + 625: "‒ъ", + 635: "У", + 647: "φ", + 650: "Ξ", + 656: "БЛЬ", + 667: "ΑΒΔΕΚΛΡΥΧЁАВЕРХЧÉ", + 669: "ж", + 674: "Ç", + 677: "Д", + 688: "м", + 690: "π", + 706: "©", + 707: "Đ", + 712: "ψ", + 719: "ИЙПЭы", + 722: "НСЯ", + 723: "ΗΝΠ", + 740: "Ц", + 747: "Ω", + 750: "юÀÁÄÜ", + 760: "Ф", + 778: "ΘΟО", + 780: "ω", + 787: "\uf0fc", + 792: "Ъ", + 798: "Φ", + 799: "¼½¾⅓⅔⅛⅜⅝⅞", + 802: "ш", + 823: "фщ", + 832: "Μ", + 833: "М", + 836: "Ψ", + 885: "Ы", + 900: ( + "¤¨ª\u00ad®´¶ÆÐØÞæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ↔↕↖↗↘↙⇒⇔" + "∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱" + "⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥" + "┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞" + "♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌" + "㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑" + "㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓" + "㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVW" + "XYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩ぁあぃいぅうぇえぉおかがきぎく" + "ぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりる" + "れろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピ" + "フブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ" + ), + 917: "Ш", + 923: "Ж", + 938: "Щ", + 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", + 1000: "・ー\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851", + 1010: "Ю", + }, + "KoPub돋움체 Bold": { + 160: "·", + 167: "⁄", + 223: "ι", + 260: "𐤟", + 280: "²³¹⁴ⁿ₁₂₃₄", + 289: "․", + 290: "ìíîǐỉị", + 294: "ˮ", + 300: "¡", + 312: "\uf09e\uf0a0", + 319: "º", + 335: "‖", + 352: "ī", + 365: "г", + 396: "τ", + 400: "•‣", + 438: "к", + 440: "ζ", + 447: "εξ", + 450: "§¸ː˛′″∂、。【】〔〕", + 451: "з", + 458: "т\uf0a7", + 485: "「」■", + 486: "¿", + 500: "γκλνсухàáâãäāăǎạảấầẩẫậắằẳặ・\U000f0800\U000f0854\U000f0855", + 506: "¢", + 510: "э", + 520: "¥", + 521: "чь", + 525: "χ", + 527: "‐", + 531: "в", + 533: "£«»", + 540: "èéêñòóôõöùúûüēěōũūơưǒǔǚǜẹẻẽếềểễệọỏốồổỗộớờởỡợụủ", + 542: "Гпя", + 547: "υ", + 550: "Γ", + 552: "н", + 556: "δηθοаеорё", + 559: "ий", + 565: "ứừửữự", + 569: "ρ", + 570: "−", + 573: "бц", + 576: "βμ", + 578: "α", + 583: "Кдлỷ", + 589: "ʹ", + 600: "ß◦", + 604: "З", + 610: "ΖΤ", + 611: "Т", + 616: "σ", + 618: "Σ", + 625: "‒ъ", + 635: "У", + 647: "φ", + 650: "Ξ", + 656: "БЛЬ", + 667: "ΑΒΔΕΚΛΡΥΧЁАВЕРХЧÉ", + 669: "ж", + 674: "Ç", + 677: "Д", + 688: "м", + 690: "π", + 706: "©", + 707: "Đ", + 712: "ψ", + 719: "ИЙПЭы", + 722: "НСЯ", + 723: "ΗΝΠ", + 740: "Ц", + 747: "Ω", + 750: "юÀÁÄÜ", + 760: "Ф", + 778: "ΘΟО", + 780: "ω", + 787: "\uf0fc", + 792: "Ъ", + 798: "Φ", + 799: "¼½¾⅓⅔⅛⅜⅝⅞", + 802: "ш", + 823: "фщ", + 832: "Μ", + 833: "М", + 836: "Ψ", + 885: "Ы", + 900: ( + "¤¨ª\u00ad®´¶ÆÐØÞæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ↔↕↖↗↘↙⇒⇔" + "∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱" + "⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥" + "┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞" + "♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌" + "㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑" + "㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓" + "㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVW" + "XYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩ぁあぃいぅうぇえぉおかがきぎく" + "ぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりる" + "れろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピ" + "フブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ" + ), + 917: "Ш", + 923: "Ж", + 938: "Щ", + 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", + 1000: "・ー\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851", + 1010: "Ю", + }, + "KoPub바탕체 Light": { + 160: "·", + 167: "⁄", + 223: "ι", + 260: "𐤟", + 280: "²³¹º⁴₁₂₃₄", + 289: "․", + 290: "ìíîǐỉị", + 294: "ˮ", + 312: "¡\uf09e\uf0a0", + 335: "‖", + 346: "ⁿ", + 352: "ī", + 365: "г", + 385: "\uf0fa", + 396: "τ", + 400: "•‣", + 438: "к", + 440: "«»ζ", + 447: "εξ", + 450: "§¸ː˛′″∂、。【】〔〕", + 451: "з", + 458: "т\uf0a7\uf027\uf073\uf09f", + 468: "¿", + 483: "\uf0f9", + 485: "「」■", + 500: "γκλνсухàáâãäāăǎạảấầẩẫậắằẳặ・\U000f0800\U000f0854\U000f0855\uf07f", + 510: "э", + 521: "чь", + 525: "χ", + 527: "‐", + 531: "в\uf07d\uf07e", + 536: "¢", + 540: "èéêñòóôõöùúûüēěōũūơưǒǔǚǜẹẻẽếềểễệọỏốồổỗộớờởỡợụủ", + 542: "Гпя", + 547: "υ", + 549: "\uf047\uf048", + 550: "Γ", + 552: "н", + 554: "\uf035", + 555: "£", + 556: "δηθοаеорё", + 559: "ий", + 565: "ứừửữự", + 569: "ρ", + 570: "−", + 573: "бц", + 576: "βμ", + 578: "α\uf077", + 583: "Кдлỷ", + 587: "\uf041", + 589: "ʹ", + 600: "◦", + 603: "\uf036", + 604: "З", + 610: "ΖΤ", + 611: "Т", + 616: "σ", + 618: "Σ", + 620: "ß", + 625: "‒ъ", + 635: "У", + 636: "\uf0fb", + 647: "φ", + 650: "Ξ", + 651: "\uf053", + 656: "БЛЬ", + 660: "\uf04e", + 667: "ΑΒΔΕΚΛΡΥΧЁАВЕРХЧÉ", + 669: "ж", + 674: "Ç\uf043\uf044", + 677: "Д", + 688: "м", + 690: "π", + 693: "\uf058", + 700: "\uf032\uf033", + 706: "¥", + 707: "Đ", + 712: "ψ", + 719: "ИЙПЭы", + 722: "НСЯ", + 723: "ΗΝΠ\uf057", + 740: "Ц", + 747: "Ω\uf055\uf056\uf06c\uf06e\uf074", + 750: "юÀÁÄÜ", + 760: "Ф", + 776: "\uf0e3\uf0e4\uf0e5\uf0e6", + 778: "ΘΟО", + 780: "ω\uf069", + 783: "\uf0f5\uf0f6\uf0f7\uf0f8", + 787: "\uf0fc", + 792: "Ъ", + 793: "\uf042", + 794: "\uf059\uf0d7\uf0d8", + 798: "Φ", + 802: "ш", + 811: "\uf0f1\uf0f2\uf0f4", + 813: "\uf054", + 823: "фщ", + 832: "Μ", + 833: "М", + 836: "Ψ", + 843: "\uf04a\uf04b\uf04c", + 849: "\uf04f", + 873: "\uf0eb\uf0ec\uf0ed\uf0ee", + 880: "\uf052", + 885: "Ы\uf05a", + 887: "\uf051", + 891: "\uf03b\uf03e\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0", + 893: "\uf029\uf034\uf03c\uf03d\uf049\uf05b\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0fd\uf0fe", + 894: "\uf025", + 896: "\uf05c", + 900: ( + "¤¨©ª\u00ad®´¶¼½¾ÆÐØÞæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ⅓⅔⅛⅜" + "⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧" + "⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛" + "├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽" + "◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂" + "㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄" + "㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃" + "㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLM" + "NOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩ぁあぃいぅ" + "うぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめ" + "もゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナ" + "ニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ" + ), + 911: "\uf03f\uf040", + 917: "Ш", + 923: "Ж", + 929: "\uf066", + 933: "\uf063", + 938: "Щ", + 940: "\uf03a\uf062", + 943: "\uf045\uf046", + 947: "\uf038\uf064", + 953: "\uf06d\uf0a6", + 963: "\uf060", + 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", + 980: "\uf0df\uf0e0", + 987: "\uf075", + 1000: "・ー\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4", + 1010: "Ю", + 1025: "\uf065", + 1031: "\uf021", + 1036: "\uf0ff", + 1047: "\uf0c7\uf0c8\uf0c9\uf0ca", + 1051: "\uf06a", + 1054: "\uf05f", + 1060: "\uf078\uf079\uf0f3", + 1065: "\uf068", + 1067: "\uf0e7\uf0e8", + 1073: "\uf037", + 1078: "\uf039", + 1083: "\uf028", + 1089: "\uf050", + 1091: "\uf061", + 1096: "\uf030\uf067", + 1111: "\uf04d", + 1133: "\uf02a\uf02b", + 1145: "\uf022", + 1156: "\uf05e", + 1171: "\uf02c\uf02d", + 1216: "\uf026", + 1253: "\uf0d5\uf0d6", + 1271: "\uf06b", + 1300: "\uf023", + }, + "KoPub바탕체 Medium": { + 160: "·", + 167: "⁄", + 223: "ι", + 260: "𐤟", + 280: "²³¹º⁴₁₂₃₄", + 289: "․", + 290: "ìíîǐỉị", + 294: "ˮ", + 312: "¡\uf09e\uf0a0", + 335: "‖", + 346: "ⁿ", + 352: "ī", + 365: "г", + 396: "τ", + 400: "•‣", + 438: "к", + 440: "«»ζ", + 447: "εξ", + 450: "§¸ː˛′″∂、。【】〔〕", + 451: "з", + 458: "т\uf0a7", + 468: "¿", + 485: "「」■", + 500: "γκλνсухàáâãäāăǎạảấầẩẫậắằẳặ・\U000f0800\U000f0854\U000f0855", + 510: "э", + 521: "чь", + 525: "χ", + 527: "‐", + 531: "в", + 536: "¢", + 540: "èéêñòóôõöùúûüēěōũūơưǒǔǚǜẹẻẽếềểễệọỏốồổỗộớờởỡợụủ", + 542: "Гпя", + 547: "υ", + 550: "Γ", + 552: "н", + 555: "£", + 556: "δηθοаеорё", + 559: "ий", + 565: "ứừửữự", + 569: "ρ", + 570: "−", + 573: "бц", + 576: "βμ", + 578: "α", + 583: "Кдлỷ", + 589: "ʹ", + 600: "◦", + 604: "З", + 610: "ΖΤ", + 611: "Т", + 616: "σ", + 618: "Σ", + 620: "ß", + 625: "‒ъ", + 635: "У", + 647: "φ", + 650: "Ξ", + 656: "БЛЬ", + 667: "ΑΒΔΕΚΛΡΥΧЁАВЕРХЧÉ", + 669: "ж", + 674: "Ç", + 677: "Д", + 688: "м", + 690: "π", + 706: "¥", + 707: "Đ", + 712: "ψ", + 719: "ИЙПЭы", + 722: "НСЯ", + 723: "ΗΝΠ", + 740: "Ц", + 747: "Ω", + 750: "юÀÁÄÜ", + 760: "Ф", + 778: "ΘΟО", + 780: "ω", + 787: "\uf0fc", + 792: "Ъ", + 798: "Φ", + 802: "ш", + 823: "фщ", + 832: "Μ", + 833: "М", + 836: "Ψ", + 885: "Ы", + 900: ( + "¤¨©ª\u00ad®´¶¼½¾ÆÐØÞæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ⅓⅔⅛⅜" + "⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧" + "⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛" + "├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽" + "◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂" + "㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄" + "㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃" + "㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLM" + "NOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩ぁあぃいぅ" + "うぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめ" + "もゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナ" + "ニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ" + ), + 917: "Ш", + 923: "Ж", + 938: "Щ", + 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", + 1000: "・ー\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851", + 1010: "Ю", + }, + "KoPub바탕체 Bold": { + 160: "·", + 167: "⁄", + 223: "ι", + 260: "𐤟", + 280: "²³¹º⁴₁₂₃₄", + 289: "․", + 290: "ìíîǐỉị", + 294: "ˮ", + 312: "¡\uf09e\uf0a0", + 335: "‖", + 346: "ⁿ", + 352: "ī", + 365: "г", + 396: "τ", + 400: "•‣", + 438: "к", + 440: "«»ζ", + 447: "εξ", + 450: "§¸ː˛′″∂、。【】〔〕", + 451: "з", + 458: "т\uf0a7", + 468: "¿", + 485: "「」■", + 500: "γκλνсухàáâãäāăǎạảấầẩẫậắằẳặ・\U000f0800\U000f0854\U000f0855", + 510: "э", + 521: "чь", + 525: "χ", + 527: "‐", + 531: "в", + 536: "¢", + 540: "èéêñòóôõöùúûüēěōũūơưǒǔǚǜẹẻẽếềểễệọỏốồổỗộớờởỡợụủ", + 542: "Гпя", + 547: "υ", + 550: "Γ", + 552: "н", + 555: "£", + 556: "δηθοаеорё", + 559: "ий", + 565: "ứừửữự", + 569: "ρ", + 570: "−", + 573: "бц", + 576: "βμ", + 578: "α", + 583: "Кдлỷ", + 589: "ʹ", + 600: "◦", + 604: "З", + 610: "ΖΤ", + 611: "Т", + 616: "σ", + 618: "Σ", + 620: "ß", + 625: "‒ъ", + 635: "У", + 647: "φ", + 650: "Ξ", + 656: "БЛЬ", + 667: "ΑΒΔΕΚΛΡΥΧЁАВЕРХЧÉ", + 669: "ж", + 674: "Ç", + 677: "Д", + 688: "м", + 690: "π", + 706: "¥", + 707: "Đ", + 712: "ψ", + 719: "ИЙПЭы", + 722: "НСЯ", + 723: "ΗΝΠ", + 740: "Ц", + 747: "Ω", + 750: "юÀÁÄÜ", + 760: "Ф", + 778: "ΘΟО", + 780: "ω", + 787: "\uf0fc", + 792: "Ъ", + 798: "Φ", + 802: "ш", + 823: "фщ", + 832: "Μ", + 833: "М", + 836: "Ψ", + 885: "Ы", + 900: ( + "¤¨©ª\u00ad®´¶¼½¾ÆÐØÞæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ⅓⅔⅛⅜" + "⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧" + "⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛" + "├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽" + "◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂" + "㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄" + "㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃" + "㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLM" + "NOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩ぁあぃいぅ" + "うぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめ" + "もゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナ" + "ニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ" + ), + 917: "Ш", + 923: "Ж", + 938: "Щ", + 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", + 1000: "・ー\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851", + 1010: "Ю", + }, + "KoPubWorld돋움체 Light": { + 160: "·", + 167: "⁄", + 223: "ι", + 232: "ìíîïĩīĭįİıĵĺļłſǐỉị", + 257: "¦", + 260: "𐤟", + 280: "²³¹⁴ⁿ₁₂₃₄", + 283: "ÌÍÎÏĨĪĬĮ", + 289: "․", + 290: "\u00a0", + 294: "ˮ", + 300: "¡", + 312: "\uf09e\uf0a0", + 319: "´º", + 320: "¨", + 325: "ľ", + 335: "‖", + 341: "ŕŗřţŧ", + 349: "ŀ", + 365: "г", + 396: "τ", + 400: "•‣", + 424: "ť", + 433: "\u00ad", + 438: "к", + 440: "ζ", + 447: "εξ", + 450: "ː˛′″∂、。【】〔〕", + 451: "зźżž", + 458: "т\uf0a7", + 473: "ij", + 485: "「」■", + 486: "¿", + 500: "Ĵусхγκλν・\U000f0800\U000f0854\U000f0855", + 503: "ỷ", + 504: "ýÿŷ", + 506: "¢ªàáâãäåçāăąćĉċčķĸśŝşš", + 507: "ǎạảấầẩẫậắằẳặ", + 510: "э", + 520: "¥", + 521: "чь", + 523: "¶", + 525: "χ", + 527: "‐", + 529: "¯", + 531: "в", + 533: "£¤§«»", + 542: "япГ", + 547: "υ", + 549: "òóôõöøōŏőǒọỏốồổỗộ", + 550: "Γ", + 552: "нµ", + 555: "ĹĻĽĿŁŢŤŦŹŻŽ", + 556: "аоðерёδηθο", + 559: "ий¬", + 562: "èéêëñùúûüþđēĕėęěĝğġģĥħńņňŋũūŭůűų", + 563: "ǔǚǜẹẻẽếềểễệụủ", + 569: "ρ", + 570: "−", + 573: "цб", + 576: "βμ", + 578: "α", + 583: "лКд", + 585: "ß", + 589: "ʹ", + 600: "◦", + 601: "ŚŜŞŠ", + 604: "З", + 609: "ÈÉÊËÝĒĔĖĘĚĶŶŸ", + 610: "ΖΤ", + 611: "Т", + 616: "σ", + 618: "Σ", + 625: "ъ‒", + 635: "У", + 636: "ďơớờởỡợ", + 647: "φ", + 650: "Ξ", + 655: "Þ", + 656: "ЛБЬưứừửữự", + 661: "ʼn", + 662: "ÀÁÂÃÄÅĀĂĄ", + 664: "ÇĆĈĊČŔŖŘ", + 667: "ЁЕРХАВЧΑΒΔΕΚΛΡΥΧ", + 669: "ж", + 677: "Д", + 688: "м", + 690: "π", + 706: "©®", + 712: "ψĜĞĠĢ", + 713: "ÐĎĐ", + 718: "ÑÙÚÛÜĤĦŃŅŇŨŪŬŮŰŲ", + 719: "ЭПИЙŊы", + 722: "СЯН", + 723: "ΗΝΠ", + 740: "Ц", + 747: "Ω", + 750: "ю", + 758: "ÒÓÔÕÖØIJŌŎŐ", + 760: "Ф", + 778: "ОΘΟ", + 780: "ω", + 787: "\uf0fc", + 792: "Ъ", + 798: "Φ", + 799: "¼½¾⅓⅔⅛⅜⅝⅞", + 802: "шŵ", + 823: "фщ", + 832: "Μ", + 833: "¸М", + 836: "Ψ", + 857: "æ", + 885: "Ы", + 900: ( + "ˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆" + "⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│" + "┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆" + "╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈" + "➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰" + "㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲" + "㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<" + "=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwx" + "yz{|}~¢£¬ ̄¥₩ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはば" + "ぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジス" + "ズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵ" + "ヶ・ー" + ), + 917: "Ш", + 923: "Ж", + 938: "œЩ", + 967: "Æ", + 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", + 987: "Œ", + 990: "Ŵ", + 1000: "\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851", + 1010: "Ю", + }, + "KoPubWorld돋움체 Medium": { + 160: "·", + 167: "⁄", + 223: "ι", + 232: "ìíîïĩīĭįİıĵĺļłſǐỉị", + 257: "¦", + 260: "𐤟", + 280: "²³¹⁴ⁿ₁₂₃₄", + 283: "ÌÍÎÏĨĪĬĮ", + 289: "․", + 290: "\u00a0", + 294: "ˮ", + 300: "¡", + 312: "\uf09e\uf0a0", + 319: "´º", + 320: "¨", + 325: "ľ", + 335: "‖", + 341: "ŕŗřţŧ", + 349: "ŀ", + 365: "г", + 396: "τ", + 400: "•‣", + 424: "ť", + 433: "\u00ad", + 438: "к", + 440: "ζ", + 447: "εξ", + 450: "ː˛′″∂、。【】〔〕", + 451: "зźżž", + 458: "т\uf0a7", + 473: "ij", + 485: "「」■", + 486: "¿", + 500: "Ĵусхγκλν・\U000f0800\U000f0854\U000f0855", + 503: "ỷ", + 504: "ýÿŷ", + 506: "¢ªàáâãäåçāăąćĉċčķĸśŝşš", + 507: "ǎạảấầẩẫậắằẳặ", + 510: "э", + 520: "¥", + 521: "чь", + 523: "¶", + 525: "χ", + 527: "‐", + 529: "¯", + 531: "в", + 533: "£¤§«»", + 542: "япГ", + 547: "υ", + 549: "òóôõöøōŏőǒọỏốồổỗộ", + 550: "Γ", + 552: "нµ", + 555: "ĹĻĽĿŁŢŤŦŹŻŽ", + 556: "аоðерёδηθο", + 559: "ий¬", + 562: "èéêëñùúûüþđēĕėęěĝğġģĥħńņňŋũūŭůűų", + 563: "ǔǚǜẹẻẽếềểễệụủ", + 569: "ρ", + 570: "−", + 573: "цб", + 576: "βμ", + 578: "α", + 583: "лКд", + 585: "ß", + 589: "ʹ", + 600: "◦", + 601: "ŚŜŞŠ", + 604: "З", + 609: "ÈÉÊËÝĒĔĖĘĚĶŶŸ", + 610: "ΖΤ", + 611: "Т", + 616: "σ", + 618: "Σ", + 625: "ъ‒", + 635: "У", + 636: "ďơớờởỡợ", + 647: "φ", + 650: "Ξ", + 655: "Þ", + 656: "ЛБЬưứừửữự", + 661: "ʼn", + 662: "ÀÁÂÃÄÅĀĂĄ", + 664: "ÇĆĈĊČŔŖŘ", + 667: "ЁЕРХАВЧΑΒΔΕΚΛΡΥΧ", + 669: "ж", + 677: "Д", + 688: "м", + 690: "π", + 706: "©®", + 712: "ψĜĞĠĢ", + 713: "ÐĎĐ", + 718: "ÑÙÚÛÜĤĦŃŅŇŨŪŬŮŰŲ", + 719: "ЭПИЙŊы", + 722: "СЯН", + 723: "ΗΝΠ", + 740: "Ц", + 747: "Ω", + 750: "ю", + 758: "ÒÓÔÕÖØIJŌŎŐ", + 760: "Ф", + 778: "ОΘΟ", + 780: "ω", + 787: "\uf0fc", + 792: "Ъ", + 798: "Φ", + 799: "¼½¾⅓⅔⅛⅜⅝⅞", + 802: "шŵ", + 823: "фщ", + 832: "Μ", + 833: "¸М", + 836: "Ψ", + 857: "æ", + 885: "Ы", + 900: ( + "ˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆" + "⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│" + "┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆" + "╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈" + "➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰" + "㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲" + "㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<" + "=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwx" + "yz{|}~¢£¬ ̄¥₩ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはば" + "ぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジス" + "ズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵ" + "ヶ・ー" + ), + 917: "Ш", + 923: "Ж", + 938: "œЩ", + 967: "Æ", + 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", + 987: "Œ", + 990: "Ŵ", + 1000: "\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851", + 1010: "Ю", + }, + "KoPubWorld돋움체 Bold": { + 160: "·", + 167: "⁄", + 223: "ι", + 232: "ìíîïĩīĭįİıĵĺļłſǐỉị", + 257: "¦", + 260: "𐤟", + 280: "²³¹⁴ⁿ₁₂₃₄", + 283: "ÌÍÎÏĨĪĬĮ", + 289: "․", + 290: "\u00a0", + 294: "ˮ", + 300: "¡", + 312: "\uf09e\uf0a0", + 319: "´º", + 320: "¨", + 325: "ľ", + 335: "‖", + 341: "ŕŗřţŧ", + 349: "ŀ", + 365: "г", + 396: "τ", + 400: "•‣", + 424: "ť", + 433: "\u00ad", + 438: "к", + 440: "ζ", + 447: "εξ", + 450: "ː˛′″∂、。【】〔〕", + 451: "зźżž", + 458: "т\uf0a7", + 473: "ij", + 485: "「」■", + 486: "¿", + 500: "Ĵусхγκλν・\U000f0800\U000f0854\U000f0855", + 503: "ỷ", + 504: "ýÿŷ", + 506: "¢ªàáâãäåçāăąćĉċčķĸśŝşš", + 507: "ǎạảấầẩẫậắằẳặ", + 510: "э", + 520: "¥", + 521: "чь", + 523: "¶", + 525: "χ", + 527: "‐", + 529: "¯", + 531: "в", + 533: "£¤§«»", + 542: "япГ", + 547: "υ", + 549: "òóôõöøōŏőǒọỏốồổỗộ", + 550: "Γ", + 552: "нµ", + 555: "ĹĻĽĿŁŢŤŦŹŻŽ", + 556: "аоðерёδηθο", + 559: "ий¬", + 562: "èéêëñùúûüþđēĕėęěĝğġģĥħńņňŋũūŭůűų", + 563: "ǔǚǜẹẻẽếềểễệụủ", + 569: "ρ", + 570: "−", + 573: "цб", + 576: "βμ", + 578: "α", + 583: "лКд", + 585: "ß", + 589: "ʹ", + 600: "◦", + 601: "ŚŜŞŠ", + 604: "З", + 609: "ÈÉÊËÝĒĔĖĘĚĶŶŸ", + 610: "ΖΤ", + 611: "Т", + 616: "σ", + 618: "Σ", + 625: "ъ‒", + 635: "У", + 636: "ďơớờởỡợ", + 647: "φ", + 650: "Ξ", + 655: "Þ", + 656: "ЛБЬưứừửữự", + 661: "ʼn", + 662: "ÀÁÂÃÄÅĀĂĄ", + 664: "ÇĆĈĊČŔŖŘ", + 667: "ЁЕРХАВЧΑΒΔΕΚΛΡΥΧ", + 669: "ж", + 677: "Д", + 688: "м", + 690: "π", + 706: "©®", + 712: "ψĜĞĠĢ", + 713: "ÐĎĐ", + 718: "ÑÙÚÛÜĤĦŃŅŇŨŪŬŮŰŲ", + 719: "ЭПИЙŊы", + 722: "СЯН", + 723: "ΗΝΠ", + 740: "Ц", + 747: "Ω", + 750: "ю", + 758: "ÒÓÔÕÖØIJŌŎŐ", + 760: "Ф", + 778: "ОΘΟ", + 780: "ω", + 787: "\uf0fc", + 792: "Ъ", + 798: "Φ", + 799: "¼½¾⅓⅔⅛⅜⅝⅞", + 802: "шŵ", + 823: "фщ", + 832: "Μ", + 833: "¸М", + 836: "Ψ", + 857: "æ", + 885: "Ы", + 900: ( + "ˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆" + "⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│" + "┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆" + "╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈" + "➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰" + "㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲" + "㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<" + "=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwx" + "yz{|}~¢£¬ ̄¥₩ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはば" + "ぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジス" + "ズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵ" + "ヶ・ー" + ), + 917: "Ш", + 923: "Ж", + 938: "œЩ", + 967: "Æ", + 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", + 987: "Œ", + 990: "Ŵ", + 1000: "\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851", + 1010: "Ю", + }, + "KoPubWorld바탕체 Light": { + 160: "·", + 167: "⁄", + 223: "ι", + 260: "𐤟", + 280: "²³¹º⁴₁₂₃₄", + 282: "ĵ", + 288: "ĺļł", + 289: "․", + 290: "\u00a0", + 294: "ˮ", + 312: "¡´\uf09e\uf0a0", + 323: "ǐỉị", + 324: "ìíîïĩīĭįı", + 328: "ª", + 335: "‖", + 346: "ⁿ", + 350: "ţŧ", + 352: "ÌÍÎÏĨĪĬĮİ", + 354: "ľ", + 358: "Ĵſ", + 361: "ŀ", + 365: "г", + 396: "τ", + 400: "•‣", + 416: "¶ŕŗř", + 432: "śŝşš", + 433: "\u00ad", + 438: "к", + 440: "«»ζ", + 444: "ť", + 447: "εξ", + 450: "§ː˛′″∂、。【】〔〕", + 451: "з", + 458: "т\uf0a7", + 468: "¦¿", + 476: "źżž", + 485: "「」■", + 500: "усхγκλν・\U000f0800\U000f0854\U000f0855", + 510: "э", + 516: "ýÿŷỷ", + 521: "ьч", + 525: "χ", + 527: "‐", + 529: "¯", + 531: "в", + 532: "ŚŜŞŠ", + 533: "¤", + 536: "¢çćĉċč", + 542: "яГп", + 547: "υẹẻẽếềểễệ", + 548: "èéêëēĕėęěĝğġģ", + 550: "Γ", + 552: "ĹĻĽĿŁн", + 555: "£", + 556: "еёаорδηθο", + 558: "àáâãäåāăąǎạảấầẩẫậắằẳặ", + 559: "ий", + 562: "ĥħ", + 564: "ķ", + 569: "ρ", + 570: "−", + 573: "ðбц", + 576: "βμ", + 578: "α", + 583: "лдК", + 584: "ĸ", + 589: "ʹ", + 590: "ÈÉÊËĒĔĖĘĚ", + 592: "đ", + 600: "◦", + 601: "ß", + 603: "ǔǚǜụủ", + 604: "Зµùúûüũūŭůűų", + 606: "ij", + 610: "ΖΤ", + 611: "Т", + 612: "Þñòóôõöøńņňŋōŏőǒọỏốồổỗộ", + 616: "σ", + 618: "Σ", + 625: "ъ¬‒", + 632: "þ", + 635: "У", + 638: "ŹŻŽ", + 647: "φơớờởỡợ", + 649: "ʼn", + 650: "Ξ", + 652: "ŢŤŦ", + 656: "БЬЛưứừửữự", + 667: "ЁЕРВАЧХΑΒΔΕΚΛΡΥΧ", + 668: "ÀÁÂÃÄÅĀĂĄ", + 669: "ж", + 672: "ďŔŖŘ", + 677: "Д", + 688: "м", + 690: "π", + 706: "¥ÝŶŸ", + 708: "ÇĆĈĊČ", + 710: "IJ", + 712: "ψ", + 717: "Ŋ", + 719: "ЭыИЙП", + 722: "ЯСН", + 723: "ΗΝΠ", + 740: "ÙÚÛÜŨŪŬŮŰŲЦ", + 746: "Ķ", + 747: "Ω", + 750: "ю", + 760: "Ф", + 768: "ĜĞĠĢ", + 770: "ÐĎĐĤĦ", + 772: "ŵ", + 778: "ÑŃŅŇОΘΟ", + 780: "ω", + 787: "\uf0fc", + 792: "Ъ", + 798: "Φ", + 802: "ш", + 812: "ÒÓÔÕÖØŌŎŐ", + 823: "фщ", + 832: "Μ", + 833: "¸М", + 836: "Ψ", + 860: "æ", + 868: "œ", + 885: "Ы", + 900: ( + "¨©®¼½¾ˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵" + "∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠ" + "ⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺" + "┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼" + "❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤" + "㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦" + "㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0" + "123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkl" + "mnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + 915: "Œ", + 917: "Ш", + 923: "Ж", + 938: "Щ", + 954: "Ŵ", + 967: "Æ", + 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", + 1000: "\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851", + 1010: "Ю", + 1023: ( + "ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼ" + "ぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅ" + "テデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ・ー" + ), + }, + "KoPubWorld바탕체 Medium": { + 160: "·", + 167: "⁄", + 223: "ι", + 260: "𐤟", + 280: "²³¹º⁴₁₂₃₄", + 282: "ĵ", + 288: "ĺļł", + 289: "․", + 290: "\u00a0", + 294: "ˮ", + 312: "¡´\uf09e\uf0a0", + 323: "ǐỉị", + 324: "ìíîïĩīĭįı", + 328: "ª", + 335: "‖", + 346: "ⁿ", + 350: "ţŧ", + 352: "ÌÍÎÏĨĪĬĮİ", + 354: "ľ", + 358: "Ĵſ", + 361: "ŀ", + 365: "г", + 396: "τ", + 400: "•‣", + 416: "¶ŕŗř", + 432: "śŝşš", + 433: "\u00ad", + 438: "к", + 440: "«»ζ", + 444: "ť", + 447: "εξ", + 450: "§ː˛′″∂、。【】〔〕", + 451: "з", + 458: "т\uf0a7", + 468: "¦¿", + 476: "źżž", + 485: "「」■", + 500: "усхγκλν・\U000f0800\U000f0854\U000f0855", + 510: "э", + 516: "ýÿŷỷ", + 521: "ьч", + 525: "χ", + 527: "‐", + 529: "¯", + 531: "в", + 532: "ŚŜŞŠ", + 533: "¤", + 536: "¢çćĉċč", + 542: "яГп", + 547: "υẹẻẽếềểễệ", + 548: "èéêëēĕėęěĝğġģ", + 550: "Γ", + 552: "ĹĻĽĿŁн", + 555: "£", + 556: "еёаорδηθο", + 558: "àáâãäåāăąǎạảấầẩẫậắằẳặ", + 559: "ий", + 562: "ĥħ", + 564: "ķ", + 569: "ρ", + 570: "−", + 573: "ðбц", + 576: "βμ", + 578: "α", + 583: "лдК", + 584: "ĸ", + 589: "ʹ", + 590: "ÈÉÊËĒĔĖĘĚ", + 592: "đ", + 600: "◦", + 601: "ß", + 603: "ǔǚǜụủ", + 604: "Зµùúûüũūŭůűų", + 606: "ij", + 610: "ΖΤ", + 611: "Т", + 612: "Þñòóôõöøńņňŋōŏőǒọỏốồổỗộ", + 616: "σ", + 618: "Σ", + 625: "ъ¬‒", + 632: "þ", + 635: "У", + 638: "ŹŻŽ", + 647: "φơớờởỡợ", + 649: "ʼn", + 650: "Ξ", + 652: "ŢŤŦ", + 656: "БЬЛưứừửữự", + 667: "ЁЕРВАЧХΑΒΔΕΚΛΡΥΧ", + 668: "ÀÁÂÃÄÅĀĂĄ", + 669: "ж", + 672: "ďŔŖŘ", + 677: "Д", + 688: "м", + 690: "π", + 706: "¥ÝŶŸ", + 708: "ÇĆĈĊČ", + 710: "IJ", + 712: "ψ", + 717: "Ŋ", + 719: "ЭыИЙП", + 722: "ЯСН", + 723: "ΗΝΠ", + 740: "ÙÚÛÜŨŪŬŮŰŲЦ", + 746: "Ķ", + 747: "Ω", + 750: "ю", + 760: "Ф", + 768: "ĜĞĠĢ", + 770: "ÐĎĐĤĦ", + 772: "ŵ", + 778: "ÑŃŅŇОΘΟ", + 780: "ω", + 787: "\uf0fc", + 792: "Ъ", + 798: "Φ", + 802: "ш", + 812: "ÒÓÔÕÖØŌŎŐ", + 823: "фщ", + 832: "Μ", + 833: "¸М", + 836: "Ψ", + 860: "æ", + 868: "œ", + 885: "Ы", + 900: ( + "¨©®¼½¾ˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵" + "∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠ" + "ⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺" + "┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼" + "❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤" + "㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦" + "㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0" + "123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkl" + "mnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + 915: "Œ", + 917: "Ш", + 923: "Ж", + 938: "Щ", + 954: "Ŵ", + 967: "Æ", + 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", + 1000: "\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851", + 1010: "Ю", + 1023: ( + "ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼ" + "ぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅ" + "テデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ・ー" + ), + }, + "KoPubWorld바탕체 Bold": { + 160: "·", + 167: "⁄", + 223: "ι", + 260: "𐤟", + 280: "²³¹º⁴₁₂₃₄", + 282: "ĵ", + 288: "ĺļł", + 289: "․", + 290: "\u00a0", + 294: "ˮ", + 312: "¡´\uf09e\uf0a0", + 323: "ǐỉị", + 324: "ìíîïĩīĭįı", + 328: "ª", + 335: "‖", + 346: "ⁿ", + 350: "ţŧ", + 352: "ÌÍÎÏĨĪĬĮİ", + 354: "ľ", + 358: "Ĵſ", + 361: "ŀ", + 365: "г", + 396: "τ", + 400: "•‣", + 416: "¶ŕŗř", + 432: "śŝşš", + 433: "\u00ad", + 438: "к", + 440: "«»ζ", + 444: "ť", + 447: "εξ", + 450: "§ː˛′″∂、。【】〔〕", + 451: "з", + 458: "т\uf0a7", + 468: "¦¿", + 476: "źżž", + 485: "「」■", + 500: "усхγκλν・\U000f0800\U000f0854\U000f0855", + 510: "э", + 516: "ýÿŷỷ", + 521: "ьч", + 525: "χ", + 527: "‐", + 529: "¯", + 531: "в", + 532: "ŚŜŞŠ", + 533: "¤", + 536: "¢çćĉċč", + 542: "яГп", + 547: "υẹẻẽếềểễệ", + 548: "èéêëēĕėęěĝğġģ", + 550: "Γ", + 552: "ĹĻĽĿŁн", + 555: "£", + 556: "еёаорδηθο", + 558: "àáâãäåāăąǎạảấầẩẫậắằẳặ", + 559: "ий", + 562: "ĥħ", + 564: "ķ", + 569: "ρ", + 570: "−", + 573: "ðбц", + 576: "βμ", + 578: "α", + 583: "лдК", + 584: "ĸ", + 589: "ʹ", + 590: "ÈÉÊËĒĔĖĘĚ", + 592: "đ", + 600: "◦", + 601: "ß", + 603: "ǔǚǜụủ", + 604: "Зµùúûüũūŭůűų", + 606: "ij", + 610: "ΖΤ", + 611: "Т", + 612: "Þñòóôõöøńņňŋōŏőǒọỏốồổỗộ", + 616: "σ", + 618: "Σ", + 625: "ъ¬‒", + 632: "þ", + 635: "У", + 638: "ŹŻŽ", + 647: "φơớờởỡợ", + 649: "ʼn", + 650: "Ξ", + 652: "ŢŤŦ", + 656: "БЬЛưứừửữự", + 667: "ЁЕРВАЧХΑΒΔΕΚΛΡΥΧ", + 668: "ÀÁÂÃÄÅĀĂĄ", + 669: "ж", + 672: "ďŔŖŘ", + 677: "Д", + 688: "м", + 690: "π", + 706: "¥ÝŶŸ", + 708: "ÇĆĈĊČ", + 710: "IJ", + 712: "ψ", + 717: "Ŋ", + 719: "ЭыИЙП", + 722: "ЯСН", + 723: "ΗΝΠ", + 740: "ÙÚÛÜŨŪŬŮŰŲЦ", + 746: "Ķ", + 747: "Ω", + 750: "ю", + 760: "Ф", + 768: "ĜĞĠĢ", + 770: "ÐĎĐĤĦ", + 772: "ŵ", + 778: "ÑŃŅŇОΘΟ", + 780: "ω", + 787: "\uf0fc", + 792: "Ъ", + 798: "Φ", + 802: "ш", + 812: "ÒÓÔÕÖØŌŎŐ", + 823: "фщ", + 832: "Μ", + 833: "¸М", + 836: "Ψ", + 860: "æ", + 868: "œ", + 885: "Ы", + 900: ( + "¨©®¼½¾ˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵" + "∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠ" + "ⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺" + "┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼" + "❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤" + "㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦" + "㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0" + "123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkl" + "mnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + 915: "Œ", + 917: "Ш", + 923: "Ж", + 938: "Щ", + 954: "Ŵ", + 967: "Æ", + 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", + 1000: "\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851", + 1010: "Ю", + 1023: ( + "ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼ" + "ぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅ" + "テデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ・ー" + ), + }, + "HY견명조": { + 165: "\u0387", + 512: ( + "\u00a0¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöù" + "úûüýÿ" + ), + 1024: ( + "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘΙ" + "ΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТУ" + "ФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄℉ℓ№" + "℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟" + "⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓" + "└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥" + "▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓" + "㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘" + "㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"" + "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^" + "_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + }, + "HY동녘M": { + 165: "\u0387", + 512: ( + "\u00a0¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöù" + "úûüýÿ" + ), + 1024: ( + "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘΙ" + "ΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТУ" + "ФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄℉ℓ№" + "℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟" + "⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓" + "└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥" + "▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓" + "㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘" + "㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"" + "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^" + "_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + }, + "HCI Poppy": { + 1: "¡\u302a\u302b", + 161: "˙", + 165: "\u0387", + 172: "ː", + 218: "⁏", + 232: "⁚⁝⁞", + 256: "¦", + 263: "˛", + 270: "˚", + 272: "ĺļľł", + 276: "ìíîïĩīĭįı", + 294: "Ι", + 296: "․‧", + 300: "‚‛", + 304: "ª", + 308: "ĵ", + 321: "¹", + 328: "⁴ⁿ₁₂₃₄", + 338: "ι", + 343: "‖′‵", + 346: "ÌÍÎÏĨĪĬĮİ", + 358: "¸", + 370: "ţťŧ", + 378: "‣", + 384: "º", + 386: "´˘", + 390: "¨", + 392: "²³", + 395: "ˇ", + 400: "„‟", + 402: "ŀ", + 406: "‹›", + 409: "•", + 418: "ŕŗř", + 427: "⁎", + 432: "¼½¾", + 445: "˝", + 448: "Ĵ", + 449: "‡", + 458: "τ‼", + 466: "śŝşš", + 467: "⁃", + 474: "źżž", + 475: "⁖", + 483: "⁅⁆", + 485: "″‶", + 488: "⚬", + 491: "¶", + 492: "‽", + 494: "çðćĉċč", + 497: ( + "〿。「」、ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑→" + "↓■○" + ), + 498: "§⁑", + 502: "èéêëēĕėęě", + 506: "¯", + 512: ( + "¢»¿【】〔〕〖〗〘〙〚〛・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモ" + "ヤユヨラリルレロワン゙゚ᅠ" + ), + 514: "«", + 522: "àáâãäåāăą", + 523: "₫", + 529: "₰", + 530: "её", + 532: "£òóôõöøōŏő", + 534: "⁙", + 536: "µ", + 537: "δ", + 538: "ĸ‸", + 540: "ij", + 541: "‐‑", + 544: "⁊", + 546: "ζξ⚘", + 547: "сэ", + 549: "ν", + 550: "β", + 551: "з", + 553: "х", + 554: "у", + 555: "μ", + 556: "ďđ", + 562: "ь", + 564: "⚨⚲", + 565: "ρ", + 566: "ß", + 568: "ĝğġģε⁒", + 570: "ķ", + 571: "†", + 573: "а", + 574: "¤ùúûüĥħũūŭůűųŷ", + 578: "ñńņňʼnŋ", + 580: "ýþÿκ", + 584: "¥οо₤", + 585: "б", + 586: "гт", + 587: "γ", + 590: "ÞΡ⚚", + 593: "‗", + 601: "Β", + 604: "η", + 605: "υ", + 606: "В", + 607: "θ", + 608: "‾", + 609: "₦", + 612: "ŹŻŽк", + 613: "в", + 614: "φ", + 615: "₠₪", + 616: "З", + 621: "Р₲", + 623: "Ζря‴‷₵", + 624: "ΕЁБЕ", + 627: "Γ", + 628: "₴", + 632: "χий", + 636: "ŚŜŞŠ", + 637: "Г", + 639: "⁈", + 640: "‒", + 645: "ч", + 647: "₣", + 649: "ц⁉", + 650: "⁄", + 652: "₱", + 655: "‥", + 657: "ΚЯ⁘⁛", + 660: "ĹĻĽĿŁ", + 662: "ΤТ⁋⁌⁍", + 665: "Ь", + 666: "₭", + 668: "⁗", + 670: "₮", + 671: "н", + 672: "€", + 673: "σ", + 674: "С", + 675: "⚭", + 676: "α", + 677: "ΞЭ", + 681: "лп₥", + 682: "ψ⁁₡₢", + 688: "æК", + 694: "ÈÉÊËĒĔĖĘĚ", + 697: "⁕", + 705: "Ç", + 706: "ĆĈĊČ", + 711: "⚥⚦", + 712: "Δм", + 713: "ΘΟО", + 714: "Π", + 716: "ŔŖŘ", + 717: "Ч", + 720: "ΥΧХ", + 721: "ΑА", + 724: "λ", + 726: "Ŋъ", + 727: "д", + 731: "πω", + 733: "ΗΝН", + 736: "ИЙ", + 737: "⚐⚑", + 738: "Ω", + 740: "œ", + 752: "ПЦ", + 753: "ΛЛ", + 760: "ĜĞĠĢ", + 762: "Д", + 764: "Ψ", + 765: "ΦФ", + 766: "ÐÒÓÔÕÖØĎĐŌŎŐ", + 768: "У", + 773: "Σ", + 780: "ŶŸ", + 787: "₳", + 788: "ÙÚÛÜÝŢŤŦŨŪŬŮŰŲ‿⁀", + 792: "IJ", + 796: "ÑŃŅŇ", + 798: "Ķ", + 800: "ж", + 802: "ĤĦ", + 804: "©", + 806: "®", + 808: "Ъ", + 813: "₩", + 814: "ÀÁÂÃÄÅĀĂĄю", + 815: "⁔", + 818: "⁐", + 819: "⚢", + 822: "⁓", + 825: "ы", + 829: "₨", + 841: "ΜМ", + 842: "ŵ", + 845: "шщ", + 853: "⁇", + 864: "⚩", + 882: "◸◹◺◿", + 886: "ШЩ", + 895: "Ы⚣⚤", + 896: "―", + 920: "ф⚊⚋⚌⚍⚎⚏", + 931: "⁂", + 950: "Œ", + 951: "Ж", + 954: "⚮", + 956: "Æ", + 971: "Ю", + 979: "‱", + 980: "₧", + 993: ( + "₯℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∊∋∌∍∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡∢∣∤∥" + "∦∧∨∩∪∫∬∭∮∯∰∱∲∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟≠≡" + "≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝" + "⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙" + "⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰" + "⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤" + "┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱▴▵▶▷" + "▸▹►▻▼▽▾▿◀◁◂◃◄◅◈◉◊◌◍◎◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷" + "☀☁☂☃☄☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☙☚☛☝☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂" + "♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽⚀" + "⚁⚂⚃⚄⚅⚆⚇⚈⚉✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷" + "✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❙❚❛❜❝❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻" + "❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻" + "➼➽➾、。〃〄〇〜〝〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘" + "㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝" + "㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'" + "()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abc" + "defghijklmnopqrstuvwxyz{|}~⦅⦆¢£¬ ̄¦¥₩" + ), + 1022: "¬", + 1024: "ſ⁜✀々〆〒〓〞〟", + 1036: "☜☞", + 1058: "Ŵ", + 1116: "⚯", + 1406: "◻◼◽◾☔☕☘♾♿⚒⚓⚔⚕⚖⚗⚙⚛⚜⚠⚡⚧⚪⚫⚰⚱", + }, + "HCI Hollyhock": { + 1: "¡\u302a\u302b", + 161: "˙", + 165: "\u0387", + 172: "ː", + 200: "ıľ", + 202: "ī", + 204: "į", + 206: "ĵ", + 210: "Ī", + 218: "ìíîïĺļł⁏", + 226: "ĭ", + 232: "Į⁚⁝⁞", + 238: "ÌÍÎÏ", + 242: "¦", + 244: "¹", + 246: "ĩ", + 260: "Ĭİ", + 262: "ţťŧ", + 263: "˛", + 270: "˚", + 276: "´Ĩ", + 286: "ŀ", + 294: "Ι", + 296: "․‧", + 300: "‚‛", + 318: "ŕŗř", + 328: "⁴ⁿ₁₂₃₄", + 338: "¸ι", + 343: "‖′‵", + 358: "¨", + 370: "º", + 372: "²³", + 378: "‣", + 380: "ª", + 384: "„‟", + 386: "˘", + 394: "¼½¾ij", + 395: "ˇ", + 406: "‹›", + 409: "•", + 427: "⁎", + 445: "˝", + 449: "‡", + 458: "τ‼", + 467: "⁃", + 475: "⁖", + 478: "ŷ", + 480: "ýþÿ", + 482: "ð", + 483: "⁅⁆", + 485: "″‶", + 488: "⚬", + 491: "ķ", + 492: "śŝşš‽", + 494: "¢çćĉċč", + 496: "źżž", + 497: ( + "〿。「」、ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑→" + "↓■○" + ), + 498: "»⁑", + 500: "«", + 508: "Ĵ", + 510: "ĸ", + 512: ( + "【】〔〕〖〗〘〙〚〛・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨ" + "ラリルレロワン゙゚ᅠ" + ), + 522: "¯", + 523: "₫", + 528: "¿", + 529: "₰", + 530: "её", + 534: "⁙", + 536: "Þ", + 537: "δ", + 538: "‸", + 541: "‐‑", + 542: "ñĝğġģĥńņňʼnŋ", + 544: "èéêëùúûüďđēĕėęěũūŭůűų⁊", + 546: "àáâãäåāăąζξ⚘", + 547: "сэ", + 548: "ô", + 549: "ν", + 550: "õβ", + 551: "з", + 552: "òóöøōŏő", + 553: "х", + 554: "у", + 555: "μ", + 562: "ĹĻĽĿŁь", + 564: "⚨⚲", + 565: "ρ", + 568: "ε⁒", + 571: "†", + 572: "ħ", + 573: "а", + 574: "¥µ", + 577: "¶", + 580: "κ", + 584: "οо₤", + 585: "б", + 586: "гт", + 587: "γ", + 590: "Ρ⚚", + 593: "‗", + 600: "ßŢŤŦŹŻŽ", + 601: "Β", + 604: "η", + 605: "υ", + 606: "¤В", + 607: "θ", + 608: "‾", + 609: "₦", + 612: "к", + 613: "в", + 614: "φ", + 615: "₠₪", + 616: "З", + 621: "Р₲", + 623: "Ζря‴‷₵", + 624: "£ΕЁБЕ", + 627: "Γ", + 628: "₴", + 632: "χий", + 634: "ÝŊŶŸ", + 637: "Г", + 639: "⁈", + 640: "Ķ‒", + 645: "ч", + 647: "₣", + 648: "ÀÁÂÃÄÅĀĂĄ", + 649: "ц⁉", + 650: "Ş⁄", + 652: "ŚŜŠ₱", + 655: "‥", + 657: "ΚЯ⁘⁛", + 658: "§", + 662: "ΤТ⁋⁌⁍", + 664: "ÈÉÊËĒĔĖĘĚ", + 665: "Ь", + 666: "₭", + 668: "⁗", + 670: "₮", + 671: "н", + 672: "€", + 673: "σ", + 674: "С", + 675: "⚭", + 676: "α", + 677: "ΞЭ", + 681: "лп₥", + 682: "ψ⁁₡₢", + 688: "К", + 697: "⁕", + 698: "IJ", + 702: "ĎĐ", + 705: "ÙÚÛÜŨŪŬŮŲ", + 706: "ĤĦŰ", + 708: "ÑŃŅŇŔŖŘ", + 710: "Ð", + 711: "⚥⚦", + 712: "Δм", + 713: "ΘΟО", + 714: "ŵΠ", + 716: "ÇĆĈĊČ", + 717: "Ч", + 720: "ΥΧХ", + 721: "ΑА", + 724: "λ", + 726: "ъ", + 727: "д", + 731: "πω", + 733: "ΗΝН", + 736: "ИЙ", + 737: "⚐⚑", + 738: "Ω", + 752: "ПЦ", + 753: "ΛЛ", + 762: "Д", + 764: "Ψ", + 765: "ΦФ", + 766: "ÒÓÔÕÖŌŎŐ", + 768: "У", + 770: "ĜĞĠĢ", + 773: "Σ", + 782: "©®", + 787: "₳", + 788: "‿⁀", + 800: "ж", + 806: "Ø", + 808: "Ъ", + 813: "₩", + 814: "ю", + 815: "⁔", + 818: "⁐", + 819: "⚢", + 822: "⁓", + 825: "ы", + 829: "₨", + 841: "ΜМ", + 845: "шщ", + 848: "æ", + 853: "⁇", + 864: "⚩", + 882: "◸◹◺◿", + 886: "ШЩ", + 892: "œ", + 895: "Ы⚣⚤", + 896: "―", + 920: "ф⚊⚋⚌⚍⚎⚏", + 926: "Ŵ", + 931: "⁂", + 946: "Œ", + 951: "Ж", + 954: "⚮", + 958: "¬", + 971: "Ю", + 972: "Æ", + 979: "‱", + 980: "₧", + 993: ( + "₯℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∊∋∌∍∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡∢∣∤∥" + "∦∧∨∩∪∫∬∭∮∯∰∱∲∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟≠≡" + "≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝" + "⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙" + "⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰" + "⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤" + "┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱▴▵▶▷" + "▸▹►▻▼▽▾▿◀◁◂◃◄◅◈◉◊◌◍◎◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷" + "☀☁☂☃☄☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☙☚☛☝☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂" + "♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽⚀" + "⚁⚂⚃⚄⚅⚆⚇⚈⚉✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷" + "✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❙❚❛❜❝❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻" + "❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻" + "➼➽➾、。〃〄〇〜〝〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘" + "㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝" + "㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'" + "()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abc" + "defghijklmnopqrstuvwxyz{|}~⦅⦆¢£¬ ̄¦¥₩" + ), + 1024: "ſ⁜✀々〆〒〓〞〟", + 1036: "☜☞", + 1116: "⚯", + 1406: "◻◼◽◾☔☕☘♾♿⚒⚓⚔⚕⚖⚗⚙⚛⚜⚠⚡⚧⚪⚫⚰⚱", + }, + "한양중고딕": { + 1: "\u302a\u302b", + 195: "ıľ", + 198: "ī", + 200: "į", + 201: "ĵ", + 205: "Ī", + 212: "ìíîïĺļł", + 213: "⁏", + 220: "ĭ", + 226: "Į", + 227: "⁚⁝⁞", + 233: "ÌÍÎÏ", + 237: "¦", + 239: "¹", + 240: "ĩ", + 253: "Ĭİ", + 255: "ţťŧ", + 270: "´Ĩ", + 279: "ŀ", + 292: "‚‛", + 310: "ŕŗř", + 312: "˙", + 313: "·˚˛\uf09e\uf0a0", + 330: "¸", + 350: "¨", + 361: "º", + 363: "²", + 364: "³", + 371: "ª", + 375: "ˇ˘Ι„‟", + 384: "¼½", + 385: "¾ij\uf0fa", + 398: "ι", + 417: "⁎", + 438: "˝ζξ", + 457: "с", + 458: "\uf027\uf073\uf09f\uf0a7", + 463: "⁖", + 464: "з", + 466: "ŷ", + 468: "ÿ", + 469: "ýþ", + 470: "ð", + 477: "⚬", + 478: "ķ", + 480: "śŝşš", + 483: "¢çćĉċč\uf0f9", + 485: ( + "źżžε〿ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑→" + "↓○" + ), + 486: "υ⁑", + 487: "»", + 488: "«", + 497: "Ĵ", + 498: "ĸ", + 500: ( + "ао‧▮▯◤◥❙❚〖〗〘〙。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマ" + "ミムメモヤユヨラリルレロワン゙゚ᅠ\uf07f" + ), + 506: "э", + 509: "¯", + 511: "₫", + 515: "¿", + 517: "₰", + 520: "⁙", + 521: "р", + 522: "ρ", + 524: "Þ", + 526: "τ", + 529: "ñĝğġģĥńņňʼnŋ", + 531: "ùúûüďđũūŭůűų⁊\uf07d\uf07e", + 532: "èéêëēĕėęě", + 533: "⚘", + 534: "àáâãäåāăą", + 535: "ô", + 537: "З", + 538: "õ", + 539: "óöøōŏő", + 540: "ò", + 542: "δμοσеё", + 544: "α", + 547: "ν", + 548: "я", + 549: "ĹĻĽĿŁ₤\uf047\uf048", + 551: "⚨⚲", + 554: "\uf035", + 555: "⁒", + 556: "г", + 559: "ħ", + 560: "¥", + 561: "µ", + 562: "¶γ", + 563: "κх", + 565: "π", + 574: "б", + 576: "⚚", + 577: "у", + 578: "\uf077", + 580: "ь", + 585: "ßŹŻŽ", + 586: "ŢŤŦ", + 587: "\uf041", + 592: "¤", + 593: "ч", + 594: "в", + 595: "₦", + 601: "₠₪", + 603: "Ξ\uf036", + 605: "к", + 606: "₲", + 608: "₵", + 609: "£Ρ", + 610: "Γ", + 612: "Р", + 613: "₴", + 616: "Ь", + 617: "т", + 619: "ÝŊŶŸ", + 623: "η", + 624: "⁈", + 625: "ĶΖλωГ₣", + 626: "χ", + 632: "ÀÁÂÃÄÅĀĂĄ", + 634: "⁉", + 635: "Ş", + 636: "ŚŜŠ\uf0fb", + 637: "₱", + 640: "и", + 641: "⁘⁛", + 643: "§", + 645: "н", + 646: "⁋⁌⁍", + 649: "ÈÉÊËĒĔĖĘĚ", + 650: "Ч₭", + 651: "\uf053", + 652: "⁗", + 654: "Ββ₮", + 658: "Δ₧", + 659: "⚭", + 660: "\uf04e", + 661: "φ", + 662: "п", + 665: "₥", + 666: "₡₢", + 667: "ΕΥЁБВЕСЭЯ", + 670: "д", + 674: "\uf043\uf044", + 680: "⁕", + 681: "IJ", + 684: "ΧХ", + 686: "ĎĐц", + 688: "ÙÚÛÜŨŪŬŮŲъ", + 689: "ĤĦ", + 690: "Űψф", + 692: "ÑŃŅŇŔŖŘУ", + 693: "Ð\uf058", + 694: "⚥⚦", + 697: "ŵ", + 699: "ÇĆĈĊČ", + 700: "Πл\uf032\uf033", + 708: "ΘΟθО", + 711: "Т", + 716: "Τ", + 717: "Ω", + 720: "⚐⚑", + 723: "\uf057", + 736: "ΦЛФ", + 741: "Ψ", + 747: "\uf055\uf056\uf06c\uf06e\uf074", + 749: "ÒÓÔÕÖŌŎŐ", + 750: "ΑΗΚΛΝАИЙН►◄", + 751: "ĜĞĠĢ", + 762: "ж", + 764: "©®", + 769: "₳", + 770: "м", + 774: "♦", + 776: "\uf0e3\uf0e4\uf0e5\uf0e6", + 780: "П\uf069", + 781: "Σ", + 783: "\uf0f5\uf0f6\uf0f7\uf0f8", + 787: "Ø\uf0fc", + 793: "\uf042", + 794: "Д\uf059\uf0d7\uf0d8", + 795: "Ъ", + 796: "⁔", + 798: "ю", + 799: "⁐⚢", + 801: "Ц", + 802: "⁓", + 810: "₨", + 811: "\uf0f1\uf0f2\uf0f4", + 813: "К\uf054", + 829: "æ", + 833: "⁇", + 843: "\uf04a\uf04b\uf04c", + 844: "⚩", + 849: "\uf04f", + 861: "◸◹◺◿", + 872: "œ", + 873: "\uf0eb\uf0ec\uf0ed\uf0ee", + 874: "⚣⚤", + 875: "шы", + 880: "\uf052", + 885: "\uf05a", + 887: "\uf051", + 890: "щ", + 891: "\uf03b\uf03e\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0", + 893: "\uf029\uf034\uf03c\uf03d\uf049\uf05b\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0fd\uf0fe", + 894: "\uf025", + 896: "\uf05c", + 898: "⚊⚋⚌⚍⚎⚏", + 900: "Ы", + 904: "Ŵ", + 911: "\uf03f\uf040", + 912: "ΜМ", + 924: "Œ", + 929: "\uf066", + 932: "⚮", + 933: "\uf063", + 936: "¬", + 940: "\uf03a\uf062", + 943: "\uf045\uf046", + 947: "\uf038\uf064", + 950: "Æ", + 953: "\uf06d\uf0a6", + 963: "\uf060", + 970: ( + "₯∊∍≛⋍⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿▢▭▰▻◅◌◍◖◗◚◛◠◡◢◣◧◨◩◪◫◬◭◮◰◱◲◳◴◵◶◷☀☉☊☋☌☍☐☓☖☗" + "☙☚☛☠☡☣☤☥☦☧☩☪☫☬☭☸☹☾☿♁♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♢♰♱♲♳♴♵♶♷♸♹" + "♺♻♼♽⚀⚁⚂⚃⚄⚅⚆⚇⚈⚉✁✃✄✆✇✈✌✍✎✏✐✑✒✓✕✖✘✙✚✛✜✞✟✠✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸" + "✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❛❜❝❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❿➀➁➂➃➄➅➆➇" + "➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➝➞➟➠➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻➼➽➾〝〠〡〢〣〤〥〦〧〨〩" + "〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾⦅⦆¦" + ), + 980: "\uf0df\uf0e0", + 987: "\uf075", + 1000: ( + "¡ſːЖШЩЮй‐‑‒―‖‗†‡•‣․‥‱′″‴‵‶‷‸‹›‼‽‾‿⁀⁁⁂⁃⁄⁅⁆⁜⁴ⁿ₁₂₃₄₩€℉ℓ№℡™ΩÅ⅓⅔⅛" + "⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∋∌∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡∢∣∤∥∦∧∨∩∪∫∬∭∮∯∰∱∲" + "∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≜≝≞≟≠≡≢≣≤≥≦≧≨≩≪≫≬≭≮≯" + "≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫" + "⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨" + "⋩⋪⋫⋬⋭⋮⋯⋰⋱⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧ" + "ⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁" + "╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▪▫▬▱▴▵▶▷▸▹▼▽▾▿◀◁◂◃◈◉◊◎◐◑◒◓◔◕◘◙◜◝◞◟◦◯☁☂☃☄☇☈" + "☎☏☑☒☜☝☞☟☢☨☮☯☰☱☲☳☴☵☶☷☺☻☼☽♀♂♠♡♣♤♥♧♨♩♪♫♬♭♮♯✀✂✉✔✗✝✡❶❷❸❹❺❻❼❽❾➜➡、。" + "〃〄々〆〇【】〒〓〔〕〚〛〜〞〟㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮" + "㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰" + "㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:" + ";<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuv" + "wxyz{|}~¢£¬ ̄¥₩■\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4" + ), + 1025: "\uf065", + 1031: "\uf021", + 1036: "\uf0ff", + 1047: "\uf0c7\uf0c8\uf0c9\uf0ca", + 1051: "\uf06a", + 1054: "\uf05f", + 1060: "\uf078\uf079\uf0f3", + 1065: "\uf068", + 1067: "\uf0e7\uf0e8", + 1073: "\uf037", + 1078: "\uf039", + 1083: "\uf028", + 1089: "⚯\uf050", + 1091: "\uf061", + 1096: "\uf030\uf067", + 1111: "\uf04d", + 1133: "\uf02a\uf02b", + 1145: "\uf022", + 1156: "\uf05e", + 1171: "\uf02c\uf02d", + 1216: "\uf026", + 1253: "\uf0d5\uf0d6", + 1271: "\uf06b", + 1300: "\uf023", + 1373: "◻◼◽◾☔☕☘♾♿⚒⚓⚔⚕⚖⚗⚙⚛⚜⚠⚡⚧⚪⚫⚰⚱", + }, + "한양신명조": { + 1: "\u302a\u302b", + 213: "⁏", + 227: "⁚⁝⁞", + 250: "¦", + 265: "ĺļľł", + 269: "ìíîïĩīĭįı", + 292: "‚‛", + 297: "ª", + 301: "ĵ", + 312: "˙", + 313: "·¹˚˛\uf09e\uf0a0", + 337: "ÌÍÎÏĨĪĬĮİ", + 350: "¸", + 361: "ţťŧ", + 375: "ºˇ˘Ι", + 376: "´", + 380: "¨", + 383: "²³", + 385: "\uf0fa", + 390: "„‟", + 393: "ŀ", + 398: "ι", + 409: "ŕŗř", + 417: "⁎", + 421: "¼½¾", + 438: "Ĵ˝ζξ", + 455: "śŝşš", + 457: "с", + 458: "\uf027\uf073\uf09f\uf0a7", + 463: "źżž⁖", + 464: "з", + 477: "⚬", + 479: "¶", + 482: "çðćĉċč", + 483: "\uf0f9", + 485: "ε〿ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑→↓○", + 486: "§υ⁑", + 490: "èéêëēĕėęě", + 494: "¯", + 500: ( + "¢»¿ао‧▮▯◤◥❙❚〖〗〘〙。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフ" + "ヘホマミムメモヤユヨラリルレロワン゙゚ᅠ\uf07f" + ), + 501: "«", + 506: "э", + 509: "àáâãäåāăą", + 511: "₫", + 517: "₰", + 519: "òóôõöøōŏő", + 520: "£⁙", + 521: "р", + 522: "ρ", + 523: "µ", + 525: "ĸ", + 526: "τ", + 528: "ij", + 531: "⁊\uf07d\uf07e", + 533: "⚘", + 537: "З", + 542: "δμοσеё", + 543: "ďđ", + 544: "α", + 547: "ν", + 548: "я", + 549: "₤\uf047\uf048", + 551: "⚨⚲", + 553: "ß", + 554: "ĝğġģ\uf035", + 555: "⁒", + 556: "г", + 557: "ķ", + 560: "ùúûüĥħũūŭůűų", + 561: "¤ŷ", + 562: "γ", + 563: "κх", + 564: "ñńņňʼnŋ", + 565: "π", + 566: "ýþÿ", + 571: "¥", + 574: "б", + 576: "Þ⚚", + 577: "у", + 578: "\uf077", + 580: "ь", + 587: "\uf041", + 593: "ч", + 594: "в", + 595: "₦", + 597: "ŹŻŽ", + 601: "₠₪", + 603: "Ξ\uf036", + 605: "к", + 606: "₲", + 608: "₵", + 609: "Ρ", + 610: "Γ", + 612: "Р", + 613: "₴", + 616: "Ь", + 617: "т", + 622: "ŚŜŞŠ", + 623: "η", + 624: "⁈", + 625: "ΖλωГ₣", + 626: "χ", + 634: "⁉", + 636: "\uf0fb", + 637: "₱", + 640: "и", + 641: "⁘⁛", + 645: "ĹĻĽĿŁн", + 646: "⁋⁌⁍", + 650: "Ч₭", + 651: "\uf053", + 652: "⁗", + 654: "Ββ₮", + 658: "Δ₧", + 659: "⚭", + 660: "\uf04e", + 661: "φ", + 662: "п", + 665: "₥", + 666: "₡₢", + 667: "ΕΥЁБВЕСЭЯ", + 670: "д", + 672: "æ", + 674: "\uf043\uf044", + 677: "ÈÉÊËĒĔĖĘĚ", + 680: "⁕", + 684: "ΧХ", + 686: "ц", + 687: "Ç", + 688: "ъ", + 690: "ĆĈĊČψф", + 692: "У", + 693: "\uf058", + 694: "⚥⚦", + 700: "ŔŖŘΠл\uf032\uf033", + 708: "ΘΟθО", + 709: "Ŋ", + 711: "Т", + 716: "Τ", + 717: "Ω", + 720: "⚐⚑", + 723: "œ\uf057", + 736: "ΦЛФ", + 741: "Ψ", + 742: "ĜĞĠĢ", + 747: "\uf055\uf056\uf06c\uf06e\uf074", + 748: "ÒÓÔÕÖØŌŎŐ", + 749: "ÐĎĐ", + 750: "ΑΗΚΛΝАИЙН►◄", + 762: "ŶŸж", + 769: "₳", + 770: "ÙÚÛÜÝŢŤŦŨŪŬŮŰŲм", + 774: "IJ♦", + 776: "\uf0e3\uf0e4\uf0e5\uf0e6", + 777: "ÑŃŅŇ", + 780: "ĶП\uf069", + 781: "Σ", + 783: "\uf0f5\uf0f6\uf0f7\uf0f8", + 784: "ĤĦ", + 785: "©", + 787: "\uf0fc", + 788: "®", + 793: "\uf042", + 794: "ÀÁÂÃÄÅĀĂĄД\uf059\uf0d7\uf0d8", + 795: "Ъ", + 796: "⁔", + 798: "ю", + 799: "⁐⚢", + 801: "Ц", + 802: "⁓", + 810: "₨", + 811: "\uf0f1\uf0f2\uf0f4", + 813: "К\uf054", + 823: "ŵ", + 833: "⁇", + 843: "\uf04a\uf04b\uf04c", + 844: "⚩", + 849: "\uf04f", + 861: "◸◹◺◿", + 873: "\uf0eb\uf0ec\uf0ed\uf0ee", + 874: "⚣⚤", + 875: "шы", + 880: "\uf052", + 885: "\uf05a", + 887: "\uf051", + 890: "щ", + 891: "\uf03b\uf03e\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0", + 893: "\uf029\uf034\uf03c\uf03d\uf049\uf05b\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0fd\uf0fe", + 894: "\uf025", + 896: "\uf05c", + 898: "⚊⚋⚌⚍⚎⚏", + 900: "Ы", + 911: "\uf03f\uf040", + 912: "ΜМ", + 927: "Œ", + 929: "\uf066", + 932: "⚮", + 933: "\uf063", + 934: "Æ", + 940: "\uf03a\uf062", + 943: "\uf045\uf046", + 947: "\uf038\uf064", + 953: "\uf06d\uf0a6", + 963: "\uf060", + 970: ( + "₯∊∍≛⋍⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿▢▭▰▻◅◌◍◖◗◚◛◠◡◢◣◧◨◩◪◫◬◭◮◰◱◲◳◴◵◶◷☀☉☊☋☌☍☐☓☖☗" + "☙☚☛☠☡☣☤☥☦☧☩☪☫☬☭☸☹☾☿♁♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♢♰♱♲♳♴♵♶♷♸♹" + "♺♻♼♽⚀⚁⚂⚃⚄⚅⚆⚇⚈⚉✁✃✄✆✇✈✌✍✎✏✐✑✒✓✕✖✘✙✚✛✜✞✟✠✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸" + "✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❛❜❝❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❿➀➁➂➃➄➅➆➇" + "➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➝➞➟➠➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻➼➽➾〝〠〡〢〣〤〥〦〧〨〩" + "〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾⦅⦆¦" + ), + 980: "\uf0df\uf0e0", + 987: "\uf075", + 999: "¬", + 1000: ( + "¡ſːЖШЩЮй‐‑‒―‖‗†‡•‣․‥‱′″‴‵‶‷‸‹›‼‽‾‿⁀⁁⁂⁃⁄⁅⁆⁜⁴ⁿ₁₂₃₄₩€℉ℓ№℡™ΩÅ⅓⅔⅛" + "⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∋∌∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡∢∣∤∥∦∧∨∩∪∫∬∭∮∯∰∱∲" + "∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≜≝≞≟≠≡≢≣≤≥≦≧≨≩≪≫≬≭≮≯" + "≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫" + "⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨" + "⋩⋪⋫⋬⋭⋮⋯⋰⋱⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧ" + "ⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁" + "╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▪▫▬▱▴▵▶▷▸▹▼▽▾▿◀◁◂◃◈◉◊◎◐◑◒◓◔◕◘◙◜◝◞◟◦◯☁☂☃☄☇☈" + "☎☏☑☒☜☝☞☟☢☨☮☯☰☱☲☳☴☵☶☷☺☻☼☽♀♂♠♡♣♤♥♧♨♩♪♫♬♭♮♯✀✂✉✔✗✝✡❶❷❸❹❺❻❼❽❾➜➡、。" + "〃〄々〆〇【】〒〓〔〕〚〛〜〞〟㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮" + "㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰" + "㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:" + ";<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuv" + "wxyz{|}~¢£¬ ̄¥₩■\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4" + ), + 1025: "\uf065", + 1031: "\uf021", + 1034: "Ŵ", + 1036: "\uf0ff", + 1047: "\uf0c7\uf0c8\uf0c9\uf0ca", + 1051: "\uf06a", + 1054: "\uf05f", + 1060: "\uf078\uf079\uf0f3", + 1065: "\uf068", + 1067: "\uf0e7\uf0e8", + 1073: "\uf037", + 1078: "\uf039", + 1083: "\uf028", + 1089: "⚯\uf050", + 1091: "\uf061", + 1096: "\uf030\uf067", + 1111: "\uf04d", + 1133: "\uf02a\uf02b", + 1145: "\uf022", + 1156: "\uf05e", + 1171: "\uf02c\uf02d", + 1216: "\uf026", + 1253: "\uf0d5\uf0d6", + 1271: "\uf06b", + 1300: "\uf023", + 1373: "◻◼◽◾☔☕☘♾♿⚒⚓⚔⚕⚖⚗⚙⚛⚜⚠⚡⚧⚪⚫⚰⚱", + }, + "한양견고딕": { + 3: "\u302a\u302b", + 644: "˙", + 660: "\u0387", + 689: "ː", + 799: "ıľ", + 813: "ī", + 820: "į", + 824: "ĵ", + 840: "Ī", + 869: "ìíîïĺļł", + 873: "⁏", + 902: "ĭ", + 925: "Į", + 930: "⁚⁝⁞", + 955: "ÌÍÎÏ", + 971: "¦", + 979: "¹", + 983: "ĩ", + 1037: "Ĭİ", + 1045: "ţťŧ", + 1053: "˛", + 1082: "˚", + 1107: "´Ĩ", + 1143: "ŀ", + 1176: "Ι", + 1184: "․‧", + 1196: "‚‛", + 1271: "ŕŗř", + 1311: "⁴ⁿ₁₂₃₄", + 1353: "¸ι", + 1373: "‖′‵", + 1435: "¨", + 1479: "º", + 1487: "²", + 1491: "³", + 1512: "‣", + 1520: "ª", + 1536: "„‟", + 1545: "˘", + 1573: "¼½", + 1577: "¾ij", + 1581: "ˇ", + 1622: "‹›", + 1635: "•", + 1708: "⁎", + 1782: "˝", + 1796: "‡", + 1831: "τ‼", + 1868: "⁃", + 1901: "⁖", + 1908: "ŷ", + 1917: "ÿ", + 1921: "ýþ", + 1927: "ð", + 1934: "⁅⁆", + 1941: "″‶", + 1954: "⚬", + 1959: "ķ", + 1967: "śŝşš‽", + 1979: "¢çćĉċč", + 1987: ( + "źżž〿。「」、ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│" + "←↑→↓■○" + ), + 1992: "⁑", + 1995: "»", + 1999: "«", + 2036: "Ĵ", + 2041: "ĸ", + 2048: ( + "【】〔〕〖〗〘〙〚〛・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨ" + "ラリルレロワン゙゚ᅠ" + ), + 2053: "¡", + 2085: "¯", + 2094: "₫", + 2110: "¿", + 2118: "₰", + 2121: "её", + 2134: "⁙", + 2147: "Þδ", + 2151: "‸", + 2163: "‐‑", + 2167: "ñĝğġģĥńņňʼnŋ", + 2175: "ùúûüďđũūŭůűų⁊", + 2180: "èéêëēĕėęě", + 2184: "ζξ⚘", + 2189: "àáâãäåāăąсэ", + 2192: "ô", + 2196: "ν", + 2200: "β", + 2205: "õз", + 2208: "óöøōŏő", + 2212: "òх", + 2216: "у", + 2219: "μ", + 2249: "ĹĻĽĿŁь", + 2257: "⚨⚲", + 2261: "ρ", + 2274: "ε⁒", + 2285: "†", + 2290: "ħ", + 2294: "¥а", + 2298: "µ", + 2301: "¶", + 2320: "κ", + 2336: "οо₤", + 2339: "б", + 2343: "гт", + 2347: "γ", + 2360: "Ρ⚚", + 2372: "‗", + 2397: "ßŹŻŽ", + 2400: "ŢŤŦ", + 2405: "Β", + 2416: "η", + 2421: "υ", + 2425: "¤В", + 2429: "θ", + 2432: "‾", + 2438: "₦", + 2449: "к", + 2454: "в", + 2458: "φ", + 2462: "₠₪", + 2465: "З", + 2484: "Р₲", + 2491: "Ζря‴‷₵", + 2495: "£ΕЁБЕ", + 2507: "Γ", + 2511: "₴", + 2528: "χий", + 2536: "ÝŊŶŸ", + 2549: "Г", + 2556: "⁈", + 2560: "Ķ‒", + 2580: "ч", + 2589: "ÀÁÂÃÄÅĀĂĄ₣", + 2596: "ц⁉", + 2601: "Ş⁄", + 2606: "ŚŜŠ", + 2610: "₱", + 2622: "‥", + 2629: "ΚЯ⁘⁛", + 2634: "§", + 2648: "ΤТ⁋⁌⁍", + 2659: "ÈÉÊËĒĔĖĘĚЬ", + 2664: "₭", + 2671: "⁗", + 2680: "₮", + 2683: "н", + 2687: "€", + 2692: "σ", + 2697: "С", + 2700: "⚭", + 2704: "α", + 2708: "ΞЭ", + 2724: "лп₥", + 2729: "ψ⁁₡₢", + 2753: "К", + 2790: "IJ⁕", + 2809: "ĎĐ", + 2818: "ÙÚÛÜŨŪŬŮŲ", + 2823: "ĤĦ", + 2828: "Ű", + 2835: "ÑŃŅŇŔŖŘ", + 2839: "Ð", + 2844: "⚥⚦", + 2847: "Δм", + 2851: "ΘΟО", + 2855: "ŵΠ", + 2864: "ÇĆĈĊČ", + 2868: "Ч", + 2880: "ΥΧХ", + 2884: "ΑА", + 2896: "λ", + 2905: "ъ", + 2908: "д", + 2924: "πω", + 2933: "ΗΝН", + 2945: "ИЙ", + 2950: "⚐⚑", + 2954: "Ω", + 3008: "ПЦ", + 3011: "ΛЛ", + 3048: "Д", + 3057: "Ψ", + 3060: "ΦФ", + 3068: "ÒÓÔÕÖŌŎŐ", + 3073: "У", + 3077: "ĜĞĠĢ", + 3093: "Σ", + 3130: "©®", + 3150: "₳", + 3153: "‿⁀", + 3199: "ж", + 3224: "Ø", + 3232: "Ъ", + 3252: "₩", + 3257: "ю", + 3261: "⁔", + 3273: "⁐", + 3277: "⚢", + 3290: "⁓", + 3301: "ы", + 3317: "₨", + 3363: "ΜМ", + 3380: "шщ", + 3396: "æ", + 3412: "⁇", + 3457: "⚩", + 3527: "◸◹◺◿", + 3543: "ШЩ", + 3572: "œ", + 3581: "Ы⚣⚤", + 3584: "―", + 3680: "ф⚊⚋⚌⚍⚎⚏", + 3703: "Ŵ", + 3724: "⁂", + 3785: "Œ", + 3806: "Ж", + 3818: "⚮", + 3834: "¬", + 3883: "Ю", + 3893: "Æ", + 3916: "‱", + 3920: "₧", + 3973: ( + "₯℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∊∋∌∍∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡∢∣∤∥" + "∦∧∨∩∪∫∬∭∮∯∰∱∲∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟≠≡" + "≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝" + "⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙" + "⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰" + "⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤" + "┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱▴▵▶▷" + "▸▹►▻▼▽▾▿◀◁◂◃◄◅◈◉◊◌◍◎◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷" + "☀☁☂☃☄☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☙☚☛☝☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂" + "♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽⚀" + "⚁⚂⚃⚄⚅⚆⚇⚈⚉✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷" + "✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❙❚❛❜❝❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻" + "❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻" + "➼➽➾、。〃〄〇〜〝〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘" + "㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝" + "㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'" + "()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abc" + "defghijklmnopqrstuvwxyz{|}~⦅⦆¢£¬ ̄¦¥₩" + ), + 4096: "ſ⁜✀々〆〒〓〞〟", + 4146: "☜☞", + 4464: "⚯", + 5624: "◻◼◽◾☔☕☘♾♿⚒⚓⚔⚕⚖⚗⚙⚛⚜⚠⚡⚧⚪⚫⚰⚱", + }, + "휴먼옛체": { + 1: "\u302a\u302b", + 164: "\u0387", + 228: "ι", + 256: "¦", + 276: "‚‛", + 284: "Ι", + 296: "․‧⁚", + 298: "ìíîïįĵĺļ⁏⁝⁞", + 344: "‖‵", + 360: "ĩīĭ", + 374: "г", + 378: "‣", + 380: "„‟", + 384: "¯ÌÍÎÏĨĪĬĮİţſ", + 394: "ľ", + 404: "τ", + 406: "‹›", + 408: "•", + 426: "ŕŗř", + 448: "к", + 452: "ζ", + 456: "ε", + 458: "ξ‼", + 466: "⁃", + 470: "Ĵзт", + 482: "źżž", + 484: "⁅⁆", + 486: "‶", + 492: "‽", + 496: ( + "ť〿。「」、ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑" + "→↓■○" + ), + 498: "⁎⁑", + 512: ( + "¢£«»àáâãäåāăąćĉċčśŝşšγκλνсух〖〗〘〙〚〛・ヲァィゥェォャュョッーアイウエオカキクケコサシスセ" + "ソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚ᅠ" + ), + 522: "э", + 524: "₫", + 530: "₰", + 532: "ç", + 534: "чь", + 538: "χ‸", + 540: "‐‑", + 544: "в⁊", + 550: "⁖", + 554: "µèéêëñòóôõöùúûüēĕėęěĝğġģĥķńņňōŏőũūŭůűųГпя", + 560: "υ", + 564: "Γ", + 566: "н", + 568: "⁒", + 570: "δηθοаеорё", + 572: "ий⁕", + 582: "ρ", + 584: "₤", + 586: "бц⁗", + 590: "βμ", + 592: "α‗", + 596: "К", + 598: "ýÿŷдл", + 608: "‾", + 610: "₦", + 616: "₠₪", + 619: "З⁙", + 620: "₲", + 622: "‴‷₵", + 626: "ΖΤТ", + 628: "₴", + 632: "σ", + 634: "Σ", + 638: "⁈⁘", + 640: "ĹĻĽŚŜŞŠŹŻŽъ‒", + 648: "₣", + 650: "У⁄⁉", + 652: "₱", + 662: "⁋⁌⁍", + 664: "φ", + 666: "Ξ₭", + 670: "₮", + 672: "БЛЬ€", + 680: "₥", + 682: "¥ÈÉÊËÝĆĈĊČĒĔĖĘĚŔŖŘŶŸЧ⁁₡₢", + 684: "ΑΒΔΕΚΛΡΥΧЁАВЕРХ", + 686: "ж", + 690: "Ç", + 694: "ďД", + 700: "⁛", + 705: "м⁓", + 706: "π", + 726: "ÒÓÔÕÖĎĐĜĞĠĢŌŎŐ", + 730: "ψ", + 736: "ИЙПЭы", + 740: "ΗΝΠНСЯ", + 758: "Ц", + 766: "Ω", + 768: "ÀÁÂÃÄÅÑÙÚÛÜĀĂĄĤĶŃŅŇŢŤŨŪŬŮŰŲю", + 778: "Ф", + 788: "‿⁀⁔⁜₳", + 796: "ΘΟО", + 800: "ω", + 802: "©®", + 804: "¬", + 810: "ŵЪ", + 814: "₩", + 818: "Φ⁐", + 822: "ш", + 830: "₨", + 842: "фщ", + 854: "ΜМ", + 856: "Ψ", + 900: "⁇", + 906: "Ы", + 930: "⁂", + 938: "Ш", + 946: "Ж", + 960: "Щ", + 978: "‱", + 980: "₧", + 982: "Ŵ", + 994: ( + "₯∁∄∅∆∉∊∌∍∎∐−∓∔∕∖∗∘∙∛∜∟∡∢∣∤∦∭∯∰∱∲∳∶∷∸∹∺∻∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≓" + "≔≕≖≗≘≙≚≛≜≝≞≟≢≣≦≧≨≩≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊄⊅⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊚" + "⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗" + "⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿▢▪▫▬▭▮▯▰▱▴▵▸▹►▻▾▿◂◃◄" + "◅◉◊◌◍◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷◸◹◺◻◼◽◾◿☀☁☂☃☄☇☈☉☊" + "☋☌☍☐☑☒☓☔☕☖☗☘☙☚☛☝☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♁♃♄♅♆♇♈♉♊♋♌" + "♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♢♦♫♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚇⚈⚉⚊⚋⚌⚍⚎⚏⚐⚑⚒⚓" + "⚔⚕⚖⚗⚘⚙⚚⚛⚜⚠⚡⚢⚣⚤⚥⚦⚧⚨⚩⚪⚫⚬⚭⚮⚯⚰⚱⚲✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣" + "✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❙❚❛❜❝❞❡❢❣❤❥❦❧❨" + "❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧" + "➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻➼➽➾〄〇〜〝〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾⦅⦆¦" + ), + 1024: ( + "¡¤§¨ª²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝―†‡‥′″⁴ⁿ₁₂" + "₃₄℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥" + "⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎" + "┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊" + "╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭✀、。〃々〆【】〒〓〔〕〞〟㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉" + "㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎" + "㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊" + "㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRST" + "UVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" + ), + 1034: "Ю", + }, + "Times New Roman": { + 342: "⁄∕", + 410: "¦", + 448: "′‵", + 512: "\u00a0‧∙", + 551: "ίι", + 561: "∫", + 565: "ª", + 569: "ìíîïĩīĭįıĵĺļłţŧſ", + 575: "‖", + 614: "²³¹⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", + 635: "º", + 682: "¡¨\u00ad´¸ÌÍÎÏĨĪĬĮİŕŗřΙΪ‐‑‚‛․‹›‾", + 704: "ŀ", + 717: "•‣", + 797: "Ĵśŝşš", + 811: "ς", + 823: "τ", + 832: "ľ", + 848: "ζ", + 853: "″‴", + 860: "έε", + 875: "ť", + 905: "γ", + 909: "¿àáâãäåçèéêëāăąćĉċčēĕėęěźżžχ„‟", + 913: "ξ", + 926: "ν", + 928: "¶", + 965: "δ", + 981: "θ", + 993: "λ", + 1012: "◊", + 1013: "ŋ", + 1014: "ΰυ", + 1022: "ρ", + 1024: "¢£¤¥§«¯»ßðñòóôõöøùúûüýþÿđĝğġģĥħķĸńņňōŏőũūŭůűųŷο‒‗†‡€", + 1032: "κ", + 1034: "π", + 1042: "β", + 1071: "ήη", + 1073: "άα", + 1098: "μ", + 1104: "σ", + 1124: "√≈≠≤≥", + 1131: "ij", + 1139: "ÞŚŜŞŠΡfifl", + 1155: "¬−≡", + 1173: "‼", + 1180: "µ", + 1182: "φ", + 1184: "Γ", + 1192: "Σ", + 1229: "℮", + 1237: "ʼn", + 1251: "ÈÉÊËĒĔĖĘĚĹĻĽĿŁŢŤŦŹŻŽΕΖΤ", + 1282: "ψ", + 1317: "ΔΞ", + 1324: "ď", + 1348: "ω", + 1364: "‥", + 1366: "ÇæĆĈĊČŔŖŘΒ", + 1437: "Ŋ", + 1451: "IJ", + 1460: "∞", + 1479: "ÀÁÂÃÄÅÐÑÒÓÔÕÖØÙÚÛÜÝĀĂĄĎĐĜĞĠĢĤĦĶŃŅŇŌŎŐœŨŪŬŮŰŲŵŶŸΑΗΘΚΝΟΠΥΧΫ", + 1485: "Λ", + 1497: "Φ", + 1511: "Ψ", + 1522: "Ω", + 1536: "¼½¾⅓⅔⅛", + 1556: "©®", + 1821: "ÆŒΜ", + 1870: "℉", + 1933: "Ŵ₩", + 1954: "№", + 2007: "™", + 2048: "―↔", + 2713: "‱", + }, + "Arial": { + 342: "⁄∕", + 384: "′", + 455: "įĵĺļłſίι‚‛", + 532: "¦", + 561: "∫", + 569: "\u00a0ÌÍÎÏìíîïĨĩĪīĬĭĮİıţŧΙΪ∙", + 592: "․‧", + 597: "ľ", + 655: "₀₁₂₃₄₅₆₇₈₉", + 682: "¡¨\u00ad²³´¸¹ŕŗř„‟‹›‾⁰⁴⁵⁶⁷⁸⁹", + 684: "ŀ", + 686: "‵", + 717: "•", + 725: "″‴", + 748: "º", + 756: "‣", + 758: "ª", + 768: "ť", + 809: "τ", + 846: "‖", + 903: "ζ", + 909: "ij", + 913: "έε", + 917: "ξ", + 987: "ς", + 1012: "◊", + 1024: "çýÿćĉċčĴķĸśŝşšŷźżžγκλν‼fifl", + 1075: "χ", + 1081: "‐‑", + 1100: "¶", + 1120: "ΰυ", + 1124: "√≈≠≤≥", + 1128: "Γ", + 1131: "¯‗", + 1139: ( + "¢£¤¥§«»àáâãäåèéêëðñòóôõöùúûüþāăąđēĕėęěĝğġģĥħĹĻĽĿŁńņňŋōŏőũūŭů" + "űųήηθο‒†‡€" + ), + 1140: "δ", + 1165: "ρ", + 1178: "β", + 1180: "µμ", + 1184: "άα", + 1195: "≡", + 1196: "¬−", + 1229: "℮", + 1237: "ʼn", + 1251: "¿ßøŢŤŦŹŻŽΖΤ", + 1259: "ď", + 1264: "σ", + 1266: "Σ", + 1311: "‥", + 1328: "φ", + 1331: "Ξ", + 1366: "ÀÁÂÃÄÅÈÉÊËÝÞĀĂĄĒĔĖĘĚĶŚŜŞŠŶŸΑΒΕΚΡΥΧΫ", + 1368: "ΔΛ", + 1413: "π", + 1460: "ψ∞", + 1479: "ÇÐÑÙÚÛÜĆĈĊČĎĐĤĦŃŅŇŔŖŘŨŪŬŮŰŲŵΗΝΠ", + 1481: "Ŋ", + 1505: "IJ", + 1509: "©®", + 1531: "Ω", + 1593: "ÒÓÔÕÖØĜĞĠĢŌŎŐΘΟ", + 1599: "ω", + 1634: "Φ", + 1706: "Μ", + 1708: "¼½¾⅓⅔⅛", + 1711: "Ψ", + 1821: "æ", + 1933: "œŴ₩", + 1958: "‱", + 1987: "℉", + 2048: "ÆŒ―™↔", + 2197: "№", + }, + "Cambria": { + 234: "∕", + 420: "‚․", + 451: "\u00a0", + 453: "‛", + 506: "∙", + 529: "′", + 545: "ĵ", + 556: "ĺļ", + 569: "ìíîïĩīĭįı", + 572: "ſ", + 582: "ίι", + 583: "¨¯´¸", + 585: "¡", + 592: "‧", + 620: "‹›", + 628: "Ĵ", + 632: "ł", + 648: "¦", + 664: "ÌÍÎÏĨĪĬĮİΙΪ", + 680: "\u00ad‐‑", + 686: "‵", + 693: "ţ", + 723: "ŧ", + 738: "„", + 741: "‾", + 756: "‣", + 759: "‗", + 769: "‟", + 770: "ŀ", + 788: "ľ", + 819: "ζ", + 829: "ξ", + 834: "²³¹⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", + 847: "ŕŗř", + 854: "ª", + 865: "¿", + 871: "∫", + 876: "º", + 880: "śŝşš", + 881: "″", + 883: "ς", + 903: "¢çćĉċč", + 908: "•", + 909: "έε", + 923: "ť", + 931: "źżž", + 979: "τ", + 987: "ν", + 995: "χ", + 999: "«»èéêëēĕėęěλ", + 1000: "àáâãäåāăą", + 1012: "ĝğġģ", + 1016: "ŚŜŞŠ", + 1024: "§", + 1032: "ýÿŷ", + 1038: "γ", + 1055: "‼", + 1058: "†‡", + 1074: "ķ", + 1075: "δ", + 1079: "κ", + 1082: "£", + 1083: "‖", + 1086: "ð", + 1087: "òóôõöøĸōŏőο", + 1090: "ρ", + 1098: "Γ", + 1099: "ĹĻĽ", + 1101: "ŹŻŽΖ", + 1104: "◊", + 1105: "Ł", + 1108: "ΰυ", + 1112: "ήη", + 1114: "¤µij‒", + 1118: "μ", + 1120: "θ", + 1121: "þ", + 1122: "Σ", + 1128: "ŋ", + 1130: "ĥħ", + 1131: "ùúûüũūŭůűų", + 1134: "¬⁄−≈≠≤≥", + 1136: "đ", + 1137: "β", + 1143: "ñńņň", + 1152: "ÇĆĈĊČ", + 1163: "Ρ", + 1168: "ÝŶŸ", + 1170: "Χ", + 1171: "Ξσ", + 1175: "Þfl", + 1176: "άα", + 1178: "ÈÉÊËĒĔĖĘĚΕ", + 1189: "fi", + 1204: "¶", + 1214: "ŢŤŦΤ", + 1220: "Δ", + 1233: "π", + 1240: "ßΛ", + 1243: "‴", + 1244: "ΥΫ", + 1248: "¥", + 1251: "ĜĞĠĢ", + 1252: "Β", + 1272: "ŔŖŘ", + 1274: "Ŀ", + 1276: "ÀÁÂÃÄÅĀĂĄΑ", + 1287: "€", + 1289: "ĶΚ", + 1292: "IJ", + 1311: "‥", + 1327: "ÙÚÛÜŨŪŬŮŰŲ", + 1338: "ÒÓÔÕÖØŌŎŐΘΟ", + 1345: "√", + 1355: "Ď", + 1361: "ÐĐ", + 1381: "Π", + 1388: "ď", + 1391: "Ω™", + 1394: "ÑŃŅŇŊΝ", + 1406: "ĤΗ", + 1413: "ʼn", + 1416: "Ħ", + 1458: "φ", + 1473: "ψ", + 1530: "≡", + 1536: "―", + 1538: "ω", + 1541: "æ", + 1586: "ŵ", + 1603: "Ψ", + 1608: "Φ", + 1670: "Μ", + 1676: "œ", + 1742: "©®∞", + 1751: "℮", + 1772: "¼¾", + 1774: "Æ", + 1799: "℉", + 1800: "₩", + 1822: "½", + 1886: "↔", + 1887: "Ŵ", + 1901: "⅓⅔⅛", + 1902: "Œ", + 1958: "‱", + 2127: "№", + }, + "Constantia": { + 321: "⁄∕", + 454: "‚", + 514: "\u00a0", + 524: "¡∙", + 541: "ίι", + 543: "ĵ", + 552: "‛", + 575: "ĺļł", + 579: "ſ", + 580: "ìíîïĩīĭįı", + 592: "․‧", + 611: "ª", + 628: "‹›", + 640: "Ĵ", + 642: "•", + 678: "ºΪ", + 686: "‖′‵", + 692: "Į", + 694: "ľ", + 696: "ÌÍÎÏĨĪĬİΙ", + 706: "ŀ", + 721: "ŧ", + 723: "ţť", + 736: "\u00ad‐", + 738: "²³¹⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", + 742: "¦", + 756: "‣", + 758: "‟", + 784: "„", + 785: "ŕŗř", + 795: "∫", + 829: "śŝşš", + 840: "¨¯´¸", + 844: "®", + 846: "ζ", + 880: "¿", + 883: "ξ", + 897: "έε", + 907: "τ", + 915: "‼", + 929: "¢", + 944: "γ", + 945: "çćĉċč", + 953: "ς", + 965: "ν", + 971: "″", + 981: "èéêëēĕėęě", + 983: "àáâãäåāăąźżž", + 986: "ýÿŷ", + 991: "£", + 1016: "χ", + 1037: "ΰυ", + 1040: "ĝğġģ", + 1044: "ŚŜŞŠ", + 1048: "«»", + 1050: "δ", + 1056: "€", + 1073: "◊", + 1076: "¥", + 1081: "‑", + 1083: "θ", + 1095: "ķ", + 1100: "ĸ", + 1101: "ο", + 1102: "λ", + 1104: "ρ", + 1106: "§", + 1107: "òóôõöøōŏőκ", + 1122: "ð", + 1123: "ij", + 1124: "ήη", + 1126: "Γ", + 1130: "¤¬−≈≠≤≥", + 1131: "µ", + 1132: "†", + 1138: "ĹĻĽĿŁ", + 1140: "σ", + 1141: "þ", + 1147: "μ", + 1148: "β", + 1156: "ŋ", + 1158: "άα", + 1162: "đ", + 1166: "ùúûüũūŭůűų", + 1168: "π", + 1172: "¶", + 1182: "ŹŻŽΖ", + 1186: "‗", + 1187: "ĥħ", + 1189: "ÈÉÊËĒĔĖĘĚΕ", + 1191: "Ρ", + 1192: "ñńņň", + 1196: "fi", + 1198: "Þ", + 1201: "fl", + 1215: "ÝŶŸΥΫ", + 1217: "‾", + 1223: "Β", + 1229: "√", + 1232: "‡", + 1245: "‴", + 1247: "Σ", + 1250: "ß", + 1256: "ŢŤŦΤ", + 1279: "Ξ", + 1280: "‒", + 1281: "ď", + 1293: "ŔŖŘ", + 1311: "‥", + 1334: "ÇĆĈĊČ", + 1336: "IJ", + 1343: "Δ", + 1346: "Χ", + 1350: "ĶΚ", + 1375: "Λ", + 1381: "ÀÁÂÃÄÅĀĂĄΑψ", + 1411: "φ", + 1417: "ʼn", + 1435: "ĜĞĠĢ", + 1437: "™", + 1444: "ω", + 1481: "Φ", + 1499: "ŵ", + 1511: "æ", + 1523: "ÙÚÛÜŨŪŬŮŰŲ", + 1534: "ÑŃŅŇŊΝ", + 1538: "ÐĎĐ", + 1579: "Π", + 1620: "ĤĦΗ", + 1626: "Ω₩", + 1631: "©", + 1646: "Θ", + 1647: "ÒÓÔÕÖØŌŎŐΟ", + 1687: "¼½¾", + 1692: "œ", + 1707: "Ψ", + 1783: "∞", + 1839: "Æ", + 1850: "℮", + 1854: "Μ", + 1956: "№", + 1958: "‱", + 1987: "℉⅓⅔⅛↔≡", + 2022: "Œ", + 2088: "Ŵ", + 2103: "―", + }, + "Calibri": { + 452: "′", + 463: "\u00a0", + 470: "ìíîïĩīĭįıĺļ", + 490: "ĵ", + 497: "ſ", + 504: "¹₁", + 507: "ł", + 511: "‚‛", + 516: "ÌÍÎÏĨĪĬĮİΙΪ", + 517: "․∙", + 540: "ľ", + 562: "ίι", + 592: "‧", + 598: "´", + 627: "\u00ad‐", + 629: "¸", + 653: "Ĵ", + 657: "⁷₇", + 667: "¡", + 678: "⁵₅", + 685: "³₃", + 686: "ţ‵", + 688: "²₂", + 689: "⁄∕", + 694: "‹›", + 700: "ŧ", + 708: "ť", + 712: "ζ", + 714: "ŕŗř", + 731: "⁴₄", + 735: "⁶⁹₆₉", + 737: "⁸₈", + 749: "∫", + 756: "‣", + 765: "ŀ", + 770: "ξ", + 793: "τ", + 801: "śŝşš⁰₀", + 804: "¨", + 807: "¯", + 809: "źżž‖", + 820: "″", + 824: "ª", + 841: "ς", + 851: "Γ", + 856: "‟", + 857: "„", + 861: "ĹĻ", + 865: "º", + 866: "çćĉċčĽ", + 873: "χ", + 880: "Ł", + 914: "γ", + 919: "ν", + 927: "ýÿŷ", + 931: "ķĸκ", + 933: "έε", + 939: "Σ", + 941: "ŚŜŞŠ", + 948: "λ", + 949: "¿", + 959: "ŹŻŽΖ", + 960: "ij", + 964: "ĝğġģ", + 981: "àáâãäåāăą", + 998: "ÝŢŤŦŶŸΤΥΫ", + 1000: "ÈÉÊËĒĔĖĘĚΕ", + 1007: "Ξ", + 1019: "èéêëēĕėęě", + 1020: "¢¤¦§¬‗†‡•‾−√≈≠≡≤≥", + 1038: "£¥®‒€", + 1042: "ρ", + 1046: "◊", + 1049: "«»", + 1058: "ÞΡ", + 1063: "Χ", + 1064: "ĶΚ", + 1072: "δ", + 1076: "ðñùúûüþĥńņňŋũūŭůűų", + 1080: "ßòóôõöōŏőο", + 1081: "‑", + 1084: "øfifl", + 1088: "β", + 1089: "θσ", + 1091: "ħ", + 1092: "ÇĆĈĊČ", + 1100: "ήη", + 1109: "ΰυ", + 1112: "ŔŖŘ", + 1114: "Β", + 1118: "Ŀ", + 1126: "µμ", + 1130: "đ", + 1132: "π", + 1142: "‼", + 1156: "Δ", + 1162: "άα", + 1164: "ď", + 1170: "IJ", + 1173: "Λ", + 1185: "ÀÁÂÃÄÅĀĂĄΑ", + 1186: "ʼn", + 1188: "‴", + 1200: "¶", + 1260: "Ď", + 1276: "ĤΗΠ", + 1279: "ÐĐ", + 1287: "Ŋ", + 1292: "ĜĞĠĢ", + 1303: "¼", + 1311: "‥", + 1314: "ÙÚÛÜŨŪŬŮŰŲ", + 1322: "ÑŃŅŇΝ", + 1334: "φ", + 1344: "Ħ", + 1356: "ÒÓÔÕÖŌŎŐΘΟ", + 1359: "Ø", + 1360: "Ω", + 1363: "⅛", + 1375: "½", + 1383: "¾", + 1385: "⅓", + 1426: "ω", + 1444: "™", + 1449: "ψ", + 1464: "ŵ", + 1481: "⅔", + 1513: "℮", + 1536: "Ψ", + 1555: "Φ", + 1563: "Æ", + 1583: "æ", + 1709: "©", + 1740: "œ", + 1747: "∞", + 1751: "Μ", + 1775: "Œ", + 1822: "Ŵ₩", + 1854: "―", + 1958: "‱", + 1987: "℉", + 2099: "№", + 2638: "↔", + }, + "Georgia": { + 166: "⁄∕", + 400: "‛", + 464: "‚", + 494: "\u00a0", + 572: "∙", + 586: "ĺļł", + 592: "․‧", + 598: "ĵ", + 600: "ìíîïĩīĭįı", + 605: "ίι", + 613: "ſ", + 658: "′", + 678: "¡", + 686: "‖‵", + 707: "ţťŧ", + 756: "‣", + 758: "‟", + 766: "\u00ad", + 768: "¦", + 771: "ľ", + 798: "ÌÍÎÏĨĪĬĮİΙΪ", + 804: "•", + 827: "ζ", + 839: "ŕŗř", + 840: "„", + 850: "‹›", + 861: "ŀ", + 885: "śŝşš", + 903: "ξ", + 909: "źżž", + 913: "ς", + 923: "τ", + 930: "çćĉċč", + 959: "έε", + 967: "†‡", + 980: "¿", + 990: "èéêëēĕėęě", + 999: "λ", + 1008: "ýÿŷ", + 1023: "∫", + 1024: "§¨ª²³´¶¸¹º⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", + 1027: "ν", + 1032: "àáâãäåāăą", + 1037: "χ", + 1043: "ĝğġģ", + 1052: "γ", + 1059: "″", + 1060: "Ĵ", + 1081: "‐‑", + 1089: "ð", + 1097: "ķ", + 1098: "κ", + 1104: "òóôõöøōŏőδο", + 1108: "ΰυ", + 1115: "ĸ", + 1123: "ß", + 1137: "¢", + 1139: "θ", + 1142: "ρ", + 1145: "þ", + 1149: "ŚŜŞŠ", + 1150: "◊", + 1158: "β", + 1160: "µ", + 1169: "ήη", + 1170: "¤", + 1172: "ij", + 1173: "σ", + 1176: "đ", + 1178: "ùúûüũūŭůűų‼", + 1185: "ŋ", + 1186: "μ", + 1190: "«»", + 1192: "ĥħ", + 1193: "fi", + 1195: "Γ", + 1208: "fl", + 1210: "ñńņň", + 1224: "άα", + 1231: "π", + 1232: "ŹŻŽΖ", + 1236: "ĹĻĽĿŁΣ", + 1245: "‴", + 1249: "Ρ", + 1258: "Þ", + 1259: "¥", + 1260: "ÝŶŸΥΫ", + 1261: "℮", + 1267: "ŢŤŦΤ", + 1274: "£", + 1280: "‒", + 1311: "‥", + 1315: "ÇĆĈĊČ€", + 1317: "¬¯‗‾−≈≠≤≥", + 1320: "ʼn", + 1338: "ÈÉÊËĒĔĖĘĚΕ", + 1339: "Β", + 1353: "Δ", + 1362: "ď", + 1370: "√", + 1374: "ÀÁÂÃÄÅĀĂĄΑ", + 1380: "Λ", + 1420: "Ξ", + 1422: "ĶΚ", + 1425: "φ", + 1437: "ŔŖŘ", + 1455: "Χ", + 1464: "ω", + 1468: "∞", + 1485: "ĜĞĠĢ", + 1496: "ψ", + 1509: "æ", + 1510: "ŵ", + 1524: "ÒÓÔÕÖØŌŎŐΘΟ", + 1534: "ÐĎĐ", + 1549: "ÙÚÛÜŨŪŬŮŰŲ", + 1570: "Φ", + 1571: "ÑŃŅŇŊΝ", + 1595: "Ω", + 1626: "₩", + 1655: "Π", + 1669: "ĤĦΗ", + 1672: "œ", + 1755: "―", + 1791: "Ψ", + 1818: "IJ", + 1899: "Μ", + 1929: "©®", + 1930: "™", + 1958: "‱", + 1987: "℉⅓⅔↔≡", + 1988: "Æ", + 1998: "Ŵ", + 2044: "Œ", + 2150: "¼½¾⅛", + 2500: "№", + }, + "Verdana": { + 550: "‚‛", + 562: "ìíîïĩīĭįıĺļίι", + 582: "ł", + 592: "․‧", + 606: "ľ", + 615: "ſ", + 686: "‖‵", + 705: "ĵ", + 720: "\u00a0", + 740: "′⁄∕", + 745: "∙", + 756: "‣", + 806: "¡", + 807: "ţťŧ", + 862: "ÌÍÎÏĨĪĬĮİΙΪ", + 874: "ŕŗř", + 930: "¦\u00ad‹›", + 931: "Ĵ", + 937: "ζ", + 939: "ŀ", + 940: "„‟", + 1016: "τ", + 1030: "ξ", + 1040: "ς", + 1050: "έε", + 1067: "çćĉċčśŝşš", + 1076: "źżž", + 1081: "‐‑", + 1110: "²³¹⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", + 1117: "ªº¿•", + 1140: "ĹĻĽĿ", + 1141: "″‴", + 1150: "Ł", + 1160: "Γ", + 1208: "χ", + 1212: "ýÿķĸŷγκλν", + 1220: "èéêëēĕėęě", + 1230: "àáâãäåāăą", + 1235: "Ρ", + 1240: "Þ", + 1243: "òóôõöøōŏőο", + 1245: "δ", + 1253: "ð", + 1257: "ij", + 1260: "ÝŶŸΥΫ", + 1262: "ŢŤŦΤ", + 1270: "ßβ", + 1276: "þđĝğġģάα", + 1278: "θ", + 1279: "‼", + 1280: "ρfi", + 1282: "fl", + 1291: "ųσ", + 1293: "ΰυ", + 1295: "ÈÉÊËĒĔĖĘĚΕ", + 1296: "ñùúûüĥħńņňŋũūŭůűήη", + 1302: "¢£¤¥§¨¯´¶¸‒‗†‡‾€∫", + 1305: "π", + 1310: "μ", + 1311: "‥", + 1314: "µ", + 1320: "«»", + 1326: "ď", + 1329: "Ξ", + 1377: "Σ", + 1400: "ÀÁÂÃÄÅĀĂĄŚŜŞŠΑ", + 1403: "ŹŻŽΖΧ", + 1404: "ΒΛ", + 1419: "ĶΚ", + 1424: "ŔŖŘ", + 1430: "ÇĆĈĊČ", + 1440: "Δ", + 1470: "℮", + 1496: "ʼn", + 1499: "ÙÚÛÜŨŪŬŮŰŲ", + 1532: "ÑŃŅŇŊΝ", + 1539: "ĤĦΗΠ", + 1578: "Ď", + 1588: "ÐĐĜĞĠĢ", + 1612: "ÒÓÔÕÖØŌŎŐΘΟ", + 1618: "φ", + 1666: "ω", + 1676: "¬ŵΩ−√≈≠≡≤≥◊", + 1677: "Φ", + 1683: "ψ", + 1726: "Μ", + 1783: "IJΨ", + 1956: "æ", + 1958: "‱", + 1987: "℉⅓⅔↔", + 2000: "™", + 2010: "œ", + 2016: "Æ", + 2025: "Ŵ₩", + 2048: "©®¼½¾―⅛∞", + 2191: "Œ", + 2400: "№", + }, + "Tahoma": { + 317: "∕", + 432: "‚‛", + 468: "ìíîïĩīĭįıĺļίι", + 520: "ſ", + 558: "․", + 562: "ł", + 577: "ĵ", + 602: "′‵", + 620: "‧∙", + 640: "\u00a0", + 680: "¡", + 685: "ţ", + 695: "ŧ", + 738: "ŕŗř", + 739: "ľ", + 744: "\u00ad‐‑", + 764: "ÌÍÎÏĨĪĬĮİΙΪ", + 783: "¦‖", + 784: "‹›", + 801: "ζ", + 814: "„", + 822: "‟", + 853: "Ĵ", + 881: "ς", + 886: "⁄", + 887: "ξ", + 910: "źżž", + 912: "ŀ", + 914: "śŝşš", + 931: "•‣", + 932: "έε", + 945: "çćĉċč", + 956: "τ", + 959: "ť", + 970: "¿", + 972: "″‴", + 1010: "ª²³¹º⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", + 1018: "χ", + 1019: "ĹĻĽĿ", + 1020: "ýÿķĸŷγκλν", + 1039: "Γ", + 1056: "ij", + 1060: "Ł", + 1075: "àáâãäåāăą", + 1078: "èéêëēĕėęě", + 1086: "fl", + 1092: "fi", + 1112: "òóôõöøōŏőδο", + 1116: "‥", + 1118: "¢£¤¥§¨¯´¶¸ð‒‗†‡‾€∫", + 1123: "ß", + 1129: "Ρ", + 1130: "ρ", + 1132: "þĝğġģ", + 1136: "άαθ", + 1137: "β", + 1139: "Σ", + 1140: "ΰυ", + 1141: "ŚŜŞŠ", + 1142: "ñùúûüĥńņňŋũūŭůűųήη", + 1144: "‼", + 1145: "ŹŻŽΖ", + 1149: "ÈÉÊËĒĔĖĘĚΕ", + 1154: "π", + 1158: "Þ", + 1160: "Ξ", + 1163: "µμ", + 1174: "«»đ", + 1180: "ÝŶŸΥΫ", + 1184: "ħ", + 1189: "Χ", + 1191: "σ", + 1196: "ŢŤŦΤ", + 1204: "ĶΚ", + 1207: "Β", + 1222: "Λ", + 1228: "ÀÁÂÃÄÅĀĂĄΑ", + 1230: "ÇĆĈĊČ", + 1268: "Δ", + 1271: "ŔŖŘ", + 1296: "℮", + 1343: "ÙÚÛÜŨŪŬŮŰŲ", + 1367: "ÑĜĞĠĢŃŅŇŊΝ", + 1383: "ĤΗΠ", + 1389: "Ď", + 1407: "ď", + 1418: "ʼn", + 1430: "ÐĐ", + 1438: "Ω", + 1446: "φ", + 1449: "ÒÓÔÕÖØŌŎŐΘΟ", + 1463: "ψ", + 1465: "Ħ", + 1484: "ω", + 1490: "¬−√≈≠≡≤≥◊", + 1497: "IJ", + 1520: "ŵ", + 1533: "Φ", + 1578: "Μ", + 1625: "Ψ", + 1794: "™", + 1802: "æ", + 1847: "Ŵ₩", + 1861: "œ", + 1862: "―∞", + 1870: "Æ", + 1902: "©®", + 1926: "℉", + 2000: "Œ", + 2048: "¼½¾⅓⅛↔", + 2172: "⅔", + 2336: "№", + 3692: "‱", + }, + "Segoe UI": { + 354: "⁄∕", + 420: "¸", + 444: "∙", + 469: "‚‛′", + 490: "¦", + 494: "ſ", + 496: "ìíîïĩīĭįıĵĺļ", + 545: "ÌÍÎÏĨĪĬĮİΙΪ", + 546: "ίι", + 561: "\u00a0ł", + 578: "´", + 582: "¡", + 592: "․‧", + 629: "ľ", + 645: "ŀ", + 647: "‹›", + 686: "‵", + 694: "ţŧ", + 712: "ŕŗř", + 719: "¹⁴₁₄", + 731: "Ĵ", + 750: "²³⁰⁵⁶⁷⁸⁹₀₂₃₅₆₇₈₉", + 756: "‣", + 768: "†‡", + 772: "„‟″", + 803: "ª", + 819: "\u00ad‐‑", + 832: "•", + 848: "¨", + 850: "¯‗‾", + 869: "śŝşš", + 882: "º", + 897: "έε", + 901: "ť", + 905: "ζ", + 911: "ξ", + 918: "§¿", + 926: "źżž", + 938: "¶", + 940: "‖", + 943: "ς", + 946: "çćĉċč", + 964: "ĹĻĽĿŁ", + 966: "Γ", + 983: "‼", + 991: "ýÿŷ", + 998: "τ", + 1014: "ij", + 1018: "ķĸ", + 1020: "λ", + 1036: "«»ÈÉÊËĒĔĖĘĚΕ", + 1042: "àáâãäåāăą", + 1044: "Ξ", + 1053: "‴", + 1057: "Σ", + 1063: "γ", + 1071: "èéêëēĕėęě", + 1073: "ŢŤŦΤκ", + 1077: "ν", + 1088: "ŚŜŞŠ", + 1102: "χ", + 1104: "¢£¥‒€", + 1105: "∫", + 1114: "ß", + 1122: "β", + 1132: "ÝŶŸΥΫΰυ", + 1136: "fifl", + 1138: "¤", + 1145: "ð", + 1147: "ÞΡ", + 1159: "ñùúûüĥħńņňŋũūŭůűų", + 1168: "ŹŻŽΖ", + 1174: "Β", + 1177: "σ", + 1178: "ήη", + 1182: "µμ", + 1188: "ĶΚ", + 1195: "◊", + 1196: "δ", + 1200: "òóôõöøōŏőορ", + 1201: "θ", + 1204: "þ", + 1206: "đĝğġģ", + 1208: "Χ", + 1225: "ŔŖŘ", + 1229: "℮", + 1241: "ʼn", + 1258: "άα", + 1268: "ÇĆĈĊČ", + 1276: "IJ", + 1284: "π", + 1288: "Λ", + 1311: "‥", + 1320: "Δ", + 1321: "ÀÁÂÃÄÅĀĂĄΑ", + 1331: "√", + 1381: "ď", + 1401: "¬−≡", + 1403: "≈≠≤≥", + 1405: "ĜĞĠĢ", + 1407: "ÙÚÛÜŨŪŬŮŰŲ", + 1432: "φ", + 1436: "ÐĎĐ", + 1454: "ĤĦΗ", + 1460: "Π", + 1480: "ŵ", + 1524: "₩", + 1532: "ÑŃŅŇŊΝ", + 1536: "ψ", + 1544: "ÒÓÔÕÖØŌŎŐΘΟΦ", + 1546: "Ω", + 1583: "™", + 1589: "Ψ", + 1655: "ω", + 1673: "∞", + 1704: "æ", + 1762: "Æ", + 1765: "↔", + 1823: "©®", + 1839: "Μ", + 1856: "¼", + 1888: "⅓⅔⅛", + 1900: "œ", + 1906: "½Œ", + 1913: "Ŵ", + 1950: "¾", + 1958: "‱", + 1987: "℉", + 2048: "―", + 2298: "№", + }, + "Consolas": { + 592: "‧", + 686: "‵", + 756: "‣", + 1081: "‑", + 1126: ( + "\u00a0¡¢£¤¥¦§¨©ª«¬\u00ad®¯²³´µ¶¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞß" + "àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜ" + "ĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘ" + "řŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦ" + "ΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψω‐‒―‖‗‚‛„‟†‡•․′″‴‹›‼‾⁄⁰⁴⁵⁶" + "⁷⁸⁹₀₁₂₃₄₅₆₇₈₉₩€№™℮⅓⅔⅛↔−∕∙√∞∫≈≠≡≤≥◊fifl" + ), + 1311: "‥", + 1958: "‱", + 1987: "℉", + }, + "Courier New": { + 592: "․‧", + 655: "⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", + 686: "‖‵", + 756: "‣", + 1081: "‐‑", + 1229: ( + "\u00a0¡¢£¤¥¦§¨©ª«¬\u00ad®¯²³´µ¶¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞß" + "àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜ" + "ĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘ" + "řŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦ" + "ΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψω‒―‗‚‛„‟†‡•′″‴‹›‼‾⁄₩€№™℮⅓⅔" + "⅛↔−∕∙√∞∫≈≠≡≤≥◊fifl" + ), + 1311: "‥", + 1958: "‱", + 1987: "℉", + }, + "#신명조": { + 250: "¦", + 265: "ĺļľł", + 269: "ìíîïĩīĭįı", + 292: "‚‛", + 297: "ª", + 301: "ĵ", + 313: "¹", + 320: "⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉", + 337: "ÌÍÎÏĨĪĬĮİ", + 350: "¸", + 361: "ţťŧ", + 375: "\u00adºΙΪ", + 376: "´", + 380: "¨", + 383: "²³", + 390: "„‟", + 393: "ŀ", + 398: "ίι", + 409: "ŕŗř", + 421: "¼½¾", + 438: "Ĵζξ", + 455: "śŝşš", + 463: "źżž", + 479: "¶", + 482: "çðćĉċč", + 485: "έε", + 486: "§ΰυ", + 490: "èéêëēĕėęě", + 494: "¯", + 500: "¢»¿ς‧", + 501: "«", + 509: "àáâãäåāăą", + 519: "òóôõöøōŏő", + 520: "£", + 522: "ρ", + 523: "µ", + 525: "ĸ", + 526: "τ", + 528: "ij", + 542: "δμοσ", + 543: "ďđ", + 544: "άα", + 547: "ν", + 553: "ß", + 554: "ĝğġģ", + 557: "ķ", + 560: "ùúûüĥħũūŭůűų", + 561: "¤ŷ", + 562: "γ", + 563: "κ", + 564: "ñńņňʼnŋ", + 565: "π", + 566: "ýþÿ", + 571: "¥", + 576: "Þ", + 597: "ŹŻŽ", + 603: "Ξ", + 609: "Ρ", + 610: "Γ", + 622: "ŚŜŞŠ", + 623: "ήη", + 625: "Ζλω", + 626: "χ", + 645: "ĹĻĽĿŁ", + 654: "Ββ", + 658: "Δ", + 661: "φ", + 667: "ΕΥΫ", + 672: "æ", + 677: "ÈÉÊËĒĔĖĘĚ", + 684: "Χ", + 687: "Ç", + 690: "ĆĈĊČψ", + 700: "ŔŖŘΠ", + 708: "ΘΟθ", + 709: "Ŋ", + 716: "Τ", + 717: "Ω", + 723: "œ", + 736: "Φ", + 741: "Ψ", + 742: "ĜĞĠĢ", + 748: "ÒÓÔÕÖØŌŎŐ", + 749: "ÐĎĐ", + 750: "ΑΗΚΛΝ", + 762: "ŶŸ", + 770: "ÙÚÛÜÝŢŤŦŨŪŬŮŰŲ", + 774: "IJ", + 777: "ÑŃŅŇ", + 780: "Ķ", + 781: "Σ", + 784: "ĤĦ", + 785: "©", + 788: "®", + 794: "ÀÁÂÃÄÅĀĂĄ", + 823: "ŵ", + 912: "Μ", + 927: "Œ", + 934: "Æ", + 999: "¬", + 1000: "¡ſ‐‑‒―‖‗†‡•‣․‥‱′″‴‵‹›‼‾⁄⁴₁₂₃₄₩€℉№™℮⅓⅔⅛↔−∕∙√∞∫≈≠≡≤≥◊", + 1034: "Ŵ", + }, + "양재백두체B": { + 222: "ι", + 250: "¦", + 270: "‚‛", + 278: "Ι", + 287: "Ϊ", + 289: "․‧", + 291: "ìíîïįĵĺļ", + 320: "⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉", + 335: "‖‵", + 338: "ί", + 352: "ĩīĭ", + 369: "‣", + 370: "„‟", + 375: "¯ÌÍÎÏĨĪĬĮİţſ", + 384: "ľ", + 395: "τ", + 396: "‹›", + 399: "•", + 416: "ŕŗř", + 441: "ζ", + 446: "ε", + 447: "‼", + 448: "ξ", + 458: "Ĵ", + 470: "źżž", + 484: "ť", + 500: "¢£«»àáâãäåāăąćĉċčśŝşšγκλν", + 501: "ς", + 520: "ç", + 525: "χ", + 528: "‐‑", + 541: "µèéêëñòóôõöùúûüēĕėęěĝğġģĥķńņňōŏőũūŭůűų", + 547: "υ", + 551: "Γ", + 556: "ηθο", + 557: "δ", + 563: "έ", + 569: "ρ", + 575: "β", + 576: "μ", + 578: "α", + 579: "‗", + 583: "ýÿŷ", + 590: "ή", + 591: "ΰ", + 594: "‾", + 608: "‴", + 611: "ΖΤ", + 617: "σ", + 618: "Σ", + 625: "ĹĻĽŚŜŞŠŹŻŽ‒", + 635: "⁄", + 648: "φ", + 650: "Ξ", + 656: "€", + 666: "¥ÈÉÊËÝĆĈĊČĒĔĖĘĚŔŖŘŶŸ", + 667: "ΑΒΕΚΡΥΧ", + 668: "ΔΛά", + 674: "Ç", + 677: "ď", + 690: "π", + 703: "Ϋ", + 708: "ÒÓÔÕÖĎĐĜĞĠĢŌŎŐ", + 713: "ψ", + 722: "ΗΝΠ", + 748: "Ω", + 750: "ÀÁÂÃÄÅÑÙÚÛÜĀĂĄĤĶŃŅŇŢŤŨŪŬŮŰŲ", + 778: "ΘΟ", + 781: "ω", + 783: "©®", + 785: "¬", + 791: "ŵ", + 794: "₩", + 798: "Φ", + 833: "Μ", + 835: "Ψ", + 956: "‱", + 958: "Ŵ", + 970: "℮−∕∙≈◊", + 976: "↔≡", + 1000: ( + "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧ―†‡‥′″⁴₁₂₃₄℉№™⅓⅔" + "⅛√∞∫≠≤≥" + ), + }, + "양재참숯체B": { + 250: "¦", + 270: "‚‛", + 287: "ΙΪ", + 289: "․‧", + 291: "ìíîïįıĵĺļł", + 320: "⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", + 330: "ι", + 333: "´¸", + 335: "‖′‵", + 338: "ί", + 352: "ĩīĭ", + 359: "²³", + 368: "ŀ", + 369: "‣", + 370: "„‟", + 375: "\u00ad¯¹ÌÍÎÏĨĪĬĮİţŧſ", + 384: "ľ", + 396: "‹›", + 399: "•", + 416: "¡ŕŗř", + 438: "‡", + 447: "τ‼", + 458: "Ĵ", + 469: "ªº", + 470: "źżž", + 474: "″", + 484: "ť", + 500: "¢£¤§¨«»¿àáâãäåāăąćĉċčśŝşš", + 501: "ς", + 520: "ç", + 524: "δ", + 525: "ij", + 528: "‐‑", + 533: "ζξ", + 536: "ν", + 537: "β", + 541: "µèéêëðñòóôõöøùúûüþēĕėęěĝğġģĥħķĸńņňŋōŏőũūŭůűų", + 542: "μ", + 549: "đ", + 552: "ρ", + 555: "ε", + 558: "†", + 562: "¼½¾", + 563: "έ", + 566: "κ", + 570: "ο", + 573: "γ", + 576: "Ρ", + 579: "‗", + 583: "ýÿŷ", + 587: "Β", + 590: "ήη", + 591: "ΰυ", + 593: "θ", + 594: "‾", + 600: "φ", + 608: "Ζ‴", + 609: "Ε", + 612: "Γ", + 617: "χ", + 625: "¶ßĹĻĽŁŚŜŞŠŹŻŽ‒", + 635: "⁄", + 640: "‥", + 642: "Κ", + 646: "Τ", + 656: "€", + 657: "σ", + 660: "α", + 661: "Ξ", + 666: "¥ÈÉÊËÝÞĆĈĊČĒĔĖĘĚŔŖŘŶŸψ", + 667: "ʼn", + 668: "ά", + 674: "Ç", + 677: "ď", + 695: "Δ", + 696: "ΘΟ", + 697: "Π", + 703: "ΥΧΫ", + 704: "Α", + 707: "λ", + 708: "ÐÒÓÔÕÖØĎĐĜĞĠĢŌŎŐ", + 714: "πω", + 716: "ΗΝ", + 721: "Ω", + 735: "ĿΛ", + 741: "IJ", + 746: "Ψ", + 747: "Φ", + 750: "ÀÁÂÃÄÅÑÙÚÛÜĀĂĄĤĦĶŃŅŇŊŢŤŦŨŪŬŮŰŲ", + 755: "Σ", + 783: "©®", + 785: "¬", + 791: "ŵ", + 794: "₩", + 821: "Μ", + 829: "œ", + 845: "æ", + 875: "―", + 918: "Œ", + 956: "‱", + 958: "Ŵ", + 970: "℉№™℮⅓⅔⅛↔−∕∙√∞∫≈≠≡≤≥◊", + 1000: "Æ", + }, + "한컴 솔잎 M": { + 222: "ι", + 238: "¦", + 252: "′", + 270: "‚‛", + 278: "Ι", + 287: "´Ϊ", + 289: "․‧", + 320: "⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉", + 335: "‖‵", + 337: "¸", + 338: "ί", + 360: "²³¹₁₂₃", + 366: "ĺļľŀł", + 369: "‣", + 370: "ìíîïĩīĭįı„‟", + 375: "ĵ", + 378: "§⁴₄", + 395: "τ", + 396: "‹›", + 399: "•", + 405: "″", + 425: "ÌÍÎÏĨĪĬĮİ", + 436: "ţŧ", + 441: "ζ", + 446: "ε", + 447: "‼", + 448: "ξ", + 464: "ſ", + 474: "ª", + 476: "º", + 500: "γκλν", + 501: "ς", + 508: "‥", + 511: "\u00ad", + 522: "ť", + 525: "χ", + 528: "‐‑", + 542: "¨", + 547: "υ", + 551: "Γ", + 552: "Ĵ", + 556: "ηθο", + 557: "δ", + 563: "έ", + 569: "ρ", + 574: "źżž", + 575: "ŕŗřśŝşšβ", + 576: "μ", + 578: "α", + 579: "‗", + 585: "¶", + 590: "çćĉċčή", + 591: "ΰ", + 594: "‾", + 608: "‴", + 610: "èéêëēĕėęě", + 611: "ΖΤ", + 617: "σ", + 618: "Σ", + 625: "‒", + 635: "⁄", + 640: "ýÿŷ", + 648: "φ", + 650: "àáâãäåāăąΞ", + 660: "òóôõöøĝğġģōŏő", + 667: "ΑΒΕΚΡΥΧ", + 668: "¢ΔΛά", + 672: "ð", + 677: "¯", + 685: "µùúûüđũūŭůűų", + 686: "ij", + 690: "π", + 694: "¬", + 699: "ŹŻŽ", + 700: "ŚŜŞŠ", + 702: "þ", + 703: "Ϋ", + 710: "ñĥħńņňŋ", + 713: "ψ", + 718: "«»", + 722: "ΗΝΠ", + 723: "Þ", + 731: "ķĸ", + 739: "ĹĻĽĿŁ", + 748: "ÝŶŸΩ", + 757: "ŢŤŦ", + 765: "ÈÉÊËĒĔĖĘĚ", + 770: "ÇĆĈĊČ", + 778: "ΘΟ", + 781: "ω", + 790: "ŔŖŘ", + 791: "ÀÁÂÃÄÅĀĂĄ", + 794: "₩", + 798: "Φ", + 801: "ß", + 805: "ď", + 820: "ĤĦ", + 823: "ÑŃŅŇŊ", + 833: "Μ", + 835: "Ψ", + 840: "ÒÓÔÕÖØĎĐŌŎŐ", + 841: "Ð", + 843: "ĜĞĠĢ", + 850: "ÙÚÛÜŨŪŬŮŰŲ", + 856: "Ķ", + 864: "ʼn", + 870: "ŵ", + 900: "¡£¤¥©®¼½¾¿―†‡€℉№™⅓⅔⅛↔√∞∫≠≡≤≥", + 918: "IJ", + 956: "‱", + 970: "℮−∕∙≈◊", + 976: "Ŵ", + 978: "æ", + 985: "œ", + 1073: "Œ", + 1107: "Æ", + }, + "한컴 솔잎 B": { + 222: "ι", + 238: "¦", + 252: "′", + 270: "‚‛", + 278: "Ι", + 287: "´Ϊ", + 288: "¸", + 289: "․‧", + 320: "⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉", + 335: "‖‵", + 338: "ί", + 360: "²³¹₁₂₃", + 369: "‣", + 370: "„‟", + 378: "§⁴₄", + 380: "ĺļ", + 383: "ìíîïĩīĭįı", + 386: "ĵ", + 395: "τ", + 396: "‹›", + 399: "•", + 405: "″", + 441: "ζ", + 445: "ÌÍÎÏĨĪĬĮİ", + 446: "ε", + 447: "‼", + 448: "ξ", + 450: "ţŧ", + 472: "ŀ", + 474: "ª", + 476: "ºľ", + 481: "ł", + 494: "ſ", + 500: "γκλν", + 501: "ς", + 506: "‥", + 511: "\u00ad", + 525: "χ", + 526: "¨", + 528: "‐‑", + 534: "ť", + 547: "υ", + 551: "Γ", + 552: "Ĵ", + 556: "ηθο", + 557: "δ", + 563: "έ", + 569: "ρ", + 574: "źżž", + 575: "ŕŗřśŝşšβ", + 576: "μ", + 578: "α", + 579: "‗", + 585: "¶", + 590: "çćĉċčή", + 591: "ΰ", + 594: "‾", + 608: "‴", + 610: "èéêëēĕėęě", + 611: "ΖΤ", + 617: "σ", + 618: "Σ", + 625: "‒", + 635: "⁄", + 648: "φ", + 650: "àáâãäåýÿāăąŷΞ", + 660: "òóôõöøĝğġģōŏő", + 667: "ΑΒΕΚΡΥΧ", + 668: "¢ΔΛά", + 672: "ð", + 677: "¯", + 685: "µùúûüđũūŭůűų", + 690: "π", + 694: "¬", + 699: "ŹŻŽ", + 700: "ŚŜŞŠ", + 702: "þ", + 703: "Ϋ", + 704: "ij", + 710: "ñĥħńņňŋ", + 713: "ψ", + 718: "«»", + 722: "ΗΝΠ", + 723: "Þ", + 731: "ķĸ", + 739: "ĹĻĽĿŁ", + 748: "Ω", + 757: "ŢŤŦ", + 758: "ÝŶŸ", + 765: "ÈÉÊËĒĔĖĘĚ", + 770: "ÇĆĈĊČ", + 778: "ΘΟ", + 781: "©ω", + 790: "ŔŖŘ", + 791: "ÀÁÂÃÄÅĀĂĄ", + 794: "₩", + 796: "ď", + 798: "Φ", + 801: "ß", + 820: "ĤĦ", + 823: "ÑŃŅŇŊ", + 833: "Μ", + 835: "Ψ", + 840: "ÐÒÓÔÕÖØĎĐŌŎŐ", + 843: "ĜĞĠĢ", + 850: "ÙÚÛÜŨŪŬŮŰŲ", + 856: "Ķ", + 866: "ʼn", + 870: "ŵ", + 900: "¡£¤¥®¼½¾¿―†‡€℉№™⅓⅔⅛↔√∞∫≠≡≤≥", + 918: "IJ", + 956: "‱", + 963: "æ", + 970: "℮−∕∙≈◊", + 976: "Ŵ", + 985: "œ", + 1078: "Œ", + 1107: "Æ", + }, + "한컴 윤고딕 740": { + 222: "ι", + 240: "․", + 250: "ĺļ", + 252: "ìíı", + 259: "‚", + 267: "ÌÍİ", + 276: "Įį", + 278: "Ι", + 287: "Ϊ", + 288: "´′", + 289: "‧", + 296: "‛", + 338: "ί", + 345: "ſ", + 357: "ŕŗ", + 365: "ţŧ", + 369: "‣", + 370: "ĵ", + 373: "¸", + 379: "ř", + 380: "‵", + 395: "τ", + 400: "§²³¹⁴₁₂₃₄", + 408: "¦", + 420: "ł", + 440: "„″", + 441: "ζ", + 446: "ε", + 448: "ξ‹›", + 450: "‟", + 460: "⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉", + 462: "śŝşš", + 465: "ª", + 470: "º", + 473: "ľ", + 474: "ĨĩĬĭ", + 475: "ŀ", + 480: "ť", + 482: "ς", + 484: "îï", + 487: "ÎÏ", + 500: "γκλν", + 523: "Ĵ", + 525: "χ", + 528: "‑", + 536: "ijźżž", + 538: "çćĉċč", + 544: "¨", + 546: "ĸ", + 547: "υ", + 548: "ķ", + 551: "Γ", + 556: "ηθο", + 557: "δ", + 562: "ýÿŷ", + 563: "έ", + 564: "àáâãäåāăą", + 569: "ρ", + 575: "β", + 576: "μ", + 577: "Īī", + 578: "α", + 579: "ĹĻĽĿ‗", + 580: "èéêëēĕėęě", + 589: "ŚŜŞŠ", + 590: "ή", + 591: "ΰ", + 592: "ð", + 594: "‾", + 599: "ŢŤŦ", + 611: "ΖΤ", + 612: "‥", + 616: "ß", + 617: "ŹŻŽσ", + 618: "Σ", + 621: "ÝÞŶŸ", + 622: "µ", + 624: "ñĥńņňŋ", + 625: "‒", + 626: "ÈÉÊËòóôõöøĒĔĖĘĚōŏő", + 630: "\u00ad¯‐", + 631: "ĝğġģ", + 635: "⁄", + 641: "ùúûüũūŭůűų", + 646: "þ", + 648: "φ", + 650: "Ξ", + 667: "ΑΒΕΚΡΥΧ", + 668: "ΔΛά", + 669: "Ł", + 672: "Ķ", + 681: "ŔŖŘ", + 690: "π", + 703: "ÇĆĈĊČΫ", + 713: "ψ", + 722: "ΗΝΠ", + 726: "ÀÁÂÃÄÅĀĂĄ", + 728: "đħ", + 729: "ÙÚÛÜŨŪŬŮŰŲ", + 730: "¬", + 731: "Ď", + 732: "ÑŃŅŇŊ", + 734: "Đ", + 735: "Ĥ", + 739: "IJ", + 748: "Ω", + 751: "ĜĞĠĢ", + 774: "ď", + 778: "ΘΟ", + 779: "ʼn", + 780: "ŵ", + 781: "ω", + 794: "Ħ", + 798: "Φ", + 802: "ÒÓÔÕÖØŌŎŐ", + 833: "Μ", + 835: "Ψ", + 839: "Ð", + 886: "©®", + 915: "Ŵ", + 920: "¡¢£¤¥«¶»¼½¾¿Æ―‖†‡•‴‼₩€℉№™⅓⅔⅛↔√∞∫≈≠≡≤≥◊", + 948: "æœ", + 956: "‱", + 970: "℮−∕∙", + 982: "Œ", + }, + "HY동녘B": { + 228: "ι", + 276: "‚‛", + 285: "Ι", + 294: "Ϊ", + 296: "․‧", + 298: "įĵĺļ", + 328: "⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉", + 343: "‖‵", + 346: "ί", + 360: "ĩīĭ", + 378: "‣", + 379: "„‟", + 384: "ĨĪĬĮİţſ", + 393: "ľ", + 405: "τ", + 406: "‹›", + 409: "•", + 426: "ŕŗř", + 452: "ζ", + 457: "ε", + 458: "‼", + 459: "ξ", + 469: "Ĵ", + 481: "źżž", + 496: "ť", + 512: ( + "¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöùú" + "ûüýÿāăąćĉċčśŝşšγκλν" + ), + 513: "ς", + 538: "χ", + 541: "‐‑", + 554: "ēĕėęěĝğġģĥķńņňōŏőũūŭůűų", + 560: "υ", + 564: "Γ", + 570: "δηθο", + 577: "έ", + 583: "ρ", + 588: "fi", + 589: "β", + 590: "μ", + 592: "α", + 593: "‗", + 597: "ŷ", + 603: "fl", + 604: "ή", + 605: "ΰ", + 608: "‾", + 623: "‴", + 626: "ΖΤ", + 632: "σ", + 633: "Σ", + 640: "ĹĻĽŚŜŞŠŹŻŽ‒", + 650: "⁄", + 664: "φ", + 666: "Ξ", + 672: "€", + 682: "ĆĈĊČĒĔĖĘĚŔŖŘŶŸ", + 683: "ΑΒΕΚΡΥΧ", + 684: "ΔΛά", + 693: "ď", + 707: "π", + 720: "Ϋ", + 725: "ĎĐĜĞĠĢŌŎŐ", + 730: "ψ", + 740: "ΗΝΠ", + 766: "Ω", + 768: "ĀĂĄĤĶŃŅŇŢŤŨŪŬŮŰŲ", + 797: "ΘΟ", + 800: "ω", + 810: "ŵ", + 813: "₩", + 817: "Φ", + 853: "Μ", + 856: "Ψ", + 979: "‱", + 981: "Ŵ", + 993: "℮−∕∙≈◊", + 1024: ( + "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧ―†‡‥′″⁴₁₂₃₄℉№™⅓⅔" + "⅛↔√∞∫≠≡≤≥" + ), + }, + "HY수평선B": { + 228: "ι", + 276: "‚‛", + 285: "Ι", + 294: "Ϊ", + 296: "․‧", + 298: "įĵĺļ", + 328: "⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉", + 343: "‖‵", + 346: "ί", + 360: "ĩīĭ", + 378: "‣", + 379: "„‟", + 384: "ĨĪĬĮİţſ", + 393: "ľ", + 405: "τ", + 406: "‹›", + 409: "•", + 426: "ŕŗř", + 452: "ζ", + 457: "ε", + 458: "‼", + 459: "ξ", + 469: "Ĵ", + 481: "źżž", + 496: "ť", + 512: ( + "¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöùú" + "ûüýÿāăąćĉċčśŝşšγκλν" + ), + 513: "ς", + 538: "χ", + 541: "‐‑", + 554: "ēĕėęěĝğġģĥķńņňōŏőũūŭůűų", + 560: "υ", + 564: "Γ", + 570: "δηθο", + 577: "έ", + 583: "ρ", + 588: "fi", + 589: "β", + 590: "μ", + 592: "α", + 593: "‗", + 597: "ŷ", + 603: "fl", + 604: "ή", + 605: "ΰ", + 608: "‾", + 623: "‴", + 626: "ΖΤ", + 632: "σ", + 633: "Σ", + 640: "ĹĻĽŚŜŞŠŹŻŽ‒", + 650: "⁄", + 664: "φ", + 666: "Ξ", + 672: "€", + 682: "ĆĈĊČĒĔĖĘĚŔŖŘŶŸ", + 683: "ΑΒΕΚΡΥΧ", + 684: "ΔΛά", + 693: "ď", + 707: "π", + 720: "Ϋ", + 725: "ĎĐĜĞĠĢŌŎŐ", + 730: "ψ", + 740: "ΗΝΠ", + 766: "Ω", + 768: "ĀĂĄĤĶŃŅŇŢŤŨŪŬŮŰŲ", + 797: "ΘΟ", + 800: "ω", + 810: "ŵ", + 813: "₩", + 817: "Φ", + 853: "Μ", + 856: "Ψ", + 979: "‱", + 981: "Ŵ", + 993: "℮−∕∙≈◊", + 1024: ( + "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧ―†‡‥′″⁴₁₂₃₄℉№™⅓⅔" + "⅛↔√∞∫≠≡≤≥" + ), + }, + "MD이솝체": { + 256: "¦", + 276: "‚‛", + 294: "ΙΪ", + 296: "․‧", + 298: "ìíîïįıĵĺļł", + 328: "⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", + 338: "ι", + 341: "´¸", + 343: "‖′‵", + 346: "ί", + 360: "ĩīĭ", + 368: "²³", + 377: "ŀ", + 378: "‣", + 379: "„‟", + 384: "¯¹ÌÍÎÏĨĪĬĮİţŧſ", + 393: "ľ", + 406: "‹›", + 409: "•", + 426: "¡ŕŗř", + 449: "‡", + 458: "τ‼", + 469: "Ĵ", + 480: "ªº", + 481: "źżž", + 485: "″", + 496: "ť", + 512: "¢£¤§¨«»¿àáâãäåāăąćĉċčśŝşš", + 513: "ς", + 532: "ç", + 537: "δ", + 538: "ij", + 541: "‐‑", + 546: "ζξ", + 549: "ν", + 550: "β", + 554: "µèéêëðñòóôõöøùúûüþēĕėęěĝğġģĥħķĸńņňŋōŏőũūŭůűų", + 555: "μ", + 562: "đ", + 565: "ρ", + 568: "ε", + 571: "†", + 575: "¼½¾", + 577: "έ", + 580: "κ", + 584: "ο", + 587: "γ", + 588: "fi", + 590: "Ρ", + 593: "‗", + 597: "ýÿŷ", + 601: "Β", + 603: "fl", + 604: "ήη", + 605: "ΰυ", + 607: "θ", + 608: "‾", + 614: "φ", + 623: "Ζ‴", + 624: "Ε", + 627: "Γ", + 632: "χ", + 640: "¶ßĹĻĽŁŚŜŞŠŹŻŽ‒", + 650: "⁄", + 655: "‥", + 657: "Κ", + 662: "Τ", + 672: "€", + 673: "σ", + 676: "α", + 677: "Ξ", + 682: "¥ÈÉÊËÝÞĆĈĊČĒĔĖĘĚŔŖŘŶŸψ", + 683: "ʼn", + 684: "ά", + 690: "Ç", + 693: "ď", + 712: "Δ", + 713: "ΘΟ", + 714: "Π", + 720: "ΥΧΫ", + 721: "Α", + 724: "λ", + 725: "ÐÒÓÔÕÖØĎĐĜĞĠĢŌŎŐ", + 731: "πω", + 733: "ΗΝ", + 738: "Ω", + 753: "ĿΛ", + 759: "IJ", + 764: "Ψ", + 765: "Φ", + 768: "ÀÁÂÃÄÅÑÙÚÛÜĀĂĄĤĦĶŃŅŇŊŢŤŦŨŪŬŮŰŲ", + 773: "Σ", + 802: "©®", + 804: "¬", + 810: "ŵ", + 813: "₩", + 841: "Μ", + 849: "œ", + 865: "æ", + 896: "―", + 940: "Œ", + 979: "‱", + 981: "Ŵ", + 993: "℉№™℮⅓⅔⅛↔−∕∙√∞∫≈≠≡≤≥◊", + 1024: "\u00adÆ", + }, + "태 헤드라인D": { + 256: "¦", + 276: "‚‛", + 294: "ΙΪ", + 296: "․‧", + 298: "ìíîïįıĵĺļł", + 328: "⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", + 338: "ι", + 341: "´¸", + 343: "‖′‵", + 346: "ί", + 360: "ĩīĭ", + 368: "²³", + 377: "ŀ", + 378: "‣", + 379: "„‟", + 384: "\u00ad¯¹ÌÍÎÏĨĪĬĮİţŧſ", + 393: "ľ", + 406: "‹›", + 409: "•", + 426: "¡ŕŗř", + 449: "‡", + 458: "τ‼", + 469: "Ĵ", + 480: "ªº", + 481: "źżž", + 485: "″", + 496: "ť", + 512: "¢£¤§¨«»¿àáâãäåāăąćĉċčśŝşš", + 513: "ς", + 532: "ç", + 537: "δ", + 538: "ij", + 541: "‐‑", + 546: "ζξ", + 549: "ν", + 550: "β", + 554: "µèéêëðñòóôõöøùúûüþēĕėęěĝğġģĥħķĸńņňŋōŏőũūŭůűų", + 555: "μ", + 562: "đ", + 565: "ρ", + 568: "ε", + 571: "†", + 575: "¼½¾", + 577: "έ", + 580: "κ", + 584: "ο", + 587: "γ", + 588: "fi", + 590: "Ρ", + 593: "‗", + 597: "ýÿŷ", + 601: "Β", + 603: "fl", + 604: "ήη", + 605: "ΰυ", + 607: "θ", + 608: "‾", + 614: "φ", + 623: "Ζ‴", + 624: "Ε", + 627: "Γ", + 632: "χ", + 640: "¶ßĹĻĽŁŚŜŞŠŹŻŽ‒", + 650: "⁄", + 655: "‥", + 657: "Κ", + 662: "Τ", + 672: "€", + 673: "σ", + 676: "α", + 677: "Ξ", + 682: "¥ÈÉÊËÝÞĆĈĊČĒĔĖĘĚŔŖŘŶŸψ", + 683: "ʼn", + 684: "ά", + 690: "Ç", + 693: "ď", + 712: "Δ", + 713: "ΘΟ", + 714: "Π", + 720: "ΥΧΫ", + 721: "Α", + 724: "λ", + 725: "ÐÒÓÔÕÖØĎĐĜĞĠĢŌŎŐ", + 731: "πω", + 733: "ΗΝ", + 738: "Ω", + 753: "ĿΛ", + 759: "IJ", + 764: "Ψ", + 765: "Φ", + 768: "ÀÁÂÃÄÅÑÙÚÛÜĀĂĄĤĦĶŃŅŇŊŢŤŦŨŪŬŮŰŲ", + 773: "Σ", + 802: "©®", + 804: "¬", + 810: "ŵ", + 813: "₩", + 841: "Μ", + 849: "œ", + 865: "æ", + 896: "―", + 940: "Œ", + 979: "‱", + 981: "Ŵ", + 993: "℉№™℮⅓⅔⅛↔−∕∙√∞∫≈≠≡≤≥◊", + 1024: "Æ", + }, +} + +#: Advances Hancom Office 2024 lays italic glyphs out at, on the desktop, in the faces it draws italic in faces of +#: their own (in each face's units per em), where they differ from the regular ones: measured, not read from a +#: font file. The Windows Latin faces it draws italic in their installed italic faces. Italic glyphs in the other +#: faces Hancom slants in place, at their regular advances. +ITALIC_ADVANCES: dict[str, dict[int, str]] = { + "HCI Poppy": { + 284: "fijl", + 302: "/", + 340: "It", + 398: "ers", + 416: "c", + 454: "akoz", + 474: "bq", + 510: "\"?dghpvxy", + 568: "LSnu", + 624: "PT", + 684: "CK", + 740: "AGXw", + 796: "DHNOQm", + 910: "%", + 966: "MW", + }, + "한양중고딕": { + 191: "il", + 192: "j", + 221: "‘’", + 232: "|", + 235: "'`", + 240: ".;", + 241: ",I", + 242: ":", + 248: "[]", + 250: "ft", + 258: "/", + 275: ")", + 277: "\\", + 282: "(", + 300: "}", + 304: "r{", + 362: "*", + 368: "“”„‟", + 412: "\"", + 439: "^", + 457: "y", + 461: "Jx", + 464: "k", + 470: "v", + 471: "s", + 474: "c", + 475: "z", + 490: "0123456789_~", + 515: "+=?", + 518: "b", + 520: "$ghn", + 522: "dqu", + 523: "e", + 525: "#ap", + 529: "Lo", + 574: "Z", + 583: "F", + 608: "Y", + 615: "X", + 618: "B", + 620: "K", + 621: "AV", + 625: "PS", + 631: "&", + 637: "E", + 675: "U", + 676: "H", + 679: "NR", + 680: "D", + 684: "w", + 686: "C", + 735: "O", + 737: "G", + 740: "Q", + 788: "M", + 794: "m", + 851: "%", + 887: "W", + 980: "@", + }, + "한양신명조": { + 140: "\\", + 224: ".", + 241: "f", + 290: ",l", + 305: "j", + 310: "i", + 317: "'", + 322: "`", + 340: ":", + 348: "t", + 375: ";", + 383: "^", + 413: "(", + 417: ")", + 433: "I}", + 434: "{", + 441: "„‟", + 445: "r", + 472: "s", + 474: "c", + 482: "]", + 495: "#", + 499: "[", + 500: "*|", + 502: "a", + 508: "hx", + 513: "\"/", + 519: "y", + 524: "v", + 530: "e", + 534: "o", + 535: "z", + 539: "b", + 542: "k", + 544: "n", + 560: "u", + 564: "q", + 568: "p", + 573: "-=d", + 574: "+", + 583: "J", + 585: "?", + 618: "S", + 619: "g", + 655: "L", + 658: "$", + 708: "Z", + 716: "Y", + 720: "Tw", + 724: "", + 743: "V", + 746: "F", + 752: "E", + 754: "P", + 759: "R", + 763: "G", + 766: "B", + 769: "A", + 794: "O", + 798: "Q", + 807: "X", + 826: "D", + 840: "K", + 853: "U", + 864: "N", + 869: "%", + 881: "H", + 973: "&", + 999: "@", + 1024: "W", + 1050: "M", + }, + "한양견고딕": { + 1079: "'", + 1099: "`", + 2150: "-", + 2154: "+=", + 2874: ">", + 2966: "<", + }, + "Times New Roman": { + 438: "'", + 512: "·", + 563: "|¦", + 569: "fίι", + 570: "ŧ", + 661: "ŀ", + 682: ":;", + 733: "τ", + 745: "ľť", + 763: "․", + 797: "[]rz¡ŕŗřźżž", + 807: "έγε", + 819: "{}", + 829: "ζ", + 831: "ς", + 860: "\"‴", + 864: "^", + 877: "ξ", + 887: "λ", + 901: "χ", + 909: "JkvxyýÿĴķĸŷνⅴⅹ", + 940: "ΰυ", + 952: "δ", + 983: "κρ", + 987: "ŋ", + 1006: "θ", + 1010: "σ", + 1016: "ήη", + 1020: "β", + 1024: "?Sa¿àáâãäåā㹌ŜŞŠfifl", + 1025: "ij", + 1026: "π", + 1028: "μ", + 1071: "¶", + 1075: "άα", + 1133: "φ", + 1139: "LTYZÝĹĻĽĿŁŢŤŦŶŸŹŻŽΖΤΥΫ“”„‟", + 1165: "Γ", + 1182: "ʼn", + 1202: "Δ", + 1217: "Σ", + 1237: "Λ", + 1246: "ď", + 1251: "ABFPRVXÀÁÂÃÄÅÞĀĂĄŔŖŘΑΒΡΧⅤⅩ", + 1272: "ψ", + 1292: "‥", + 1300: "Ⅱ", + 1309: "Ξ", + 1366: "KNwÑĶŃŅŇœŵΚΝ", + 1382: "+<=>¬×−≡", + 1426: "Ŋ", + 1440: "Ψ", + 1446: "ω", + 1474: "ⅳ", + 1479: "m", + 1481: "Ω", + 1483: "ⅺ", + 1484: "ⅵ", + 1485: "ⅸ", + 1536: "IJ", + 1559: "Φ", + 1706: "MWŴΜ₩", + 1821: "—…", + 1844: "℉", + 1884: "@", + 1885: "Ⅳ", + 1908: "Ⅵ", + 1918: "Ⅲ", + 1931: "№", + 1933: "Œ", + 1942: "Ⅸ", + 1952: "Ⅺ", + 1988: "ⅻ", + 1989: "ⅶ", + 2009: "℃", + 2494: "ⅷ", + 2526: "Ⅶ", + 2570: "Ⅻ", + 2630: "Ⅷ", + 2745: "‱", + }, + "Arial": { + 455: "ĩīĭ", + 576: "ľ", + 725: "ť", + 766: "τ", + 819: "ŀ", + 900: "έε", + 915: "ξ", + 949: "ζ", + 996: "ς", + 1008: "λ", + 1111: "θ", + 1118: "χ", + 1122: "μ", + 1126: "ΰυ", + 1137: "ήη", + 1138: "δ", + 1168: "Γάα", + 1170: "β", + 1173: "ρ", + 1196: "≡", + 1228: "Σ", + 1235: "σ", + 1259: "ʼn", + 1280: "ď", + 1328: "Ξ", + 1336: "φ", + 1366: "Λ", + 1372: "π", + 1374: "Δ", + 1484: "Π", + 1490: "ψ", + 1502: "IJ", + 1558: "Ω", + 1595: "ω", + 1701: "Ψ", + 1714: "Φ", + 2218: "№", + }, + "Cambria": { + 221: "⁄", + 408: ",.‚․", + 437: "‘’‛", + 480: "'", + 494: "·", + 499: "′", + 530: ":;", + 546: "lĺļ", + 554: "`¨¯´¸", + 555: "iìíîïĩīĭįı", + 562: "ſ", + 574: "¡", + 578: "∙", + 588: "ίι", + 593: "‹›", + 599: "f", + 604: "ł", + 613: "JĴ", + 646: "|¦", + 653: "-\u00ad‐‑", + 656: "IÌÍÎÏĨĪĬĮİΙΪ", + 694: "[]", + 707: "tţ", + 719: "„", + 735: "ŧ", + 741: "ŀ", + 751: "“”", + 761: "()", + 767: "‟", + 768: "{}", + 773: "ľ", + 782: "sśŝşš", + 797: "\"", + 808: "²³¹⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", + 811: "ª", + 832: "º", + 834: "?r¿ŕŗř", + 850: "*", + 854: "ζ", + 861: "ς″", + 877: "ξ", + 883: "ť", + 887: "cçćĉċčέε", + 896: "¢", + 920: "x", + 921: "zźżž", + 936: "eèéêëēĕėęě", + 942: "vyýÿŷ", + 954: "/\\", + 958: "χ", + 960: "«»", + 961: "λ", + 973: "§", + 977: "ν", + 979: "γ", + 980: "τ", + 986: "SŚŜŞŠ", + 1000: "$", + 1010: "κ", + 1011: "†‡", + 1018: "kķ", + 1024: "δ", + 1025: "£", + 1028: "ĸ", + 1038: "oòóôõöøōŏőο", + 1042: "ð", + 1049: "ZŹŻŽΖ", + 1053: "‼", + 1067: "bþ", + 1068: "q", + 1070: "gĝğġģ", + 1071: "LĹĻĽ", + 1073: "dđΓΰυ", + 1077: "aàáâãäåā㹣Σρ", + 1079: "Fpβ", + 1081: "‖", + 1082: "+0123456789<=>^~¬±×÷−∕≈≠≤≥", + 1086: "hĥħ", + 1089: "ŋ", + 1094: "ήη", + 1096: "nuñùúûüńņňũūŭůűų", + 1100: "ij", + 1105: "CÇĆĈĊČ", + 1110: "μ", + 1112: "Ξθ", + 1116: "XΧ", + 1122: "YÝŶŸ", + 1128: "µ", + 1134: "¤", + 1135: "σ", + 1137: "PΡ", + 1143: "άα", + 1145: "ΥΫfl", + 1147: "Þ", + 1154: "fi", + 1160: "ß", + 1164: "EÈÉÊËĒĔĖĘĚΕ", + 1166: "¶", + 1171: "Δ", + 1175: "TŢŤŦΤ", + 1178: "V", + 1194: "π", + 1198: "GĜĞĠĢ", + 1205: "AÀÁÂÃÄÅĀĂĄΑΛ", + 1209: "RŔŖŘ", + 1221: "BΒ", + 1223: "‴", + 1227: "¥", + 1235: "KĶΚ", + 1238: "€", + 1241: "Ŀ", + 1269: "IJ", + 1273: "OQÒÓÔÕÖØŌŎŐΟ", + 1274: "Θ", + 1295: "UÙÚÛÜŨŪŬŮŰŲ", + 1305: "ď", + 1324: "DĎ™", + 1325: "Ω", + 1330: "ÐĐ", + 1350: "&Π", + 1361: "ʼn", + 1370: "HĤΗ", + 1374: "NÑŃŅŇŊΝ", + 1379: "Ħ", + 1386: "ψ", + 1389: "φ", + 1452: "æ", + 1472: "…", + 1481: "Φ", + 1489: "ω", + 1490: "wŵ", + 1509: "Ψ", + 1568: "√", + 1581: "œ", + 1622: "MΜ", + 1636: "m", + 1709: "Æ", + 1736: "℮", + 1739: "⅔", + 1743: "⅓", + 1757: "%¼¾", + 1769: "₩", + 1806: "½", + 1822: "■□", + 1836: "WŒŴ", + 1868: "⅛", + 1872: "▲", + 2048: "℃℉△◆◇●", + 2052: "№", + 2502: "‰", + }, + "Constantia": { + 386: "'", + 416: "‘’", + 445: "‚", + 483: " \u00a0", + 499: "·∙", + 520: "ίι", + 537: "jĵ", + 542: "ſ", + 552: "lĺļł", + 557: "iìíîïĩīĭįı", + 614: "‹›", + 616: "f", + 630: "1", + 638: "JĴ", + 652: "ª", + 653: "º", + 662: "ŀ", + 678: "Į", + 682: "∕", + 690: "ľ", + 692: "IÌÍÎÏĨĪĬİΙΪ", + 693: "-\u00ad‐", + 706: "\"", + 736: "“”", + 738: "tţť", + 751: "(", + 758: "ŧ", + 775: "„", + 792: "rŕŗř", + 797: "ζ", + 805: "/\\", + 818: "έε", + 825: "ξ", + 853: "ς", + 865: "sśŝşš", + 866: "τ", + 911: "γ", + 916: "eèéêëēĕėęě", + 921: "ν", + 936: "cvçćĉċč", + 942: "2", + 952: "5", + 961: "χ", + 983: "yýÿŷ", + 996: "zźżž", + 1009: "ΰυ", + 1010: "δ", + 1014: "«»", + 1016: "x", + 1025: "κ", + 1026: "θ", + 1028: "ο", + 1041: "gĝğġģ", + 1042: "λ", + 1043: "SŚŜŞŠ", + 1044: "q", + 1045: "ρ", + 1048: "kķ", + 1052: "aàáâãäåþāăą", + 1053: "b", + 1058: "ĸήη", + 1062: "4dđ", + 1069: "p", + 1072: "oòóôõöøōŏő", + 1079: "ð", + 1082: "F", + 1094: "ij", + 1101: "µ", + 1103: "Γμ", + 1108: "9", + 1111: "β", + 1114: "σ", + 1116: "ŋ", + 1117: "LĹĻĽĿŁ", + 1121: "π", + 1124: "άα", + 1127: "hĥħ", + 1136: "fi", + 1139: "uùúûüũūŭůűų", + 1142: "nñńņň", + 1155: "fl", + 1162: "ZŹŻŽΖ", + 1166: "EÈÉÊËĒĔĖĘĚΕ", + 1176: "PΡ", + 1181: "Þ", + 1200: "ď", + 1203: "BΒ", + 1209: "ß", + 1212: "YÝŶŸΥΫ", + 1232: "TŢŤŦΤ", + 1242: "Σ", + 1260: "Ξ", + 1277: "RŔŖŘ", + 1312: "ʼn", + 1316: "Δ", + 1318: "XΧ", + 1320: "CÇĆĈĊČ", + 1330: "IJφ", + 1344: "KĶΚ", + 1347: "Λ", + 1353: "AÀÁÂÃÄÅĀĂĄΑ", + 1365: "Vψ", + 1386: "ω", + 1387: "GĜĞĠĢ", + 1424: "wŵ", + 1437: "…", + 1473: "Φ", + 1487: "NÑŃŅŇŊ", + 1491: "æΝ", + 1496: "UÙÚÛÜŨŪŬŮŰŲ", + 1501: "&", + 1537: "DÐĎĐ", + 1560: "Π", + 1595: "OÒÓÔÕÖØŌŎŐΘΟ", + 1596: "Q", + 1597: "HĤĦΗ", + 1611: "œ", + 1637: "Ω", + 1687: "%", + 1691: "Ψ", + 1709: "m", + 1827: "MΜ", + 1840: "Æ", + 1854: "№", + 1976: "Œ", + 2055: "WŴ", + 2425: "‰", + }, + "Calibri": { + 702: "rŕŗř", + 787: "\\", + 794: "/", + 797: "sśŝşš", + 852: "cçćĉċč", + 882: "ª", + 913: "vγ", + 916: "yýÿŷ", + 926: "SŚŜŞŠ", + 978: "eèéêëēĕėęě", + 1038: "‖", + 1051: "oòóôõöōŏőο", + 1053: "abdghnpquàáâãäåñùúûüþāăąĝğġģĥńņňŋũūŭůűų", + 1066: "ħ", + 1070: "CÇĆĈĊČ", + 1076: "ήη", + 1081: "β", + 1102: "µμ", + 1128: "đ", + 1136: "ď", + 1144: "θ", + 1157: "άα", + 1165: "ʼn", + 1284: "Ŋ", + 1320: "NÑŃŅŇΝ", + 1339: "φ", + 1340: "OÒÓÔÕÖŌŎŐΟ", + 1344: "Θ", + 1347: "Ø", + 1360: "Q", + 1413: "…", + 1545: "æ", + 1556: "Φ", + 1620: "m", + 1668: "œ", + 1823: "WŴ₩", + 2093: "№", + }, + "Georgia": { + 294: "⁄∕", + 400: "‘’‚", + 575: "ίι", + 584: "lĺļł", + 596: "jĵ", + 603: "ſ", + 609: "iìíîïĩīĭįı", + 673: "f", + 711: "tţťŧ", + 786: ":;", + 790: "“”„", + 798: "ľ", + 822: "ζ", + 862: "ŀ", + 883: "sśŝşš", + 898: "ξ", + 903: "ς", + 920: "τ", + 929: "cçćĉċč", + 945: "rŕŗř", + 949: "έε", + 966: "eèéêëēĕėęě", + 1017: "7", + 1026: "x", + 1042: "γ", + 1081: "kķ", + 1100: "oòóôõöøōŏőο", + 1102: "vΰυ", + 1103: "δ", + 1110: "ß", + 1119: "ð", + 1129: "θ", + 1132: "þ", + 1134: "b", + 1137: "q", + 1138: "ĸκ", + 1146: "yýÿŷ", + 1152: "hĥħρ", + 1160: "β", + 1161: "µ", + 1166: "σ", + 1173: "agàáâãäåāăąĝğġģ", + 1178: "dđ", + 1179: "μ‼", + 1180: "ij", + 1184: "pŋήη", + 1195: "fi", + 1208: "nñńņň", + 1221: "¯‾", + 1225: "άα", + 1234: "fl", + 1236: "π", + 1288: "ʼn", + 1369: "Δ", + 1406: "ď", + 1450: "φ", + 1486: "ω", + 1496: "OQÒÔÕŌŎŐΘΟ", + 1507: "ψ", + 1565: "æ", + 1684: "wŵ", + 1690: "œ", + 1798: "IJ", + 1801: "m", + 2514: "‰", + }, + "Verdana": { + 562: "ł", + 1105: "⁰⁶⁹₀₆₉", + 1140: "Ł", + 1202: "kķĸ", + 1210: "vyýÿŷγν", + 1273: "gĝğġģ", + 1278: "ρ", + 1291: "ΰυ", + 1296: "ų", + 1308: "μ", + 1398: "AVÀÁÂÃÄÅĀĂĄΑ", + 1487: "Δ", + 1568: "DÐĎĐ", + 1669: "Φ", + 1955: "æ", + 1993: "m", + 2008: "œ", + 2026: "Æ", + 2028: "WŴ₩", + 3110: "‰", + }, + "Segoe UI": { + 270: "⁄∕", + 432: "‘’‚‛", + 446: ",.:;·", + 463: "'", + 492: "j|¦ĵ", + 530: "ilìíîïĩīĭįıĺļ", + 563: " \u00a0ł", + 600: "ſ", + 604: "fľ", + 623: "()[]{}", + 653: "¡", + 662: "tţŧ", + 709: "JĴ", + 715: "`¨¯´¸", + 727: "rŕŗř", + 745: "ť", + 750: "¹⁴", + 766: "\"“”„‟", + 770: "†‡", + 788: "₃", + 791: "\\", + 793: "₂", + 795: "₁", + 809: "sśŝşš", + 811: "/", + 829: "•", + 856: "*", + 881: "?¿", + 893: "cªçćĉċč", + 915: "º", + 932: "xς", + 936: "έε", + 937: "‖", + 940: "ξ", + 948: "LĹĻŁ", + 965: "ĽĿ", + 967: "Γ", + 969: "v", + 997: "eèéêëēĕėęě", + 1001: "Fτ", + 1004: "kķĸ", + 1018: "SŚŜŞŠ", + 1022: "EÈÉÊËĒĔĖĘĚΕ", + 1025: "ij", + 1037: "ν", + 1046: "κ", + 1053: "«»", + 1054: "‴", + 1069: "ð", + 1077: "TŢŤΤ", + 1096: "oòóôõöøōŏőο", + 1104: "∫", + 1106: "ß", + 1110: "abdgpqàáâãäåþāăąđĝğġģ", + 1116: "χ", + 1134: "fifl", + 1135: "YÝŶŸΥΫ", + 1139: "¤", + 1141: "hĥħ", + 1143: "uùúûüũūŭůűų", + 1147: "ρ", + 1149: "β", + 1151: "nñńņňŋ", + 1167: "ZŹŻŽΖ", + 1171: "θσ", + 1175: "µήημ", + 1178: "PÞΡ", + 1192: "RŔŖŘ", + 1194: "◊", + 1197: "ⅺ", + 1202: "ΰυ", + 1210: "XΧ", + 1221: "ď", + 1228: "KĶΚ", + 1230: "π", + 1268: "IJ", + 1282: "άα", + 1286: "V", + 1294: "AÀÁÂÃÄÅĀĂĄΑ", + 1309: "CÇĆĈĊČ", + 1343: "Λ", + 1360: "Δ", + 1403: "+<=>^~¬±×÷−≡", + 1409: "GĜĞĠĢ", + 1411: "UÙÚÛÜŨŪŬŮŰŲ", + 1449: "Π", + 1450: "HĤĦΗ", + 1458: "DÐĎĐⅻ", + 1475: "wŵ", + 1494: "φ", + 1507: "…", + 1538: "NÑŃŅŇŊΝ", + 1573: "ψ", + 1576: "&", + 1578: "Ω", + 1647: "ω", + 1655: "Ψ", + 1675: "MΜ", + 1686: "%", + 1692: "æ", + 1743: "œ", + 1751: "Æ", + 1757: "m", + 1862: "©", + 1876: "¼⅓⅔⅛", + 1892: "Œ", + 1903: "WŴ", + 1939: "½", + 1966: "@", + 1968: "¾", + 2359: "№", + 2482: "‰", + }, + "#신명조": { + 441: "„‟", + }, + "양재백두체B": { + 374: "τ", + 439: "ε", + 447: "ξ", + 463: "ζ", + 492: "λ", + 542: "θ", + 546: "χ", + 548: "μ", + 550: "υ", + 555: "η", + 556: "δ", + 570: "Γα", + 571: "β", + 573: "ρ", + 600: "Σ", + 603: "σ", + 648: "Ξ", + 652: "φ", + 667: "Λ", + 670: "π", + 671: "Δ", + 725: "Π", + 728: "ψ", + 761: "Ω", + 779: "ω", + 831: "Ψ", + 837: "Φ", + }, + "한컴 소망 M": { + 374: "τ", + 439: "ε", + 447: "ξ", + 463: "ζ", + 492: "λ", + 542: "θ", + 546: "χ", + 548: "μ", + 550: "υ", + 555: "η", + 556: "δ", + 570: "Γα", + 571: "β", + 573: "ρ", + 600: "Σ", + 603: "σ", + 648: "Ξ", + 652: "φ", + 667: "Λ", + 670: "π", + 671: "Δ", + 725: "Π", + 728: "ψ", + 761: "Ω", + 779: "ω", + 831: "Ψ", + 837: "Φ", + }, + "한컴 소망 B": { + 374: "τ", + 439: "ε", + 447: "ξ", + 463: "ζ", + 492: "λ", + 542: "θ", + 546: "χ", + 548: "μ", + 550: "υ", + 555: "η", + 556: "δ", + 570: "Γα", + 571: "β", + 573: "ρ", + 600: "Σ", + 603: "σ", + 648: "Ξ", + 652: "φ", + 667: "Λ", + 670: "π", + 671: "Δ", + 725: "Π", + 728: "ψ", + 761: "Ω", + 779: "ω", + 831: "Ψ", + 837: "Φ", + }, + "한컴 솔잎 M": { + 374: "τ", + 439: "ε", + 447: "ξ", + 463: "ζ", + 492: "λ", + 542: "θ", + 546: "χ", + 548: "μ", + 550: "υ", + 555: "η", + 556: "δ", + 570: "Γα", + 571: "β", + 573: "ρ", + 600: "Σ", + 603: "σ", + 648: "Ξ", + 652: "φ", + 667: "Λ", + 670: "π", + 671: "Δ", + 725: "Π", + 728: "ψ", + 761: "Ω", + 779: "ω", + 831: "Ψ", + 837: "Φ", + }, + "한컴 솔잎 B": { + 374: "τ", + 439: "ε", + 447: "ξ", + 463: "ζ", + 492: "λ", + 542: "θ", + 546: "χ", + 548: "μ", + 550: "υ", + 555: "η", + 556: "δ", + 570: "Γα", + 571: "β", + 573: "ρ", + 600: "Σ", + 603: "σ", + 648: "Ξ", + 652: "φ", + 667: "Λ", + 670: "π", + 671: "Δ", + 725: "Π", + 728: "ψ", + 761: "Ω", + 779: "ω", + 831: "Ψ", + 837: "Φ", + }, + "한컴 윤고딕 740": { + 374: "τ", + 439: "ε", + 447: "ξ", + 463: "ζ", + 486: "ς", + 492: "λ", + 542: "θ", + 546: "χ", + 548: "μ", + 550: "υ", + 555: "η", + 556: "δ", + 570: "Γα", + 571: "β", + 573: "ρ", + 600: "Σ", + 603: "σ", + 648: "Ξ", + 652: "φ", + 667: "Λ", + 670: "π", + 671: "Δ", + 725: "Π", + 728: "ψ", + 761: "Ω", + 779: "ω", + 831: "Ψ", + 837: "Φ", + }, + "HY동녘B": { + 383: "τ", + 450: "ε", + 458: "ξ", + 475: "ζ", + 504: "λ", + 556: "θ", + 559: "χ", + 561: "μ", + 563: "υ", + 569: "δη", + 584: "Γα", + 585: "β", + 587: "ρ", + 614: "Σ", + 618: "σ", + 664: "Ξ", + 668: "φ", + 683: "Λ", + 686: "π", + 687: "Δ", + 742: "Π", + 745: "ψ", + 779: "Ω", + 798: "ω", + 851: "Ψ", + 857: "Φ", + }, + "HY수평선B": { + 383: "τ", + 450: "ε", + 458: "ξ", + 475: "ζ", + 504: "λ", + 556: "θ", + 559: "χ", + 561: "μ", + 563: "υ", + 569: "δη", + 584: "Γα", + 585: "β", + 587: "ρ", + 614: "Σ", + 618: "σ", + 664: "Ξ", + 668: "φ", + 683: "Λ", + 686: "π", + 687: "Δ", + 742: "Π", + 745: "ψ", + 779: "Ω", + 798: "ω", + 851: "Ψ", + 857: "Φ", + }, + "HY태백B": { + 383: "τ", + 450: "ε", + 458: "ξ", + 475: "ζ", + 504: "λ", + 556: "θ", + 559: "χ", + 561: "μ", + 563: "υ", + 569: "δη", + 584: "Γα", + 585: "β", + 587: "ρ", + 614: "Σ", + 618: "σ", + 664: "Ξ", + 668: "φ", + 683: "Λ", + 686: "π", + 687: "Δ", + 742: "Π", + 745: "ψ", + 779: "Ω", + 798: "ω", + 851: "Ψ", + 857: "Φ", + }, +} + +#: Advances Hancom Office 2024 lays bold italic glyphs out at where they differ from the italic ones and a bold +#: italic glyph is not widened as a bold one is (see ``measure._BOLD_WIDER_FACES``): measured on the desktop. +BOLD_ITALIC_ADVANCES: dict[str, dict[int, str]] = { + "HCI Poppy": { + 444: "·", + 470: "°", + 682: "×", + 684: "±", + 690: "÷", + }, +} diff --git a/src/hwpx/form_fit/_glyph_table.json.gz b/src/hwpx/form_fit/_glyph_table.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..95312813f5c89a8a990ab3e28084cf1305406e3c GIT binary patch literal 66230 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�CO>`O4B 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%0Dn7$%@7X9C0ETSXo(P2v=S+{o=+C~ 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 literal 0 HcmV?d00001 diff --git a/src/hwpx/form_fit/_glyph_table.py b/src/hwpx/form_fit/_glyph_table.py index 14da79d6..75972876 100644 --- a/src/hwpx/form_fit/_glyph_table.py +++ b/src/hwpx/form_fit/_glyph_table.py @@ -1,12023 +1,75 @@ # SPDX-License-Identifier: Apache-2.0 -"""Design advances of glyphs beyond ``measure._GLYPHS``, per face, read from the fonts' ``hmtx`` and -``cmap`` tables: the KS X 1001 symbols and full-width forms, and the Latin-1, Latin Extended-A, General -Punctuation, Currency Symbols, Mathematical Operators, Geometric Shapes, Miscellaneous Symbols, Dingbats and -Halfwidth and Fullwidth Forms blocks (Hangul, Hanja and kana left out); for the symbol faces Wingdings and Symbol, the -private-use code points U+F020-F0FF their glyphs are stored at. A face lacking a glyph lays it out at its fallback -face's advance. The table is read from the font files, not written by hand, but for a few glyphs Hancom lays out -at an advance of its own (я in 한컴 고딕, for one), which they carry instead: 함초롬돋움's spacing modifier letters, -general punctuation but the quotation marks and currency symbols take 함초롬바탕's, and 휴먼명조, 휴먼고딕 and -HY헤드라인M carry the advances Hancom Office 2024 lays their glyphs out at where they differ from the font's (the -Greek and Cyrillic letters, and the glyphs they lack). 한컴돋움 carries only the glyphs Hancom Office 2024 lays -out at an advance of its own (the Latin letters and a few others) and takes the rest, its symbols, Greek, Cyrillic -and full-width forms, from 함초롬돋움 as a face lacking them does. 한컴 윤고딕 250 carries the advances Hancom -Office 2024 lays its glyphs out at, as measured, its Cyrillic letters left to its fallback. The Windows Latin faces -(Times New Roman, Arial, Cambria, Constantia, Calibri, Georgia, Verdana, Tahoma, Segoe UI, Consolas and Courier New) -carry the advances Hancom Office 2024 lays their glyphs out at, as measured on the desktop (no font file read): the -Latin-1, Latin Extended-A and Greek letters and common punctuation and symbols, the glyphs they lack at the advance -Hancom gives them all the same; other glyphs in them are left to the class averages. #신명조, 양재백두체B, -양재참숯체B, 한컴 소망 M and B, 한컴 솔잎 M and B and 한컴 윤고딕 740 (in 1000 units per em), and HY동녘B, HY수평선B, -HY태백B, MD이솝체, 궁서 and 태 헤드라인D (in 1024) carry the advances Hancom Office 2024 lays their Latin-1, -Latin Extended-A and Greek letters and common punctuation and symbols out at, as measured on the desktop the same way; -their Hangul syllables are an em, as in a face Hancom replaces with 한컴바탕. The twelve KoPub and KoPubWorld faces -carry, where they differ from the fonts', the advances Hancom Office 2024 lays their glyphs out at, as measured on the -desktop with the fonts installed: the glyphs the fonts lack (∙, ・, kana, Greek and Cyrillic letters among them) at -advances of its own, the same in every KoPub face, and the archaic jamo at nine tenths of the em -(``HANGUL_ADVANCES``). The Greek ano teleia (U+0387), outside the blocks read, carries the advance Hancom Office 2024 lays it out at in each face listed: the -face's own where it has one, else about a sixth of the em. Each text face's ascent and descent are here too, for -the line height of a paragraph that takes it from the font. +"""Design advances of glyphs beyond ``measure._GLYPHS``, per face, and the faces' line metrics. + +The tables are data: the KS X 1001 symbols, the full-width forms and the common Unicode blocks of each face, +read from the fonts' ``hmtx`` and ``cmap`` tables or measured as Hancom Office 2024 lays them out. They are +kept beside this module as ``_glyph_table.json.gz`` (gzip-compressed JSON, read once when this module is +imported), because as Python source they pass the size a plugin directory reads of one file. The readable +source, with where every face's values come from, is ``scripts/glyph_table_source.py`` in the python-hwpx +repository; ``scripts/build_glyph_table.py`` writes the data file from it and +``tests/test_glyph_table_data.py`` compares the two table by table. """ from __future__ import annotations +import gzip +import json +from importlib import resources +from typing import Any + +_DATA = "_glyph_table.json.gz" +_SCHEMA = "python-hwpx.glyph-table/v1" + + +def _load() -> dict[str, list[list[Any]]]: + """The tables of the data file: every one a list of ``[face, value]`` in the source's order.""" + + raw = resources.files(__package__).joinpath(_DATA).read_bytes() + payload = json.loads(gzip.decompress(raw).decode("utf-8")) + if payload.get("schema") != _SCHEMA: + raise ImportError(f"{_DATA} has schema {payload.get('schema')!r}, not {_SCHEMA!r}") + tables: dict[str, list[list[Any]]] = payload["tables"] + return tables + + +def _by_key(table: list[list[Any]]) -> dict[str, dict[int, Any]]: + """A table whose faces each hold ``[key, value]`` rows, as a dictionary of dictionaries.""" + + return {face: {key: value for key, value in rows} for face, rows in table} + + +_TABLES = _load() + #: Units per em of each face below. -UNITS_PER_EM: dict[str, int] = { - "바탕": 1024, - "바탕체": 1024, - "돋움": 1024, - "돋움체": 1024, - "굴림": 1024, - "굴림체": 1024, - "궁서": 1024, - "궁서체": 1024, - "한컴 고딕": 1000, - "함초롬바탕": 1000, - "함초롬돋움": 1000, - "맑은 고딕": 2048, - "Segoe UI Symbol": 2048, - "KoPub돋움체 Light": 1000, - "KoPub돋움체 Medium": 1000, - "KoPub돋움체 Bold": 1000, - "KoPub바탕체 Light": 1000, - "KoPub바탕체 Medium": 1000, - "KoPub바탕체 Bold": 1000, - "KoPubWorld돋움체 Light": 1000, - "KoPubWorld돋움체 Medium": 1000, - "KoPubWorld돋움체 Bold": 1000, - "KoPubWorld바탕체 Light": 1000, - "KoPubWorld바탕체 Medium": 1000, - "KoPubWorld바탕체 Bold": 1000, - "한컴 말랑말랑 Bold": 1000, - "한컴산뜻돋움": 1000, - "휴먼고딕": 1024, - "한컴돋움": 1024, - "HY울릉도M": 1024, - "HY울릉도B": 1024, - "HY중고딕": 1024, - "HY견고딕": 1024, - "HY신명조": 1024, - "HY태백B": 1024, - "HY그래픽": 1024, - "한컴바탕": 1024, - "한컴 윤고딕 230": 1000, - "한컴 윤고딕 240": 1000, - "한컴 윤고딕 250": 1000, - "한컴 윤고딕 720": 1000, - "한컴 윤고딕 760": 1000, - "한컴 윤체 L": 1000, - "한컴 소망 M": 1000, - "한컴 소망 B": 1000, - "한컴 백제 B": 1000, - "한컴 백제 M": 1000, - "한컴 바겐세일 B": 1000, - "한컴 바겐세일 M": 1000, - "새굴림": 1024, - "한컴 말랑말랑 Regular": 1000, - "MD개성체": 1024, - "휴먼명조": 1024, - "HY헤드라인M": 1024, - "Wingdings": 2048, - "Symbol": 2048, - "HY견명조": 1024, - "HY동녘M": 1024, - "HCI Poppy": 1024, - "HCI Hollyhock": 1024, - "한양중고딕": 1000, - "한양신명조": 1000, - "한양견고딕": 4096, - "휴먼옛체": 1024, - "신명 태명조": 2048, - "신명 견고딕": 1000, - "한양그래픽": 2048, - "Times New Roman": 2048, - "Arial": 2048, - "Cambria": 2048, - "Constantia": 2048, - "Calibri": 2048, - "Georgia": 2048, - "Verdana": 2048, - "Tahoma": 2048, - "Segoe UI": 2048, - "Consolas": 2048, - "Courier New": 2048, - "#신명조": 1000, - "양재백두체B": 1000, - "양재참숯체B": 1000, - "한컴 솔잎 M": 1000, - "한컴 솔잎 B": 1000, - "한컴 윤고딕 740": 1000, - "HY동녘B": 1024, - "HY수평선B": 1024, - "MD이솝체": 1024, - "태 헤드라인D": 1024, -} +UNITS_PER_EM: dict[str, int] = {face: units for face, units in _TABLES["UNITS_PER_EM"]} #: The face Hancom takes a glyph from when a face does not have it. -FALLBACK: dict[str, str] = { - "바탕": "함초롬바탕", - "궁서": "함초롬바탕", - "바탕체": "함초롬바탕", - "궁서체": "함초롬바탕", - "굴림체": "함초롬바탕", - "돋움체": "함초롬바탕", - "굴림": "함초롬돋움", - "돋움": "함초롬돋움", - "맑은 고딕": "함초롬돋움", - "한컴 고딕": "함초롬돋움", - "함초롬바탕": "Segoe UI Symbol", - "함초롬돋움": "Segoe UI Symbol", - "휴먼명조": "함초롬바탕", - "HY헤드라인M": "함초롬바탕", - "한컴산뜻돋움": "함초롬돋움", - "한컴돋움": "함초롬돋움", - "한컴 윤고딕 250": "함초롬돋움", - "HY중고딕": "함초롬바탕", - "HY견고딕": "함초롬바탕", - "HY신명조": "함초롬바탕", - "새굴림": "함초롬돋움", - "한컴 말랑말랑 Regular": "함초롬바탕", - "HY견명조": "함초롬바탕", - "HY동녘M": "함초롬바탕", - "HY울릉도M": "함초롬바탕", -} +FALLBACK: dict[str, str] = {face: other for face, other in _TABLES["FALLBACK"]} #: Each text face's ascent and descent (OS/2 usWinAscent, usWinDescent) in its units per em: a paragraph #: taking its line height from the font (``hh:paraPr@fontLineHeight``) makes its lines that tall. VERTICAL_METRICS: dict[str, tuple[int, int]] = { - "바탕": (879, 145), - "바탕체": (879, 145), - "궁서": (879, 145), - "궁서체": (879, 145), - "굴림": (879, 145), - "굴림체": (879, 145), - "돋움": (879, 145), - "돋움체": (879, 145), - "한컴 고딕": (1000, 300), - "함초롬바탕": (1070, 230), - "함초롬돋움": (1070, 230), - "맑은 고딕": (2229, 495), - "한컴산뜻돋움": (1000, 300), - "휴먼고딕": (880, 200), - "한컴돋움": (879, 145), - "HY울릉도M": (879, 145), - "HY울릉도B": (879, 145), - "HY중고딕": (879, 145), - "HY견고딕": (879, 145), - "HY신명조": (879, 145), - "HY태백B": (879, 145), - "HY그래픽": (879, 145), - "한컴바탕": (879, 145), - "한컴 윤고딕 230": (1103, 303), - "한컴 윤고딕 240": (1123, 300), - "한컴 윤고딕 720": (943, 253), - "한컴 윤고딕 760": (1039, 267), - "한컴 윤체 L": (1117, 246), - "한컴 소망 M": (1170, 280), - "한컴 소망 B": (1170, 279), - "한컴 백제 B": (1079, 262), - "한컴 백제 M": (1047, 265), - "한컴 바겐세일 B": (1062, 220), - "한컴 바겐세일 M": (1038, 230), - "새굴림": (879, 145), - "한컴 말랑말랑 Regular": (1040, 250), - "한컴 말랑말랑 Bold": (1040, 250), - "MD개성체": (879, 145), - "휴먼명조": (880, 200), - "HY헤드라인M": (879, 145), - "HY견명조": (879, 145), - "HY동녘M": (879, 145), + face: (ascent, descent) for face, (ascent, descent) in _TABLES["VERTICAL_METRICS"] } #: The line heights Hancom Office 2024 lays a line of one face and height out at, in a paragraph taking its line -#: height from the font, where they differ from its ascent and descent each rounded up (measured on the desktop at -#: every 50 HWPUNIT from 500 to 4000, no font file read): height -> line height. Other heights take the formula. -LINE_HEIGHTS: dict[str, dict[int, int]] = { - "한컴 고딕": { - 2600: 3379, 2650: 3444, 2700: 3509, 2750: 3574, 2800: 3639, 2850: 3704, 2900: 3769, 2950: 3834, - 3000: 3899, 3050: 3964, 3100: 4029, 3150: 4094, 3200: 4159, 3250: 4224, 3300: 4289, 3350: 4354, - 3400: 4419, 3450: 4484, 3500: 4549, 3550: 4614, 3600: 4679, 3650: 4744, 3700: 4809, 3750: 4874, - 3800: 4939, 3850: 5004, 3900: 5069, 3950: 5134, 4000: 5199, - }, - "함초롬바탕": { - 1100: 1431, 1200: 1561, 1300: 1691, 1400: 1821, 1500: 1951, 1600: 2082, 1700: 2212, 1800: 2342, - 1900: 2472, 2000: 2602, 2100: 2732, 2150: 2797, 2200: 2862, 2250: 2927, 2300: 2992, 2350: 3057, - 2400: 3122, 2450: 3187, 2500: 3252, 2550: 3317, 2600: 3382, 2650: 3447, 2700: 3512, 2750: 3577, - 2800: 3642, 2850: 3707, 2900: 3772, 2950: 3837, 3000: 3902, 3050: 3967, 3100: 4032, 3150: 4097, - 3200: 4163, 3250: 4228, 3300: 4293, 3350: 4358, 3400: 4423, 3450: 4488, 3500: 4553, 3550: 4618, - 3600: 4683, 3650: 4748, 3700: 4813, 3750: 4878, 3800: 4943, 3850: 5008, 3900: 5073, 3950: 5138, - 4000: 5203, - }, - "함초롬돋움": { - 1100: 1431, 1200: 1561, 1300: 1691, 1400: 1821, 1500: 1951, 1600: 2082, 1700: 2212, 1800: 2342, - 1900: 2472, 2000: 2602, 2100: 2732, 2150: 2797, 2200: 2862, 2250: 2927, 2300: 2992, 2350: 3057, - 2400: 3122, 2450: 3187, 2500: 3252, 2550: 3317, 2600: 3382, 2650: 3447, 2700: 3512, 2750: 3577, - 2800: 3642, 2850: 3707, 2900: 3772, 2950: 3837, 3000: 3902, 3050: 3967, 3100: 4032, 3150: 4097, - 3200: 4163, 3250: 4228, 3300: 4293, 3350: 4358, 3400: 4423, 3450: 4488, 3500: 4553, 3550: 4618, - 3600: 4683, 3650: 4748, 3700: 4813, 3750: 4878, 3800: 4943, 3850: 5008, 3900: 5073, 3950: 5138, - 4000: 5203, - }, - "맑은 고딕": { - 500: 665, 600: 798, 650: 865, 1150: 1531, 1300: 1731, 1550: 2063, 1600: 2130, 1650: 2197, - 1700: 2263, 1750: 2330, 1900: 2529, 2000: 2662, 2100: 2796, 2150: 2862, 2200: 2929, 2250: 2995, - 2300: 3061, 2350: 3128, 2450: 3261, 2500: 3327, 2550: 3395, 2600: 3461, 2650: 3527, 2700: 3594, - 2750: 3660, 2800: 3727, 2850: 3793, 2900: 3860, 2950: 3926, 3000: 3994, 3050: 4060, 3100: 4126, - 3150: 4193, 3200: 4259, 3250: 4326, 3300: 4392, 3350: 4459, 3400: 4525, 3450: 4593, 3500: 4659, - 3550: 4725, 3600: 4792, 3650: 4858, 3700: 4925, 3750: 4991, 3800: 5058, 3850: 5124, 3900: 5192, - 3950: 5258, 4000: 5324, - }, - "한컴산뜻돋움": { - 2600: 3379, 2650: 3444, 2700: 3509, 2750: 3574, 2800: 3639, 2850: 3704, 2900: 3769, 2950: 3834, - 3000: 3899, 3050: 3964, 3100: 4029, 3150: 4094, 3200: 4159, 3250: 4224, 3300: 4289, 3350: 4354, - 3400: 4419, 3450: 4484, 3500: 4549, 3550: 4614, 3600: 4679, 3650: 4744, 3700: 4809, 3750: 4874, - 3800: 4939, 3850: 5004, 3900: 5069, 3950: 5134, 4000: 5199, - }, - "휴먼고딕": { - 550: 580, 600: 633, 750: 791, 800: 844, 850: 896, 900: 949, 950: 1002, 1000: 1054, - 1050: 1107, 1100: 1160, 1150: 1213, 1200: 1265, 1250: 1318, 1300: 1371, 1350: 1424, 1400: 1476, - 1450: 1529, 1500: 1582, 1550: 1635, 1650: 1740, 1700: 1793, 1850: 1951, 1900: 2004, 2050: 2162, - 2100: 2215, 2250: 2373, 2300: 2426, 2450: 2584, 2500: 2636, 2550: 2689, 2600: 2742, 2650: 2795, - 2700: 2847, 2750: 2900, 2800: 2953, 2850: 3006, 2900: 3058, 2950: 3111, 3000: 3164, 3050: 3217, - 3100: 3269, 3150: 3322, 3350: 3533, 3400: 3586, 3550: 3744, 3600: 3797, 3750: 3955, 3800: 4008, - 3950: 4166, 4000: 4219, - }, - "한컴 윤고딕 230": { - 500: 702, 550: 773, 700: 984, 750: 1054, 800: 1124, 850: 1194, 900: 1264, 950: 1335, - 1050: 1476, 1100: 1546, 1150: 1616, 1200: 1686, 1250: 1756, 1300: 1827, 1350: 1897, 1400: 1968, - 1450: 2038, 1500: 2108, 1550: 2178, 1600: 2248, 1650: 2319, 1700: 2389, 1750: 2459, 1800: 2530, - 1850: 2600, 1900: 2670, 1950: 2740, 2000: 2810, 2050: 2881, 2100: 2951, 2150: 3021, 2200: 3092, - 2250: 3162, 2300: 3232, 2350: 3302, 2400: 3373, 2450: 3443, 2500: 3513, 2550: 3583, 2600: 3654, - 2650: 3724, 2700: 3794, 2750: 3865, 2800: 3935, 2850: 4005, 2900: 4075, 2950: 4145, 3000: 4216, - 3050: 4286, 3100: 4356, 3150: 4427, 3200: 4497, 3250: 4567, 3300: 4637, 3350: 4708, 3400: 4778, - 3450: 4848, 3500: 4919, 3550: 4989, 3600: 5059, 3650: 5129, 3700: 5199, 3750: 5270, 3800: 5340, - 3850: 5411, 3900: 5481, 3950: 5551, 4000: 5621, - }, - "한컴 윤고딕 240": { - 700: 996, 750: 1067, 800: 1138, 1050: 1494, 1100: 1565, 1350: 1921, 1400: 1992, 1450: 2063, - 1700: 2419, 1750: 2490, 1800: 2561, 2050: 2917, 2100: 2988, 2350: 3344, 2400: 3415, 2450: 3486, - 2600: 3699, 2650: 3770, 2700: 3841, 2750: 3912, 2800: 3984, 2850: 4055, 2900: 4126, 2950: 4197, - 3000: 4268, 3050: 4339, 3100: 4410, 3150: 4482, 3200: 4553, 3250: 4624, 3300: 4695, 3350: 4766, - 3400: 4837, 3450: 4909, 3500: 4980, 3550: 5051, 3600: 5122, 3650: 5193, 3700: 5264, 3750: 5335, - 3800: 5407, 3850: 5478, 3900: 5549, 3950: 5620, 4000: 5691, - }, - "한컴 윤고딕 720": { - 500: 598, 550: 658, 650: 777, 700: 837, 800: 957, 850: 1017, 950: 1136, 1100: 1316, - 1250: 1495, 1350: 1615, 1400: 1675, 1500: 1794, 1550: 1854, 1700: 2034, 1800: 2153, 1850: 2213, - 2000: 2393, 2100: 2512, 2200: 2631, 2300: 2752, 2350: 2811, 2400: 2871, 2500: 2990, 2600: 3111, - 2700: 3230, 2800: 3349, 3000: 3589, 3050: 3648, 3100: 3708, 3150: 3769, 3300: 3948, 3350: 4007, - 3400: 4067, 3450: 4128, 3600: 4307, 3700: 4426, 4000: 4785, - }, - "한컴 윤고딕 760": { - 500: 653, 550: 718, 600: 783, 650: 848, 700: 914, 750: 979, 800: 1044, 850: 1110, - 900: 1175, 950: 1240, 1050: 1371, 1100: 1436, 1150: 1502, 1200: 1567, 1250: 1632, 1300: 1698, - 1350: 1763, 1400: 1828, 1450: 1894, 1500: 1959, 1550: 2024, 1600: 2090, 1650: 2154, 1700: 2219, - 1750: 2285, 1800: 2350, 1850: 2415, 1900: 2481, 1950: 2546, 2000: 2611, 2050: 2677, 2100: 2742, - 2150: 2807, 2200: 2873, 2250: 2938, 2300: 3003, 2350: 3069, 2400: 3134, 2450: 3199, 2500: 3265, - 2550: 3330, 2600: 3395, 2650: 3460, 2700: 3525, 2750: 3590, 2800: 3655, 2850: 3721, 2900: 3786, - 2950: 3851, 3000: 3917, 3050: 3982, 3100: 4047, 3150: 4113, 3200: 4178, 3250: 4243, 3300: 4309, - 3350: 4374, 3400: 4439, 3450: 4505, 3500: 4570, 3550: 4635, 3600: 4701, 3650: 4766, 3700: 4831, - 3750: 4896, 3800: 4961, 3850: 5026, 3900: 5092, 3950: 5157, 4000: 5222, - }, - "한컴 윤체 L": { - 550: 749, 600: 818, 650: 886, 700: 954, 850: 1159, 900: 1226, 950: 1295, 1050: 1431, - 1200: 1636, 1250: 1704, 1300: 1772, 1350: 1840, 1550: 2113, 1650: 2249, 1700: 2317, 1850: 2522, - 2050: 2794, 2200: 2999, 2350: 3203, 2700: 3680, 2850: 3885, 3000: 4090, 3700: 5045, 3850: 5248, - 4000: 5453, - }, - "한컴 소망 M": { - 550: 797, 650: 942, 750: 1087, 850: 1232, 950: 1377, 1050: 1522, 1150: 1667, 1250: 1812, - 1350: 1957, 1450: 2102, 1550: 2247, 1650: 2392, 1750: 2537, 1900: 2756, 2000: 2901, 2100: 3046, - 2200: 3191, 2300: 3336, 2400: 3481, 2500: 3626, 2600: 3771, 2700: 3916, 2800: 4061, 2900: 4206, - 3000: 4351, 3100: 4496, 3200: 4641, 3300: 4786, 3400: 4931, 3500: 5076, 3600: 5221, 3700: 5366, - 3800: 5511, 3900: 5656, 4000: 5801, - }, - "한컴 소망 B": { - 550: 797, 650: 942, 750: 1086, 800: 1159, 850: 1231, 900: 1304, 950: 1376, 1050: 1521, - 1150: 1666, 1250: 1811, 1350: 1956, 1450: 2101, 1550: 2246, 1650: 2391, 1750: 2536, 1850: 2681, - 1950: 2826, 2000: 2899, 2100: 3044, 2150: 3115, 2250: 3260, 2350: 3405, 2450: 3550, 2550: 3695, - 2650: 3840, 2750: 3985, 2850: 4130, 2950: 4275, 3000: 4348, 3100: 4493, 3200: 4638, 3300: 4783, - 3400: 4928, 3500: 5073, 3650: 5289, 3750: 5434, 3850: 5579, 3950: 5724, 4000: 5797, - }, - "한컴 백제 B": { - 550: 738, 600: 804, 650: 871, 700: 938, 750: 1005, 800: 1072, 850: 1139, 900: 1207, - 950: 1274, 1050: 1408, 1100: 1475, 1150: 1542, 1200: 1609, 1250: 1676, 1300: 1743, 1350: 1810, - 1400: 1877, 1450: 1944, 1550: 2079, 1600: 2146, 1650: 2213, 1700: 2279, 1750: 2346, 1800: 2413, - 1850: 2480, 1900: 2547, 1950: 2614, 2000: 2681, 2050: 2749, 2100: 2816, 2150: 2883, 2200: 2950, - 2250: 3017, 2300: 3084, 2350: 3151, 2400: 3218, 2450: 3285, 2500: 3352, 2550: 3419, 2600: 3486, - 2650: 3554, 2700: 3621, 2750: 3688, 2800: 3754, 2850: 3821, 2900: 3888, 2950: 3955, 3000: 4022, - 3050: 4089, 3100: 4156, 3150: 4223, 3200: 4291, 3250: 4358, 3300: 4425, 3350: 4492, 3400: 4559, - 3450: 4626, 3500: 4693, 3550: 4760, 3600: 4827, 3650: 4894, 3700: 4961, 3750: 5028, 3800: 5096, - 3850: 5163, 3900: 5229, 3950: 5296, 4000: 5363, - }, - "한컴 백제 M": { - 500: 655, 600: 787, 650: 852, 700: 918, 750: 983, 850: 1115, 900: 1180, 950: 1246, - 1050: 1377, 1100: 1443, 1150: 1508, 1200: 1574, 1250: 1640, 1300: 1705, 1350: 1770, 1450: 1902, - 1500: 1967, 1550: 2033, 1600: 2098, 1650: 2164, 1700: 2230, 1750: 2295, 1800: 2360, 1850: 2427, - 1900: 2492, 1950: 2557, 2000: 2623, 2050: 2689, 2100: 2754, 2150: 2820, 2200: 2885, 2250: 2950, - 2300: 3017, 2350: 3082, 2400: 3148, 2450: 3213, 2500: 3279, 2550: 3345, 2600: 3410, 2650: 3475, - 2700: 3542, 2750: 3607, 2800: 3672, 2850: 3738, 2900: 3803, 2950: 3869, 3000: 3935, 3050: 4000, - 3100: 4065, 3150: 4132, 3200: 4197, 3250: 4262, 3300: 4328, 3350: 4394, 3400: 4459, 3450: 4525, - 3500: 4590, 3550: 4656, 3600: 4722, 3650: 4787, 3700: 4852, 3750: 4918, 3800: 4984, 3850: 5049, - 3900: 5115, 3950: 5180, 4000: 5247, - }, - "한컴 바겐세일 B": { - 550: 705, 600: 769, 650: 833, 700: 897, 750: 961, 800: 1025, 850: 1089, 900: 1153, - 950: 1217, 1050: 1346, 1100: 1410, 1150: 1474, 1200: 1538, 1250: 1602, 1300: 1666, 1350: 1730, - 1400: 1794, 1450: 1858, 1500: 1922, 1550: 1986, 1600: 2050, 1650: 2115, 1700: 2179, 1750: 2243, - 1800: 2307, 1850: 2370, 1900: 2434, 1950: 2498, 2000: 2562, 2050: 2626, 2100: 2690, 2150: 2754, - 2200: 2818, 2250: 2882, 2300: 2947, 2350: 3011, 2400: 3075, 2450: 3139, 2500: 3203, 2550: 3267, - 2600: 3331, 2650: 3395, 2700: 3459, 2750: 3523, 2800: 3587, 2850: 3651, 2900: 3715, 2950: 3779, - 3000: 3844, 3050: 3908, 3100: 3972, 3150: 4036, 3200: 4100, 3250: 4164, 3300: 4228, 3350: 4292, - 3400: 4356, 3450: 4420, 3500: 4484, 3550: 4548, 3600: 4612, 3650: 4677, 3700: 4741, 3750: 4805, - 3800: 4869, 3850: 4933, 3900: 4997, 3950: 5061, 4000: 5125, - }, - "한컴 바겐세일 M": { - 800: 1014, 850: 1078, 900: 1141, 950: 1205, 1100: 1396, 1200: 1523, 1300: 1650, 1350: 1712, - 1450: 1839, 1500: 1903, 1600: 2030, 1700: 2157, 1800: 2284, 1850: 2346, 1950: 2473, 2000: 2537, - 2100: 2664, 2150: 2728, 2200: 2791, 2250: 2855, 2300: 2918, 2350: 2982, 2500: 3171, 2550: 3235, - 2600: 3298, 2650: 3362, 2700: 3425, 2750: 3489, 2800: 3552, 2850: 3616, 3000: 3805, 3050: 3869, - 3100: 3932, 3150: 3996, 3200: 4060, 3250: 4123, 3300: 4187, 3350: 4250, 3400: 4313, 3500: 4440, - 3550: 4503, 3600: 4567, 3650: 4630, 3700: 4694, 3750: 4757, 3800: 4821, 3850: 4884, 3900: 4948, - 4000: 5074, - }, - "휴먼명조": { - 550: 580, 600: 633, 750: 791, 800: 844, 850: 896, 900: 949, 950: 1002, 1000: 1054, - 1050: 1107, 1100: 1160, 1150: 1213, 1200: 1265, 1250: 1318, 1300: 1371, 1350: 1424, 1400: 1476, - 1450: 1529, 1500: 1582, 1550: 1635, 1650: 1740, 1700: 1793, 1850: 1951, 1900: 2004, 2050: 2162, - 2100: 2215, 2250: 2373, 2300: 2426, 2450: 2584, 2500: 2636, 2550: 2689, 2600: 2742, 2650: 2795, - 2700: 2847, 2750: 2900, 2800: 2953, 2850: 3006, 2900: 3058, 2950: 3111, 3000: 3164, 3050: 3217, - 3100: 3269, 3150: 3322, 3350: 3533, 3400: 3586, 3550: 3744, 3600: 3797, 3750: 3955, 3800: 4008, - 3950: 4166, 4000: 4219, - }, -} +#: height from the font, where they differ from its ascent and descent each rounded up: height -> line height. +#: Other heights take the formula. +LINE_HEIGHTS: dict[str, dict[int, int]] = _by_key(_TABLES["LINE_HEIGHTS"]) #: Per face, the Hangul syllables whose design advance differs from the face's other syllables #: (``measure._DESIGN``): design advance -> those syllables. -HANGUL_ADVANCES: dict[str, dict[int, str]] = { - "한컴 윤고딕 720": { - 874: "땡", - 879: "꾸땍", - 881: "땝", - }, - "한컴 소망 M": { - 990: "뒹뜅륑튕홴", - 1010: "떡", - }, - "한컴 말랑말랑 Regular": { - 820: ( - "고곡곢곣곤곥곦곧골곩곪곫곬곭곮곯곰곱곲곳곴공곶곷곸곹곺곻교굑굒굓굔굕굖굗굘굙굚굛굜굝굞굟굠굡굢굣굤굥" - "굦굧굨굩굪굫구국굮굯군굱굲굳굴굵굶굷굸굹굺굻굼굽굾굿궀궁궂궃궄궅궆궇규귝귞귟균귡귢귣귤귥귦귧귨귩귪귫" - "귬귭귮귯귰귱귲귳귴귵귶귷그극귺귻근귽귾귿글긁긂긃긄긅긆긇금급긊긋긌긍긎긏긐긑긒긓꼬꼭꼮꼯꼰꼱꼲꼳꼴꼵" - "꼶꼷꼸꼹꼺꼻꼼꼽꼾꼿꽀꽁꽂꽃꽄꽅꽆꽇꾜꾝꾞꾟꾠꾡꾢꾣꾤꾥꾦꾧꾨꾩꾪꾫꾬꾭꾮꾯꾰꾱꾲꾳꾴꾵꾶꾷꾸꾹꾺꾻" - "꾼꾽꾾꾿꿀꿁꿂꿃꿄꿅꿆꿇꿈꿉꿊꿋꿌꿍꿎꿏꿐꿑꿒꿓뀨뀩뀪뀫뀬뀭뀮뀯뀰뀱뀲뀳뀴뀵뀶뀷뀸뀹뀺뀻뀼뀽뀾뀿끀끁" - "끂끃끄끅끆끇끈끉끊끋끌끍끎끏끐끑끒끓끔끕끖끗끘끙끚끛끜끝끞끟노녹녺녻논녽녾녿놀놁놂놃놄놅놆놇놈놉놊놋" - "놌농놎놏놐놑높놓뇨뇩뇪뇫뇬뇭뇮뇯뇰뇱뇲뇳뇴뇵뇶뇷뇸뇹뇺뇻뇼뇽뇾뇿눀눁눂눃누눅눆눇눈눉눊눋눌눍눎눏눐눑" - "눒눓눔눕눖눗눘눙눚눛눜눝눞눟뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄늅늆늇늈늉늊늋늌늍늎늏느늑늒늓는늕늖늗" - "늘늙늚늛늜늝늞늟늠늡늢늣늤능늦늧늨늩늪늫도독돆돇돈돉돊돋돌돍돎돏돐돑돒돓돔돕돖돗돘동돚돛돜돝돞돟됴됵" - "됶됷됸됹됺됻됼됽됾됿둀둁둂둃둄둅둆둇둈둉둊둋둌둍둎둏두둑둒둓둔둕둖둗둘둙둚둛둜둝둞둟둠둡둢둣둤둥둦둧" - "둨둩둪둫듀듁듂듃듄듅듆듇듈듉듊듋듌듍듎듏듐듑듒듓듔듕듖듗듘듙듚듛드득듞듟든듡듢듣들듥듦듧듨듩듪듫듬듭" - "듮듯듰등듲듳듴듵듶듷또똑똒똓똔똕똖똗똘똙똚똛똜똝똞똟똠똡똢똣똤똥똦똧똨똩똪똫뚀뚁뚂뚃뚄뚅뚆뚇뚈뚉뚊뚋" - "뚌뚍뚎뚏뚐뚑뚒뚓뚔뚕뚖뚗뚘뚙뚚뚛뚜뚝뚞뚟뚠뚡뚢뚣뚤뚥뚦뚧뚨뚩뚪뚫뚬뚭뚮뚯뚰뚱뚲뚳뚴뚵뚶뚷뜌뜍뜎뜏뜐뜑" - "뜒뜓뜔뜕뜖뜗뜘뜙뜚뜛뜜뜝뜞뜟뜠뜡뜢뜣뜤뜥뜦뜧뜨뜩뜪뜫뜬뜭뜮뜯뜰뜱뜲뜳뜴뜵뜶뜷뜸뜹뜺뜻뜼뜽뜾뜿띀띁띂띃" - "로록롞롟론롡롢롣롤롥롦롧롨롩롪롫롬롭롮롯롰롱롲롳롴롵롶롷료룍룎룏룐룑룒룓룔룕룖룗룘룙룚룛룜룝룞룟룠룡" - "룢룣룤룥룦룧루룩룪룫룬룭룮룯룰룱룲룳룴룵룶룷룸룹룺룻룼룽룾룿뤀뤁뤂뤃류륙륚륛륜륝륞륟률륡륢륣륤륥륦륧" - "륨륩륪륫륬륭륮륯륰륱륲륳르륵륶륷른륹륺륻를륽륾륿릀릁릂릃름릅릆릇릈릉릊릋릌릍릎릏모목몪몫몬몭몮몯몰몱" - "몲몳몴몵몶몷몸몹몺못몼몽몾몿뫀뫁뫂뫃묘묙묚묛묜묝묞묟묠묡묢묣묤묥묦묧묨묩묪묫묬묭묮묯묰묱묲묳무묵묶묷" - "문묹묺묻물묽묾묿뭀뭁뭂뭃뭄뭅뭆뭇뭈뭉뭊뭋뭌뭍뭎뭏뮤뮥뮦뮧뮨뮩뮪뮫뮬뮭뮮뮯뮰뮱뮲뮳뮴뮵뮶뮷뮸뮹뮺뮻뮼뮽" - "뮾뮿므믁믂믃믄믅믆믇믈믉믊믋믌믍믎믏믐믑믒믓믔믕믖믗믘믙믚믛보복볶볷본볹볺볻볼볽볾볿봀봁봂봃봄봅봆봇" - "봈봉봊봋봌봍봎봏뵤뵥뵦뵧뵨뵩뵪뵫뵬뵭뵮뵯뵰뵱뵲뵳뵴뵵뵶뵷뵸뵹뵺뵻뵼뵽뵾뵿부북붂붃분붅붆붇불붉붊붋붌붍" - "붎붏붐붑붒붓붔붕붖붗붘붙붚붛뷰뷱뷲뷳뷴뷵뷶뷷뷸뷹뷺뷻뷼뷽뷾뷿븀븁븂븃븄븅븆븇븈븉븊븋브븍븎븏븐븑븒븓" - "블븕븖븗븘븙븚븛븜븝븞븟븠븡븢븣븤븥븦븧뽀뽁뽂뽃뽄뽅뽆뽇뽈뽉뽊뽋뽌뽍뽎뽏뽐뽑뽒뽓뽔뽕뽖뽗뽘뽙뽚뽛뾰뾱" - "뾲뾳뾴뾵뾶뾷뾸뾹뾺뾻뾼뾽뾾뾿뿀뿁뿂뿃뿄뿅뿆뿇뿈뿉뿊뿋뿌뿍뿎뿏뿐뿑뿒뿓뿔뿕뿖뿗뿘뿙뿚뿛뿜뿝뿞뿟뿠뿡뿢뿣" - "뿤뿥뿦뿧쀼쀽쀾쀿쁀쁁쁂쁃쁄쁅쁆쁇쁈쁉쁊쁋쁌쁍쁎쁏쁐쁑쁒쁓쁔쁕쁖쁗쁘쁙쁚쁛쁜쁝쁞쁟쁠쁡쁢쁣쁤쁥쁦쁧쁨쁩" - "쁪쁫쁬쁭쁮쁯쁰쁱쁲쁳소속솎솏손솑솒솓솔솕솖솗솘솙솚솛솜솝솞솟솠송솢솣솤솥솦솧쇼쇽쇾쇿숀숁숂숃숄숅숆숇" - "숈숉숊숋숌숍숎숏숐숑숒숓숔숕숖숗수숙숚숛순숝숞숟술숡숢숣숤숥숦숧숨숩숪숫숬숭숮숯숰숱숲숳슈슉슊슋슌슍" - "슎슏슐슑슒슓슔슕슖슗슘슙슚슛슜슝슞슟슠슡슢슣스슥슦슧슨슩슪슫슬슭슮슯슰슱슲슳슴습슶슷슸승슺슻슼슽슾슿" - "쏘쏙쏚쏛쏜쏝쏞쏟쏠쏡쏢쏣쏤쏥쏦쏧쏨쏩쏪쏫쏬쏭쏮쏯쏰쏱쏲쏳쑈쑉쑊쑋쑌쑍쑎쑏쑐쑑쑒쑓쑔쑕쑖쑗쑘쑙쑚쑛쑜쑝" - "쑞쑟쑠쑡쑢쑣쑤쑥쑦쑧쑨쑩쑪쑫쑬쑭쑮쑯쑰쑱쑲쑳쑴쑵쑶쑷쑸쑹쑺쑻쑼쑽쑾쑿쓔쓕쓖쓗쓘쓙쓚쓛쓜쓝쓞쓟쓠쓡쓢쓣" - "쓤쓥쓦쓧쓨쓩쓪쓫쓬쓭쓮쓯쓰쓱쓲쓳쓴쓵쓶쓷쓸쓹쓺쓻쓼쓽쓾쓿씀씁씂씃씄씅씆씇씈씉씊씋오옥옦옧온옩옪옫올옭" - "옮옯옰옱옲옳옴옵옶옷옸옹옺옻옼옽옾옿요욕욖욗욘욙욚욛욜욝욞욟욠욡욢욣욤욥욦욧욨용욪욫욬욭욮욯우욱욲욳" - "운욵욶욷울욹욺욻욼욽욾욿움웁웂웃웄웅웆웇웈웉웊웋유육윢윣윤윥윦윧율윩윪윫윬윭윮윯윰윱윲윳윴융윶윷윸윹" - "윺윻으윽윾윿은읁읂읃을읅읆읇읈읉읊읋음읍읎읏읐응읒읓읔읕읖읗조족졲졳존졵졶졷졸졹졺졻졼졽졾졿좀좁좂좃" - "좄종좆좇좈좉좊좋죠죡죢죣죤죥죦죧죨죩죪죫죬죭죮죯죰죱죲죳죴죵죶죷죸죹죺죻주죽죾죿준줁줂줃줄줅줆줇줈줉" - "줊줋줌줍줎줏줐중줒줓줔줕줖줗쥬쥭쥮쥯쥰쥱쥲쥳쥴쥵쥶쥷쥸쥹쥺쥻쥼쥽쥾쥿즀즁즂즃즄즅즆즇즈즉즊즋즌즍즎즏" - "즐즑즒즓즔즕즖즗즘즙즚즛즜증즞즟즠즡즢즣쪼쪽쪾쪿쫀쫁쫂쫃쫄쫅쫆쫇쫈쫉쫊쫋쫌쫍쫎쫏쫐쫑쫒쫓쫔쫕쫖쫗쬬쬭" - "쬮쬯쬰쬱쬲쬳쬴쬵쬶쬷쬸쬹쬺쬻쬼쬽쬾쬿쭀쭁쭂쭃쭄쭅쭆쭇쭈쭉쭊쭋쭌쭍쭎쭏쭐쭑쭒쭓쭔쭕쭖쭗쭘쭙쭚쭛쭜쭝쭞쭟" - "쭠쭡쭢쭣쮸쮹쮺쮻쮼쮽쮾쮿쯀쯁쯂쯃쯄쯅쯆쯇쯈쯉쯊쯋쯌쯍쯎쯏쯐쯑쯒쯓쯔쯕쯖쯗쯘쯙쯚쯛쯜쯝쯞쯟쯠쯡쯢쯣쯤쯥" - "쯦쯧쯨쯩쯪쯫쯬쯭쯮쯯초촉촊촋촌촍촎촏촐촑촒촓촔촕촖촗촘촙촚촛촜총촞촟촠촡촢촣쵸쵹쵺쵻쵼쵽쵾쵿춀춁춂춃" - "춄춅춆춇춈춉춊춋춌춍춎춏춐춑춒춓추축춖춗춘춙춚춛출춝춞춟춠춡춢춣춤춥춦춧춨충춪춫춬춭춮춯츄츅츆츇츈츉" - "츊츋츌츍츎츏츐츑츒츓츔츕츖츗츘츙츚츛츜츝츞츟츠측츢츣츤츥츦츧츨츩츪츫츬츭츮츯츰츱츲츳츴층츶츷츸츹츺츻" - "코콕콖콗콘콙콚콛콜콝콞콟콠콡콢콣콤콥콦콧콨콩콪콫콬콭콮콯쿄쿅쿆쿇쿈쿉쿊쿋쿌쿍쿎쿏쿐쿑쿒쿓쿔쿕쿖쿗쿘쿙" - "쿚쿛쿜쿝쿞쿟쿠쿡쿢쿣쿤쿥쿦쿧쿨쿩쿪쿫쿬쿭쿮쿯쿰쿱쿲쿳쿴쿵쿶쿷쿸쿹쿺쿻큐큑큒큓큔큕큖큗큘큙큚큛큜큝큞큟" - "큠큡큢큣큤큥큦큧큨큩큪큫크큭큮큯큰큱큲큳클큵큶큷큸큹큺큻큼큽큾큿킀킁킂킃킄킅킆킇토톡톢톣톤톥톦톧톨톩" - "톪톫톬톭톮톯톰톱톲톳톴통톶톷톸톹톺톻툐툑툒툓툔툕툖툗툘툙툚툛툜툝툞툟툠툡툢툣툤툥툦툧툨툩툪툫투툭툮툯" - "툰툱툲툳툴툵툶툷툸툹툺툻툼툽툾툿퉀퉁퉂퉃퉄퉅퉆퉇튜튝튞튟튠튡튢튣튤튥튦튧튨튩튪튫튬튭튮튯튰튱튲튳튴튵" - "튶튷트특튺튻튼튽튾튿틀틁틂틃틄틅틆틇틈틉틊틋틌틍틎틏틐틑틒틓포폭폮폯폰폱폲폳폴폵폶폷폸폹폺폻폼폽폾폿" - "퐀퐁퐂퐃퐄퐅퐆퐇표푝푞푟푠푡푢푣푤푥푦푧푨푩푪푫푬푭푮푯푰푱푲푳푴푵푶푷푸푹푺푻푼푽푾푿풀풁풂풃풄풅" - "풆풇품풉풊풋풌풍풎풏풐풑풒풓퓨퓩퓪퓫퓬퓭퓮퓯퓰퓱퓲퓳퓴퓵퓶퓷퓸퓹퓺퓻퓼퓽퓾퓿픀픁픂픃프픅픆픇픈픉픊픋" - "플픍픎픏픐픑픒픓픔픕픖픗픘픙픚픛픜픝픞픟호혹혺혻혼혽혾혿홀홁홂홃홄홅홆홇홈홉홊홋홌홍홎홏홐홑홒홓효횩" - "횪횫횬횭횮횯횰횱횲횳횴횵횶횷횸횹횺횻횼횽횾횿훀훁훂훃후훅훆훇훈훉훊훋훌훍훎훏훐훑훒훓훔훕훖훗훘훙훚훛" - "훜훝훞훟휴휵휶휷휸휹휺휻휼휽휾휿흀흁흂흃흄흅흆흇흈흉흊흋흌흍흎흏흐흑흒흓흔흕흖흗흘흙흚흛흜흝흞흟흠흡" - "흢흣흤흥흦흧흨흩흪흫" - ), - }, - "한컴 말랑말랑 Bold": { - 820: ( - "고곡곢곣곤곥곦곧골곩곪곫곬곭곮곯곰곱곲곳곴공곶곷곸곹곺곻교굑굒굓굔굕굖굗굘굙굚굛굜굝굞굟굠굡굢굣굤굥" - "굦굧굨굩굪굫구국굮굯군굱굲굳굴굵굶굷굸굹굺굻굼굽굾굿궀궁궂궃궄궅궆궇규귝귞귟균귡귢귣귤귥귦귧귨귩귪귫" - "귬귭귮귯귰귱귲귳귴귵귶귷그극귺귻근귽귾귿글긁긂긃긄긅긆긇금급긊긋긌긍긎긏긐긑긒긓꼬꼭꼮꼯꼰꼱꼲꼳꼴꼵" - "꼶꼷꼸꼹꼺꼻꼼꼽꼾꼿꽀꽁꽂꽃꽄꽅꽆꽇꾜꾝꾞꾟꾠꾡꾢꾣꾤꾥꾦꾧꾨꾩꾪꾫꾬꾭꾮꾯꾰꾱꾲꾳꾴꾵꾶꾷꾸꾹꾺꾻" - "꾼꾽꾾꾿꿀꿁꿂꿃꿄꿅꿆꿇꿈꿉꿊꿋꿌꿍꿎꿏꿐꿑꿒꿓뀨뀩뀪뀫뀬뀭뀮뀯뀰뀱뀲뀳뀴뀵뀶뀷뀸뀹뀺뀻뀼뀽뀾뀿끀끁" - "끂끃끄끅끆끇끈끉끊끋끌끍끎끏끐끑끒끓끔끕끖끗끘끙끚끛끜끝끞끟노녹녺녻논녽녾녿놀놁놂놃놄놅놆놇놈놉놊놋" - "놌농놎놏놐놑높놓뇨뇩뇪뇫뇬뇭뇮뇯뇰뇱뇲뇳뇴뇵뇶뇷뇸뇹뇺뇻뇼뇽뇾뇿눀눁눂눃누눅눆눇눈눉눊눋눌눍눎눏눐눑" - "눒눓눔눕눖눗눘눙눚눛눜눝눞눟뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄늅늆늇늈늉늊늋늌늍늎늏느늑늒늓는늕늖늗" - "늘늙늚늛늜늝늞늟늠늡늢늣늤능늦늧늨늩늪늫도독돆돇돈돉돊돋돌돍돎돏돐돑돒돓돔돕돖돗돘동돚돛돜돝돞돟됴됵" - "됶됷됸됹됺됻됼됽됾됿둀둁둂둃둄둅둆둇둈둉둊둋둌둍둎둏두둑둒둓둔둕둖둗둘둙둚둛둜둝둞둟둠둡둢둣둤둥둦둧" - "둨둩둪둫듀듁듂듃듄듅듆듇듈듉듊듋듌듍듎듏듐듑듒듓듔듕듖듗듘듙듚듛드득듞듟든듡듢듣들듥듦듧듨듩듪듫듬듭" - "듮듯듰등듲듳듴듵듶듷또똑똒똓똔똕똖똗똘똙똚똛똜똝똞똟똠똡똢똣똤똥똦똧똨똩똪똫뚀뚁뚂뚃뚄뚅뚆뚇뚈뚉뚊뚋" - "뚌뚍뚎뚏뚐뚑뚒뚓뚔뚕뚖뚗뚘뚙뚚뚛뚜뚝뚞뚟뚠뚡뚢뚣뚤뚥뚦뚧뚨뚩뚪뚫뚬뚭뚮뚯뚰뚱뚲뚳뚴뚵뚶뚷뜌뜍뜎뜏뜐뜑" - "뜒뜓뜔뜕뜖뜗뜘뜙뜚뜛뜜뜝뜞뜟뜠뜡뜢뜣뜤뜥뜦뜧뜨뜩뜪뜫뜬뜭뜮뜯뜰뜱뜲뜳뜴뜵뜶뜷뜸뜹뜺뜻뜼뜽뜾뜿띀띁띂띃" - "로록롞롟론롡롢롣롤롥롦롧롨롩롪롫롬롭롮롯롰롱롲롳롴롵롶롷료룍룎룏룐룑룒룓룔룕룖룗룘룙룚룛룜룝룞룟룠룡" - "룢룣룤룥룦룧루룩룪룫룬룭룮룯룰룱룲룳룴룵룶룷룸룹룺룻룼룽룾룿뤀뤁뤂뤃류륙륚륛륜륝륞륟률륡륢륣륤륥륦륧" - "륨륩륪륫륬륭륮륯륰륱륲륳르륵륶륷른륹륺륻를륽륾륿릀릁릂릃름릅릆릇릈릉릊릋릌릍릎릏모목몪몫몬몭몮몯몰몱" - "몲몳몴몵몶몷몸몹몺못몼몽몾몿뫀뫁뫂뫃묘묙묚묛묜묝묞묟묠묡묢묣묤묥묦묧묨묩묪묫묬묭묮묯묰묱묲묳무묵묶묷" - "문묹묺묻물묽묾묿뭀뭁뭂뭃뭄뭅뭆뭇뭈뭉뭊뭋뭌뭍뭎뭏뮤뮥뮦뮧뮨뮩뮪뮫뮬뮭뮮뮯뮰뮱뮲뮳뮴뮵뮶뮷뮸뮹뮺뮻뮼뮽" - "뮾뮿므믁믂믃믄믅믆믇믈믉믊믋믌믍믎믏믐믑믒믓믔믕믖믗믘믙믚믛보복볶볷본볹볺볻볼볽볾볿봀봁봂봃봄봅봆봇" - "봈봉봊봋봌봍봎봏뵤뵥뵦뵧뵨뵩뵪뵫뵬뵭뵮뵯뵰뵱뵲뵳뵴뵵뵶뵷뵸뵹뵺뵻뵼뵽뵾뵿부북붂붃분붅붆붇불붉붊붋붌붍" - "붎붏붐붑붒붓붔붕붖붗붘붙붚붛뷰뷱뷲뷳뷴뷵뷶뷷뷸뷹뷺뷻뷼뷽뷾뷿븀븁븂븃븄븅븆븇븈븉븊븋브븍븎븏븐븑븒븓" - "블븕븖븗븘븙븚븛븜븝븞븟븠븡븢븣븤븥븦븧뽀뽁뽂뽃뽄뽅뽆뽇뽈뽉뽊뽋뽌뽍뽎뽏뽐뽑뽒뽓뽔뽕뽖뽗뽘뽙뽚뽛뾰뾱" - "뾲뾳뾴뾵뾶뾷뾸뾹뾺뾻뾼뾽뾾뾿뿀뿁뿂뿃뿄뿅뿆뿇뿈뿉뿊뿋뿌뿍뿎뿏뿐뿑뿒뿓뿔뿕뿖뿗뿘뿙뿚뿛뿜뿝뿞뿟뿠뿡뿢뿣" - "뿤뿥뿦뿧쀼쀽쀾쀿쁀쁁쁂쁃쁄쁅쁆쁇쁈쁉쁊쁋쁌쁍쁎쁏쁐쁑쁒쁓쁔쁕쁖쁗쁘쁙쁚쁛쁜쁝쁞쁟쁠쁡쁢쁣쁤쁥쁦쁧쁨쁩" - "쁪쁫쁬쁭쁮쁯쁰쁱쁲쁳소속솎솏손솑솒솓솔솕솖솗솘솙솚솛솜솝솞솟솠송솢솣솤솥솦솧쇼쇽쇾쇿숀숁숂숃숄숅숆숇" - "숈숉숊숋숌숍숎숏숐숑숒숓숔숕숖숗수숙숚숛순숝숞숟술숡숢숣숤숥숦숧숨숩숪숫숬숭숮숯숰숱숲숳슈슉슊슋슌슍" - "슎슏슐슑슒슓슔슕슖슗슘슙슚슛슜슝슞슟슠슡슢슣스슥슦슧슨슩슪슫슬슭슮슯슰슱슲슳슴습슶슷슸승슺슻슼슽슾슿" - "쏘쏙쏚쏛쏜쏝쏞쏟쏠쏡쏢쏣쏤쏥쏦쏧쏨쏩쏪쏫쏬쏭쏮쏯쏰쏱쏲쏳쑈쑉쑊쑋쑌쑍쑎쑏쑐쑑쑒쑓쑔쑕쑖쑗쑘쑙쑚쑛쑜쑝" - "쑞쑟쑠쑡쑢쑣쑤쑥쑦쑧쑨쑩쑪쑫쑬쑭쑮쑯쑰쑱쑲쑳쑴쑵쑶쑷쑸쑹쑺쑻쑼쑽쑾쑿쓔쓕쓖쓗쓘쓙쓚쓛쓜쓝쓞쓟쓠쓡쓢쓣" - "쓤쓥쓦쓧쓨쓩쓪쓫쓬쓭쓮쓯쓰쓱쓲쓳쓴쓵쓶쓷쓸쓹쓺쓻쓼쓽쓾쓿씀씁씂씃씄씅씆씇씈씉씊씋오옥옦옧온옩옪옫올옭" - "옮옯옰옱옲옳옴옵옶옷옸옹옺옻옼옽옾옿요욕욖욗욘욙욚욛욜욝욞욟욠욡욢욣욤욥욦욧욨용욪욫욬욭욮욯우욱욲욳" - "운욵욶욷울욹욺욻욼욽욾욿움웁웂웃웄웅웆웇웈웉웊웋유육윢윣윤윥윦윧율윩윪윫윬윭윮윯윰윱윲윳윴융윶윷윸윹" - "윺윻으윽윾윿은읁읂읃을읅읆읇읈읉읊읋음읍읎읏읐응읒읓읔읕읖읗조족졲졳존졵졶졷졸졹졺졻졼졽졾졿좀좁좂좃" - "좄종좆좇좈좉좊좋죠죡죢죣죤죥죦죧죨죩죪죫죬죭죮죯죰죱죲죳죴죵죶죷죸죹죺죻주죽죾죿준줁줂줃줄줅줆줇줈줉" - "줊줋줌줍줎줏줐중줒줓줔줕줖줗쥬쥭쥮쥯쥰쥱쥲쥳쥴쥵쥶쥷쥸쥹쥺쥻쥼쥽쥾쥿즀즁즂즃즄즅즆즇즈즉즊즋즌즍즎즏" - "즐즑즒즓즔즕즖즗즘즙즚즛즜증즞즟즠즡즢즣쪼쪽쪾쪿쫀쫁쫂쫃쫄쫅쫆쫇쫈쫉쫊쫋쫌쫍쫎쫏쫐쫑쫒쫓쫔쫕쫖쫗쬬쬭" - "쬮쬯쬰쬱쬲쬳쬴쬵쬶쬷쬸쬹쬺쬻쬼쬽쬾쬿쭀쭁쭂쭃쭄쭅쭆쭇쭈쭉쭊쭋쭌쭍쭎쭏쭐쭑쭒쭓쭔쭕쭖쭗쭘쭙쭚쭛쭜쭝쭞쭟" - "쭠쭡쭢쭣쮸쮹쮺쮻쮼쮽쮾쮿쯀쯁쯂쯃쯄쯅쯆쯇쯈쯉쯊쯋쯌쯍쯎쯏쯐쯑쯒쯓쯔쯕쯖쯗쯘쯙쯚쯛쯜쯝쯞쯟쯠쯡쯢쯣쯤쯥" - "쯦쯧쯨쯩쯪쯫쯬쯭쯮쯯초촉촊촋촌촍촎촏촐촑촒촓촔촕촖촗촘촙촚촛촜총촞촟촠촡촢촣쵸쵹쵺쵻쵼쵽쵾쵿춀춁춂춃" - "춄춅춆춇춈춉춊춋춌춍춎춏춐춑춒춓추축춖춗춘춙춚춛출춝춞춟춠춡춢춣춤춥춦춧춨충춪춫춬춭춮춯츄츅츆츇츈츉" - "츊츋츌츍츎츏츐츑츒츓츔츕츖츗츘츙츚츛츜츝츞츟츠측츢츣츤츥츦츧츨츩츪츫츬츭츮츯츰츱츲츳츴층츶츷츸츹츺츻" - "코콕콖콗콘콙콚콛콜콝콞콟콠콡콢콣콤콥콦콧콨콩콪콫콬콭콮콯쿄쿅쿆쿇쿈쿉쿊쿋쿌쿍쿎쿏쿐쿑쿒쿓쿔쿕쿖쿗쿘쿙" - "쿚쿛쿜쿝쿞쿟쿠쿡쿢쿣쿤쿥쿦쿧쿨쿩쿪쿫쿬쿭쿮쿯쿰쿱쿲쿳쿴쿵쿶쿷쿸쿹쿺쿻큐큑큒큓큔큕큖큗큘큙큚큛큜큝큞큟" - "큠큡큢큣큤큥큦큧큨큩큪큫크큭큮큯큰큱큲큳클큵큶큷큸큹큺큻큼큽큾큿킀킁킂킃킄킅킆킇토톡톢톣톤톥톦톧톨톩" - "톪톫톬톭톮톯톰톱톲톳톴통톶톷톸톹톺톻툐툑툒툓툔툕툖툗툘툙툚툛툜툝툞툟툠툡툢툣툤툥툦툧툨툩툪툫투툭툮툯" - "툰툱툲툳툴툵툶툷툸툹툺툻툼툽툾툿퉀퉁퉂퉃퉄퉅퉆퉇튜튝튞튟튠튡튢튣튤튥튦튧튨튩튪튫튬튭튮튯튰튱튲튳튴튵" - "튶튷트특튺튻튼튽튾튿틀틁틂틃틄틅틆틇틈틉틊틋틌틍틎틏틐틑틒틓포폭폮폯폰폱폲폳폴폵폶폷폸폹폺폻폼폽폾폿" - "퐀퐁퐂퐃퐄퐅퐆퐇표푝푞푟푠푡푢푣푤푥푦푧푨푩푪푫푬푭푮푯푰푱푲푳푴푵푶푷푸푹푺푻푼푽푾푿풀풁풂풃풄풅" - "풆풇품풉풊풋풌풍풎풏풐풑풒풓퓨퓩퓪퓫퓬퓭퓮퓯퓰퓱퓲퓳퓴퓵퓶퓷퓸퓹퓺퓻퓼퓽퓾퓿픀픁픂픃프픅픆픇픈픉픊픋" - "플픍픎픏픐픑픒픓픔픕픖픗픘픙픚픛픜픝픞픟호혹혺혻혼혽혾혿홀홁홂홃홄홅홆홇홈홉홊홋홌홍홎홏홐홑홒홓효횩" - "횪횫횬횭횮횯횰횱횲횳횴횵횶횷횸횹횺횻횼횽횾횿훀훁훂훃후훅훆훇훈훉훊훋훌훍훎훏훐훑훒훓훔훕훖훗훘훙훚훛" - "훜훝훞훟휴휵휶휷휸휹휺휻휼휽휾휿흀흁흂흃흄흅흆흇흈흉흊흋흌흍흎흏흐흑흒흓흔흕흖흗흘흙흚흛흜흝흞흟흠흡" - "흢흣흤흥흦흧흨흩흪흫" - ), - }, - "KoPub돋움체 Light": { - 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", - }, - "KoPub돋움체 Medium": { - 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", - }, - "KoPub돋움체 Bold": { - 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", - }, - "KoPub바탕체 Light": { - 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", - }, - "KoPub바탕체 Medium": { - 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", - }, - "KoPub바탕체 Bold": { - 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", - }, - "KoPubWorld돋움체 Light": { - 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", - }, - "KoPubWorld돋움체 Medium": { - 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", - }, - "KoPubWorld돋움체 Bold": { - 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", - }, - "KoPubWorld바탕체 Light": { - 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", - }, - "KoPubWorld바탕체 Medium": { - 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", - }, - "KoPubWorld바탕체 Bold": { - 900: "ㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ", - }, -} +HANGUL_ADVANCES: dict[str, dict[int, str]] = _by_key(_TABLES["HANGUL_ADVANCES"]) #: Per face, design advance -> the glyphs the face lays out at that advance. -ADVANCES: dict[str, dict[int, str]] = { - "신명 태명조": { - 2: "\u302a\u302b", - 322: "˙", - 345: "ː", - 437: "⁏", - 465: "⁚⁝⁞", - 513: "¦", - 527: "˛", - 541: "˚", - 543: "ĺļľł", - 551: "ìíîïĩīĭįı", - 588: "Ι", - 592: "․‧", - 598: "‚‛", - 609: "ª", - 615: "¡", - 617: "ĵ", - 641: "¹", - 656: "⁴ⁿ₁₂₃₄", - 676: "ι", - 687: "‖′‵", - 691: "ÌÍÎÏĨĪĬĮİ", - 717: "¸", - 740: "ţťŧ", - 756: "‣", - 768: "º", - 771: "´", - 773: "˘", - 779: "¨", - 785: "²³", - 790: "ˇ", - 799: "„‟", - 805: "ŀ", - 811: "‹›", - 818: "•", - 838: "ŕŗř", - 854: "⁎", - 863: "¼½¾", - 891: "˝", - 898: "Ĵ‡", - 916: "τ‼", - 932: "śŝşš", - 934: "⁃", - 949: "źżž", - 951: "⁖", - 967: "⁅⁆", - 970: "″‶", - 977: "⚬", - 981: "¶", - 984: "‽", - 988: "çðćĉċč", - 994: ( - "〿。「」、ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑→" - "↓■○" - ), - 996: "§⁑", - 1004: "èéêëēĕėęě", - 1012: "¯", - 1024: ( - "¢»¿【】〔〕〖〗〘〙〚〛・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモ" - "ヤユヨラリルレロワン゙゚ᅠ" - ), - 1027: "«", - 1043: "àáâãäåāăą", - 1047: "₫", - 1059: "₰", - 1060: "её", - 1063: "òóôõöøōŏő", - 1065: "£", - 1067: "⁙", - 1072: "µ", - 1074: "δ", - 1076: "ĸ‸", - 1082: "ij‐‑", - 1088: "⁊", - 1092: "ζξ⚘", - 1094: "сэ", - 1098: "ν", - 1100: "β", - 1102: "з", - 1106: "х", - 1108: "у", - 1110: "μ", - 1113: "ďđ", - 1125: "ь", - 1129: "⚨⚲", - 1131: "ρ", - 1133: "ß", - 1135: "ĝğġģ", - 1137: "ε⁒", - 1141: "ķ", - 1142: "†", - 1147: "ùúûüĥħũūŭůűųа", - 1149: "¤ŷ", - 1156: "ñńņňʼnŋ", - 1160: "ýþÿκ", - 1168: "οо₤", - 1170: "¥б", - 1172: "гт", - 1174: "γ", - 1180: "ÞΡ⚚", - 1186: "‗", - 1203: "Β", - 1208: "η", - 1211: "υ", - 1213: "В", - 1215: "θ", - 1216: "‾", - 1219: "₦", - 1223: "ŹŻŽ", - 1224: "к", - 1227: "в", - 1229: "φ", - 1231: "₠₪", - 1232: "З", - 1242: "Р₲", - 1246: "Ζря‴‷₵", - 1248: "ΕЁБЕ", - 1254: "Γ", - 1256: "₴", - 1264: "χий", - 1274: "ŚŜŞŠГ", - 1278: "⁈", - 1280: "‒", - 1290: "ч", - 1295: "₣", - 1298: "ц⁉", - 1301: "⁄", - 1305: "₱", - 1311: "‥", - 1314: "ΚЯ⁘⁛", - 1321: "ĹĻĽĿŁ", - 1324: "ΤТ⁋⁌⁍", - 1330: "Ь", - 1332: "₭", - 1336: "⁗", - 1340: "₮", - 1342: "н", - 1344: "€", - 1346: "σ", - 1348: "С", - 1350: "⚭", - 1352: "α", - 1354: "ΞЭ", - 1362: "лп₥", - 1364: "ψ⁁₡₢", - 1377: "æК", - 1387: "ÈÉÊËĒĔĖĘĚ", - 1395: "⁕", - 1407: "Ç", - 1414: "ĆĈĊČ", - 1422: "⚥⚦", - 1424: "Δм", - 1426: "ΘΟО", - 1428: "Π", - 1434: "ŔŖŘЧ", - 1440: "ΥΧХ", - 1442: "ΑА", - 1448: "λ", - 1453: "Ŋъ", - 1454: "д", - 1462: "πω", - 1467: "ΗΝН", - 1473: "ИЙ", - 1475: "⚐⚑", - 1477: "Ω", - 1481: "œ", - 1504: "ПЦ", - 1506: "ΛЛ", - 1520: "ĜĞĠĢ", - 1524: "Д", - 1528: "Ψ", - 1530: "ΦФ", - 1532: "ÒÓÔÕÖØŌŎŐ", - 1534: "ÐĎĐ", - 1537: "У", - 1547: "Σ", - 1561: "ŶŸ", - 1575: "₳", - 1576: "‿⁀", - 1577: "ÙÚÛÜÝŢŤŦŨŪŬŮŰŲ", - 1586: "IJ", - 1592: "ÑŃŅŇ", - 1598: "Ķ", - 1600: "ж", - 1606: "ĤĦ", - 1608: "©", - 1614: "®", - 1616: "Ъ", - 1626: "₩", - 1627: "ÀÁÂÃÄÅĀĂĄ", - 1629: "ю", - 1631: "⁔", - 1637: "⁐", - 1639: "⚢", - 1645: "⁓", - 1650: "ы", - 1658: "₨", - 1682: "ΜМ", - 1686: "ŵ", - 1690: "шщ", - 1706: "⁇", - 1729: "⚩", - 1764: "◸◹◺◿", - 1772: "ШЩ", - 1790: "Ы⚣⚤", - 1792: "―", - 1840: "ф⚊⚋⚌⚍⚎⚏", - 1862: "⁂", - 1899: "Œ", - 1903: "Ж", - 1909: "⚮", - 1913: "Æ", - 1942: "Ю", - 1958: "‱", - 1960: "₧", - 1986: ( - "₯℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∊∋∌∍∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡∢∣∤∥" - "∦∧∨∩∪∫∬∭∮∯∰∱∲∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟≠≡" - "≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝" - "⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙" - "⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰" - "⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤" - "┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱▴▵▶▷" - "▸▹►▻▼▽▾▿◀◁◂◃◄◅◈◉◊◌◍◎◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷" - "☀☁☂☃☄☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☙☚☛☝☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂" - "♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽⚀" - "⚁⚂⚃⚄⚅⚆⚇⚈⚉✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷" - "✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❙❚❛❜❝❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻" - "❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻" - "➼➽➾、。〃〄〇〜〝〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘" - "㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝" - "㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'" - "()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abc" - "defghijklmnopqrstuvwxyz{|}~⦅⦆¢£¬ ̄¦¥₩" - ), - 2046: "¬", - 2048: "ſ⁜✀々〆〒〓〞〟가", - 2073: "☜☞", - 2118: "Ŵ", - 2232: "⚯", - 2812: "◻◼◽◾☔☕☘♾♿⚒⚓⚔⚕⚖⚗⚙⚛⚜⚠⚡⚧⚪⚫⚰⚱", - }, - "신명 견고딕": { - 1: "\u302a\u302b", - 195: "ıľ", - 198: "ī", - 200: "į", - 201: "ĵ", - 205: "Ī", - 212: "ìíîïĺļł", - 213: "⁏", - 220: "ĭ", - 226: "Į", - 227: "⁚⁝⁞", - 233: "ÌÍÎÏ", - 237: "¦", - 239: "¹", - 240: "ĩ", - 253: "Ĭİ", - 255: "ţťŧ", - 270: "´Ĩ", - 279: "ŀ", - 292: "‚‛", - 300: "¡", - 310: "ŕŗř", - 312: "˙", - 313: "˚˛", - 330: "¸", - 350: "¨", - 361: "º", - 363: "²", - 364: "³", - 371: "ª", - 375: "ˇ˘Ι„‟", - 384: "¼½", - 385: "¾ij", - 398: "ι", - 417: "⁎", - 438: "˝ζξ", - 457: "с", - 463: "⁖", - 464: "з", - 466: "ŷ", - 468: "ÿ", - 469: "ýþ", - 470: "ð", - 477: "⚬", - 478: "ķ", - 480: "śŝşš", - 483: "¢çćĉċč", - 485: ( - "źżžε〿ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑→" - "↓○" - ), - 486: "υ⁑", - 487: "»", - 488: "«", - 497: "Ĵ", - 498: "ĸ", - 500: ( - "ао‧▮▯◤◥❙❚〖〗〘〙。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマ" - "ミムメモヤユヨラリルレロワン゙゚ᅠ" - ), - 506: "э", - 509: "¯", - 511: "₫", - 515: "¿", - 517: "₰", - 520: "⁙", - 521: "р", - 522: "ρ", - 524: "Þ", - 526: "τ", - 529: "ñĝğġģĥńņňʼnŋ", - 531: "ùúûüďđũūŭůűų⁊", - 532: "èéêëēĕėęě", - 533: "⚘", - 534: "àáâãäåāăą", - 535: "ô", - 537: "З", - 538: "õ", - 539: "óöøōŏő", - 540: "ò", - 542: "δμοσеё", - 544: "α", - 547: "ν", - 548: "я", - 549: "ĹĻĽĿŁ₤", - 551: "⚨⚲", - 555: "⁒", - 556: "г", - 559: "ħ", - 560: "¥", - 561: "µ", - 562: "¶γ", - 563: "κх", - 565: "π", - 574: "б", - 576: "⚚", - 577: "у", - 580: "ь", - 585: "ßŹŻŽ", - 586: "ŢŤŦ", - 592: "¤", - 593: "ч", - 594: "в", - 595: "₦", - 601: "₠₪", - 603: "Ξ", - 605: "к", - 606: "₲", - 608: "₵", - 609: "£Ρ", - 610: "Γ", - 612: "Р", - 613: "₴", - 616: "Ь", - 617: "т", - 619: "ÝŊŶŸ", - 623: "η", - 624: "⁈", - 625: "ĶΖλωГ₣", - 626: "χ", - 632: "ÀÁÂÃÄÅĀĂĄ", - 634: "⁉", - 635: "Ş", - 636: "ŚŜŠ", - 637: "₱", - 640: "и", - 641: "⁘⁛", - 643: "§", - 645: "н", - 646: "⁋⁌⁍", - 649: "ÈÉÊËĒĔĖĘĚ", - 650: "Ч₭", - 652: "⁗", - 654: "Ββ₮", - 658: "Δ₧", - 659: "⚭", - 661: "φ", - 662: "п", - 665: "₥", - 666: "₡₢", - 667: "ΕΥЁБВЕСЭЯ", - 670: "д", - 680: "⁕", - 681: "IJ", - 684: "ΧХ", - 686: "ĎĐц", - 688: "ÙÚÛÜŨŪŬŮŲъ", - 689: "ĤĦ", - 690: "Űψф", - 692: "ÑŃŅŇŔŖŘУ", - 693: "Ð", - 694: "⚥⚦", - 697: "ŵ", - 699: "ÇĆĈĊČ", - 700: "Πл", - 708: "ΘΟθО", - 711: "Т", - 716: "Τ", - 717: "Ω", - 720: "⚐⚑", - 736: "ΦЛФ", - 741: "Ψ", - 749: "ÒÓÔÕÖŌŎŐ", - 750: "ΑΗΚΛΝАИЙН►◄", - 751: "ĜĞĠĢ", - 762: "ж", - 764: "©®", - 769: "₳", - 770: "м", - 774: "♦", - 780: "П", - 781: "Σ", - 787: "Ø", - 794: "Д", - 795: "Ъ", - 796: "⁔", - 798: "ю", - 799: "⁐⚢", - 801: "Ц", - 802: "⁓", - 810: "₨", - 813: "К", - 829: "æ", - 833: "⁇", - 844: "⚩", - 861: "◸◹◺◿", - 872: "œ", - 874: "⚣⚤", - 875: "шы", - 890: "щ", - 898: "⚊⚋⚌⚍⚎⚏", - 900: "Ы", - 904: "Ŵ", - 912: "ΜМ", - 924: "Œ", - 932: "⚮", - 936: "¬", - 950: "Æ", - 970: ( - "₯∊∍≛⋍⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿▢▭▰▻◅◌◍◖◗◚◛◠◡◢◣◧◨◩◪◫◬◭◮◰◱◲◳◴◵◶◷☀☉☊☋☌☍☐☓☖☗" - "☙☚☛☠☡☣☤☥☦☧☩☪☫☬☭☸☹☾☿♁♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♢♰♱♲♳♴♵♶♷♸♹" - "♺♻♼♽⚀⚁⚂⚃⚄⚅⚆⚇⚈⚉✁✃✄✆✇✈✌✍✎✏✐✑✒✓✕✖✘✙✚✛✜✞✟✠✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸" - "✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❛❜❝❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❿➀➁➂➃➄➅➆➇" - "➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➝➞➟➠➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻➼➽➾〝〠〡〢〣〤〥〦〧〨〩" - "〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾⦅⦆¦" - ), - 1000: ( - "ſːЖШЩЮй‐‑‒―‖‗†‡•‣․‥‱′″‴‵‶‷‸‹›‼‽‾‿⁀⁁⁂⁃⁄⁅⁆⁜⁴ⁿ₁₂₃₄₩€℉ℓ№℡™ΩÅ⅓⅔⅛⅜" - "⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∋∌∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡∢∣∤∥∦∧∨∩∪∫∬∭∮∯∰∱∲∳" - "∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≜≝≞≟≠≡≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰" - "≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬" - "⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩" - "⋪⋫⋬⋭⋮⋯⋰⋱⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨ" - "ⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂" - "╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▪▫▬▱▴▵▶▷▸▹▼▽▾▿◀◁◂◃◈◉◊◎◐◑◒◓◔◕◘◙◜◝◞◟◦◯☁☂☃☄☇☈☎" - "☏☑☒☜☝☞☟☢☨☮☯☰☱☲☳☴☵☶☷☺☻☼☽♀♂♠♡♣♤♥♧♨♩♪♫♬♭♮♯✀✂✉✔✗✝✡❶❷❸❹❺❻❼❽❾➜➡、。〃" - "〄々〆〇【】〒〓〔〕〚〛〜〞〟㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯" - "㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱" - "㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝가!"#$%&'()*+,-./0123456789:" - ";<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuv" - "wxyz{|}~¢£¬ ̄¥₩■" - ), - 1089: "⚯", - 1373: "◻◼◽◾☔☕☘♾♿⚒⚓⚔⚕⚖⚗⚙⚛⚜⚠⚡⚧⚪⚫⚰⚱", - }, - "한양그래픽": { - 2: "\u302a\u302b", - 322: "˙", - 345: "ː", - 437: "⁏", - 465: "⁚⁝⁞", - 513: "¦ìíîïīĭįıĵĺļľł", - 527: "˛", - 541: "˚", - 585: "ĩ", - 588: "Ι", - 592: "․‧", - 598: "ÌÍÎÏĨĪĬĮİ", - 641: "ŀ", - 656: "⁴ⁿ₁₂₃₄", - 676: "ι", - 682: "¸ŕŗřţťŧ‚‛", - 687: "‖′‵", - 756: "‣", - 768: "²³´¹ſ", - 773: "˘", - 790: "ˇ", - 811: "‹›", - 818: "•", - 854: "⁎", - 891: "˝", - 897: "ªº", - 898: "‡", - 916: "τ‼", - 934: "⁃", - 939: "‟", - 951: "⁖", - 967: "⁅⁆", - 970: "″‶", - 977: "⚬", - 984: "‽", - 994: ( - "〿。「」、ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑→" - "↓■○" - ), - 996: "⁑", - 1024: ( - "¡¨«¯»ýÿŷźżž„【】〔〕〖〗〘〙〚〛・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハ" - "ヒフヘホマミムメモヤユヨラリルレロワン゙゚ᅠ" - ), - 1047: "₫", - 1059: "₰", - 1060: "её", - 1067: "⁙", - 1074: "δ", - 1076: "‸", - 1082: "‐‑", - 1088: "⁊", - 1092: "ζξ⚘", - 1094: "сэ", - 1098: "ν", - 1100: "β", - 1102: "з", - 1106: "х", - 1108: "у", - 1110: "Ĵķĸśŝşšμ", - 1125: "ь", - 1129: "⚨⚲", - 1131: "ρ", - 1137: "ε⁒", - 1142: "†", - 1147: "а", - 1153: "¤§¶¼½¾", - 1160: "κ", - 1168: "οо₤", - 1170: "б", - 1172: "гт", - 1174: "γ", - 1180: "Ρ⚚", - 1186: "‗", - 1191: "Þ", - 1194: "¢µ¿àáâãäåçèêëùúûüāăąćĉċčēĕėęěĥħijĹĻĽĿŁŢŤŦũūŭůűų", - 1195: "é", - 1203: "Β", - 1208: "η", - 1211: "υ", - 1213: "В", - 1215: "θ", - 1216: "‾", - 1219: "£₦", - 1224: "к", - 1227: "в", - 1229: "φ", - 1231: "₠₪", - 1232: "З", - 1242: "Р₲", - 1246: "Ζря‴‷₵", - 1248: "ΕЁБЕ", - 1254: "Γ", - 1256: "₴", - 1264: "χий", - 1274: "Г", - 1278: "⁈", - 1280: "¥ÝßðñòóôõöøþďđĝğġģńņňŋōŏőŶŸŹŻŽ‒", - 1290: "ч", - 1295: "₣", - 1298: "ц⁉", - 1301: "⁄", - 1305: "₱", - 1311: "‥", - 1314: "ΚЯ⁘⁛", - 1324: "ΤТ⁋⁌⁍", - 1330: "Ь", - 1332: "₭", - 1336: "⁗", - 1340: "₮", - 1342: "н", - 1344: "€", - 1346: "σ", - 1348: "С", - 1350: "⚭", - 1352: "α", - 1354: "ΞЭ", - 1362: "лп₥", - 1364: "ψ⁁₡₢", - 1366: "ÀÁÂÃÄÅÈÉÊËĀĂĄĒĔĖĘĚĶŚŜŞŠ", - 1377: "К", - 1395: "⁕", - 1422: "⚥⚦", - 1424: "Δм", - 1426: "ΘΟО", - 1428: "Π", - 1434: "Ч", - 1440: "¬ΥΧХ", - 1442: "ΑА", - 1448: "λ", - 1450: "ŔŖŘ", - 1453: "ъ", - 1454: "д", - 1462: "πω", - 1467: "ΗΝН", - 1473: "ИЙ", - 1475: "⚐⚑", - 1477: "ʼnΩ", - 1504: "ПЦ", - 1506: "ΛЛ", - 1524: "Д", - 1528: "Ψ", - 1530: "ΦФ", - 1537: "ÇÐÑÙÚÛÜĆĈĊČĎĐĤĦIJŃŅŇŊŨŪŬŮŰŲŵУ", - 1547: "Σ", - 1575: "₳", - 1576: "‿⁀", - 1600: "ж", - 1604: "©®", - 1614: "æ", - 1616: "Ъ", - 1622: "ÒÓÔÕÖØŌŎŐ", - 1626: "₩", - 1629: "ю", - 1631: "⁔", - 1637: "⁐", - 1639: "⚢", - 1645: "⁓", - 1650: "ы", - 1658: "₨", - 1682: "ΜМ", - 1690: "шщ", - 1706: "ĜĞĠĢ⁇", - 1729: "⚩", - 1764: "◸◹◺◿", - 1772: "ШЩ", - 1790: "Ы⚣⚤", - 1792: "œ―", - 1840: "ф⚊⚋⚌⚍⚎⚏", - 1862: "⁂", - 1878: "Ŵ", - 1903: "Ж", - 1909: "⚮", - 1921: "Æ", - 1942: "Ю", - 1958: "‱", - 1960: "₧", - 1986: ( - "₯℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∊∋∌∍∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡∢∣∤∥" - "∦∧∨∩∪∫∬∭∮∯∰∱∲∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟≠≡" - "≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝" - "⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙" - "⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰" - "⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤" - "┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱▴▵▶▷" - "▸▹►▻▼▽▾▿◀◁◂◃◄◅◈◉◊◌◍◎◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷" - "☀☁☂☃☄☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☙☚☛☝☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂" - "♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽⚀" - "⚁⚂⚃⚄⚅⚆⚇⚈⚉✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷" - "✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❙❚❛❜❝❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻" - "❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻" - "➼➽➾、。〃〄〇〜〝〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘" - "㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝" - "㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'" - "()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abc" - "defghijklmnopqrstuvwxyz{|}~⦅⦆¢£¬ ̄¦¥₩" - ), - 2048: "Œ⁜✀々〆〒〓〞〟가", - 2073: "☜☞", - 2232: "⚯", - 2812: "◻◼◽◾☔☕☘♾♿⚒⚓⚔⚕⚖⚗⚙⚛⚜⚠⚡⚧⚪⚫⚰⚱", - }, - "바탕": { - 256: "¦", - 271: "′∙", - 299: "ìíîïĩīĭįıĺļľł‚‛", - 319: "ĵ˙", - 320: "˚˛", - 321: "\u0387", - 339: "‹›", - 341: "´¸∕", - 352: "ŀ", - 368: "²³", - 384: "\u00ad¯¹ÌÍÎÏĨĪĬĮİţťŧſˇ˘Ι•▪▫◦", - 401: "″", - 408: "ι", - 427: "¡ŕŗř", - 429: "ℓ", - 443: "ⁿ", - 448: "˝ζξ", - 468: "с", - 469: "Ĵźżž", - 475: "з", - 480: "ªº", - 497: "ε∫", - 498: "υ", - 512: "\u00a0¢£¤§¨«»¿àáâãäåāăąćĉċčśŝşšао‗„‾⁄∂", - 518: "э", - 532: "ç", - 533: "р", - 535: "ρ", - 539: "τ", - 543: "⅝", - 550: "З", - 555: "µèéêëðñòóôõöøùúûüþďđēĕėęěĝğġģĥħķĸńņňŋōŏőũūŭůűųδμοσеё", - 557: "α", - 560: "ν", - 561: "я", - 562: "₤√", - 569: "г", - 575: "γ", - 576: "¼½¾ijκ⅛⅜⅞", - 577: "х", - 579: "π", - 588: "б", - 591: "у", - 594: "ь", - 597: "ýÿŷ", - 601: "‡", - 607: "ч", - 608: "в†", - 617: "Ξ", - 619: "к", - 624: "Ρ", - 625: "Γ", - 627: "Р", - 628: "∆", - 631: "Ь", - 632: "т", - 638: "η", - 639: "♂", - 640: "¶ßĹĻĽĿŁŚŜŞŠŹŻŽΖλωГ‼₣", - 641: "χ", - 655: "и", - 660: "н", - 666: "Ч", - 670: "Ββ", - 674: "Δ₧", - 677: "φ", - 678: "п", - 683: "¥ÈÉÊËÝÞĆĈĊČĒĔĖĘĚŔŖŘŶŸΕΥЁБВЕСЭЯ", - 684: "∩", - 686: "д", - 690: "Ç€", - 700: "ΧХ", - 702: "ц", - 704: "ʼn―♪", - 705: "ъ", - 707: "ψф", - 709: "У", - 717: "Πл∏", - 725: "ÐÒÓÔÕÖØĎĐĜĞĠĢŌŎŐΘΟθО", - 728: "Т", - 733: "Τ", - 734: "Ω", - 736: "Ω", - 747: "♀", - 754: "ΦЛФ", - 759: "Ψ", - 768: "ÀÁÂÃÄÅÑÙÚÛÜĀĂĤĦIJĶŃŅŇŊŢŤŦŨŪŬŮŰŲΑΗΚΛΝАИЙН↕►◄♠", - 769: "Ą", - 780: "ж", - 781: "♫", - 786: "≈", - 788: "м", - 793: "◊♦", - 799: "П", - 800: "Σ", - 802: "©®", - 804: "¬", - 811: "ŵ", - 812: "♥", - 813: "Д", - 814: "Ъ", - 817: "ю", - 820: "Ц", - 832: "К∑−≠≡≤≥", - 864: "♣", - 865: "æ", - 870: "œ", - 896: "шы", - 911: "щ", - 922: "Ы", - 933: "∞", - 934: "ΜМ", - 936: "▼", - 938: "☼", - 960: "Œ", - 974: "∟", - 981: "Ŵ", - 1024: ( - "ÆːЖШЩЮй‥⁴₁₂₃₄₩℉№℡™Å⅓⅔↔↖↗↘↙⇒⇔∀∃∇∈∋∝∠∥∧∨∪∬∮∴∵∼∽≒≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠" - "⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└" - "┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦" - "▧▨▩▬▶▷▽◀◁◈◎◐◑◘◙☎☏☜☞☺☻♡♤♧♨♩♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖" - "㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛" - "㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%" - "&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a" - "bcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - }, - "바탕체": { - 512: ( - "\u0387\u00a0¢£¥¦©«¬¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöùú" - "ûüýÿĀāĂ㥹ĆćĈĉĊċČčĎďĐĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĨĩĪīĬĭĮįİĴĵĶķĹĺĻļĽľ" - "ŃńŅņŇňŌōŎŏŐőŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſ‗‚‛„•‹" - "›‼‾⁄₣₤₧₩∆−∕∙∟≈▪▫▬►◄◊◘◙◦☺☻☼♦♫" - ), - 993: "✀", - 1024: ( - "¡¤§¨ª\u00ad®²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘ" - "ΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТ" - "УФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄€℉" - "ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝" - "⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑" - "┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣" - "▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑" - "㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖" - "㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝" - "!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\" - "]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - }, - "돋움": { - 256: "¦ìíîïīĭĮįıĵĺļľł", - 299: "ÌÍÎĨĩĪĬİΙ‚‛∙", - 302: "Ï", - 320: "\u0387ŀ˚˛", - 325: "˙", - 330: "²³", - 341: "´¸ŕŗřţťŧ", - 344: "′", - 384: "¹ºſ˘ι•‹›∫▪▫◦", - 413: "ª", - 427: "¡", - 448: "ˇ˝", - 469: "„", - 512: "\u00a0¨«\u00ad¯»¼½¾ýÿijŷźżžζνξУух‗‾⁄ⁿ₧ℓ∕", - 513: "√", - 525: "ь", - 555: "Ĵķśŝşš", - 575: "⅜", - 576: "£¤§¶ĸγεκꆇ⅛⅝⅞∂", - 577: "βз″", - 581: "μ", - 585: "δ", - 588: "э", - 595: "я", - 597: "¢µ¿àáâãäåçèéêëùúûüāăąćĉċčēĕėęěĥħĹĻĽĿŁŢŤŦũūŭůűųΤτυχЗТЧаесчё", - 598: "бг", - 609: "ΓГ₣₤", - 610: "т", - 624: "ъ", - 625: "в", - 628: "∆", - 634: "ц", - 640: "¥ÝßðñòóôõöøþďđĝğġģńņňŋōŏőŶŸŹŻŽΖΥΧαηορσφХор‼♀♂", - 656: "н", - 657: "л", - 661: "п", - 669: "д", - 674: "и", - 678: "й", - 683: "ÀÁÂÃÄÅÈÉÊËÞĀĂĄĒĔĖĘĚŚŜŞŠΑΕΛΡЁАЕРЬ", - 691: "Σ", - 704: "ʼnθλπ―∏♪", - 719: "Π", - 720: "¬", - 722: "Δ", - 725: "ĶŔŖŘΒΚБВКЯ", - 732: "Л", - 736: "∩", - 749: "ψ", - 756: "Э", - 758: "м", - 760: "Ц", - 768: "ÇÑÙÚÛÜĆĈĊČĎĤĦIJŃŅŇŨŪŬŮŰŲŵΗΝΞΩωИЙНПС€Ω↕►◄♠", - 769: "Ŋ", - 770: "ÐĐ", - 781: "♫", - 782: "ф", - 787: "ж", - 789: "ΦФю", - 793: "◊♦", - 798: "ы", - 802: "©®", - 806: "Ъ", - 811: "ÒÓÔÕÖØŌŎŐΘΟО", - 812: "♥", - 814: "Ψ", - 832: "æД∑", - 845: "Ы", - 853: "ĜĞĠĢ−≈≠≡≤≥", - 859: "щ", - 861: "ш", - 864: "♣", - 896: "œΜМ", - 933: "∞", - 936: "▼", - 938: "☼", - 939: "Ŵ", - 957: "Œ", - 960: "ÆЖ", - 981: "₩", - 990: "ШЩ", - 995: "☃", - 1006: "∟", - 1015: "Ю", - 1024: ( - "ː‥⁴₁₂₃₄℉№℡™Å⅓⅔↔↖↗↘↙⇒⇔∀∃∇∈∋∝∠∥∧∨∪∬∮∴∵∼∽≒≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧" - "⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛" - "├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▬▶▷▽" - "◀◁◈◎◐◑◘◙☎☏☜☞☺☻♡♤♧♨♩♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠" - "㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢" - "㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+," - "-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefgh" - "ijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - }, - "돋움체": { - 512: ( - "\u0387\u00a0¢£¥¦©«¬¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöùú" - "ûüýÿĀāĂ㥹ĆćĈĉĊċČčĎďĐĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĨĩĪīĬĭĮįİĴĵĶķĹĺĻļĽľ" - "ŃńŅņŇňŌōŎŏŐőŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſ‗‚‛„•‹" - "›‼‾⁄₣₤₧₩∆−∕∙∟≈▪▫▬►◄◊◘◙◦☺☻☼♦♫" - ), - 993: "✀", - 1024: ( - "¡¤§¨ª\u00ad®²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘ" - "ΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТ" - "УФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄€℉" - "ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝" - "⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑" - "┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣" - "▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑" - "㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖" - "㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝" - "!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\" - "]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - }, - "굴림": { - 256: "¦ìíîïīĭįıĵĺļľł∙", - 293: "ĩ", - 299: "ÌÍÎÏĨĪĬĮİΙ", - 320: "\u0387ŀ˙˚˛", - 341: "¸ŕŗřţťŧ‚‛", - 384: "²³´¹ſˇ˘ι•′‹›∫▪▫◦", - 427: "¡⁄∕", - 448: "ªº˝ⁿ", - 512: "\u00a0¨«\u00ad¯»ýÿŷźżžζνξгух‗„″‾ℓ", - 555: "ĴķĸśŝşšκУк", - 561: "ь", - 562: "√", - 576: "¤§¶¼½¾γεзлчя†‡⅛⅜⅝⅞∂", - 577: "β", - 585: "δд", - 596: "Þ", - 597: "¢µ¿àáâãäåçèéêëùúûüāăąćĉċčēĕėęěĥħijĹĻĽĿŁŢŤŦũūŭůűųΤμτυχТЧаестё", - 609: "£ΓГ₣₤", - 623: "ц", - 628: "∆", - 640: "¥ÝßðñòóôõöøþďđĝğġģńņňŋōŏőŶŸŹŻŽΖΥΧαηορσφЗХбвийнопръэ‼♀♂", - 673: "Ь", - 683: "ÀÁÂÃÄÅÈÉÊËĀĂĄĒĔĖĘĚĶŚŜŞŠΕΚΛΡЁАБЕКР₧", - 704: "ΑΣΨθλπ―∏♪", - 719: "Π", - 720: "¬", - 725: "ŔŖŘΒВЯ", - 729: "Л", - 736: "ы∩", - 738: "ʼn", - 749: "ψ", - 756: "Ц", - 768: "ÇÐÑÙÚÛÜĆĈĊČĎĐĤĦIJŃŅŇŊŨŪŬŮŰŲŵΗΝΩωИЙНСЪЭжмф€Ω↕►◄♠", - 769: "Δ", - 781: "♫", - 790: "П", - 793: "◊♦", - 802: "©®", - 806: "æ", - 811: "ÒÓÔÕÖØŌŎŐΘΟΦО", - 812: "♥", - 832: "ΞДФшщ∑", - 853: "ĜĞĠĢ−≈≠≡≤≥", - 856: "М", - 864: "♣", - 865: "Ы", - 896: "œΜ", - 911: "ю", - 935: "∞", - 936: "▼", - 938: "☼", - 939: "Ŵ₩", - 960: "ÆШЩ", - 989: "Ж", - 995: "☃", - 1006: "∟", - 1024: ( - "ŒːЮ‥⁴₁₂₃₄℉№℡™Å⅓⅔↔↖↗↘↙⇒⇔∀∃∇∈∋∝∠∥∧∨∪∬∮∴∵∼∽≒≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥" - "⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙" - "┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▬▶" - "▷▽◀◁◈◎◐◑◘◙☎☏☜☞☺☻♡♤♧♨♩♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛" - "㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠" - "㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*" - "+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdef" - "ghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - }, - "굴림체": { - 512: ( - "\u0387\u00a0¢£¥¦©«¬¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöùú" - "ûüýÿĀāĂ㥹ĆćĈĉĊċČčĎďĐĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĨĩĪīĬĭĮįİĴĵĶķĹĺĻļĽľ" - "ŃńŅņŇňŌōŎŏŐőŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſ‗‚‛„•‹" - "›‼‾⁄₣₤₧₩∆−∕∙∟≈▪▫▬►◄◊◘◙◦☺☻☼♦♫" - ), - 993: "✀", - 1024: ( - "¡¤§¨ª\u00ad®²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘ" - "ΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТ" - "УФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄€℉" - "ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝" - "⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑" - "┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣" - "▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑" - "㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖" - "㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝" - "!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\" - "]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - }, - "궁서": { - 256: '¦∙', - 296: '․‧', - 320: '˙˚·', - 328: '⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉', - 341: '¸‚‛′', - 343: '‖‵', - 378: '‣', - 379: '‟', - 384: '´ˇ˘˛•‹›∕▪▫◦', - 427: '¡⁄', - 448: '\xad¯', - 512: '\xa0¤¨ª²³¹º¼½¾ĵſ˝ζξ‗„‾ⁿ⅛⅜⅝⅞', - 538: '″ℓ', - 541: '‐‑', - 550: '«»', - 555: 'ìíîïĩīĭįıĺļľŀł', - 557: 'ίι', - 563: '√', - 576: 'έ冇', - 583: '∫', - 597: '¿ÌÍÎÏĨĪĬĮİŕŗřśŝşšţťŧźżžΪ', - 602: 'Ι', - 608: '∂', - 611: '‼', - 612: 'δ', - 614: 'τз', - 620: 'г', - 623: '‴', - 631: 'οо', - 640: '¢§çèéêëðćĉċčēĕėęěĴΰβθςυбестхэё‒♀♂', - 663: 'Ь', - 665: 'ь', - 666: 'н', - 675: 'я', - 683: 'ÞàáâãäåñòóôõöøùúûüýþÿāăąďđĝğġģĥħķĸĹĻĽĿŁńņňʼnŋōŏőũūŭůűųŷΓΡάήαγηκμνρφГРУЧавдкруч₧', - 684: 'п', - 694: '₣', - 704: '£¬µ¶ΔΖΦσЗФЭ―₤∆♪', - 725: 'ÀÁÂÃÄÅÇÈÉÊËÐÒÓÔÕÖØÝĀĂĄĆĈĊČĎĐĒĔĖĘĚŌŎŐŚŜŞŠŢŤŦŶŸŹŻŽΑΒΕΛΟΣΤΥΧΫЁАБВЕОСТХ€', - 726: 'Θ', - 733: 'ий', - 736: '∩', - 738: 'ц', - 742: '¥', - 746: 'π', - 747: 'м', - 748: 'χ', - 751: 'ъ', - 768: 'ÑßĜĞĠĢĤĦĶŃŅŇŊŔŖŘΗΚΝλИЙКНПЦЯ₩℮↕≈►◄♠', - 779: 'л', - 781: '♫', - 782: 'Π', - 786: 'ф', - 792: 'Д', - 793: '◊♦', - 796: 'ω', - 802: '©®', - 810: 'Ξfifl', - 811: 'ÙÚÛÜŨŪŬŮŰŲŵ', - 812: '♥', - 817: 'Лш', - 818: '∏', - 832: 'æΩψжΩ', - 853: 'ŴΜМ−≠≡≤≥', - 862: 'щ', - 864: 'Ъ♣', - 896: 'ы', - 905: 'Ψ', - 909: 'ю', - 919: '∑', - 923: 'ij', - 935: '∞', - 936: '▼', - 938: '☼', - 971: 'œ', - 979: '‱', - 983: '№', - 1024: 'ÆIJŒːЖШЩЫЮ‥⁴₁₂₃₄℉℡™Å⅓⅔↔↖↗↘↙⇒⇔∀∃∇∈∋∝∟∠∥∧∨∪∬∮∴∵∼∽≒≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▬▶▷▽◀◁◈◎◐◑◘◙☎☏☜☞☺☻♡♤♧♨♩♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩', - }, - "궁서체": { - 512: ( - "\u0387\u00a0¢£¥¦©«¬¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöùú" - "ûüýÿĀāĂ㥹ĆćĈĉĊċČčĎďĐĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĨĩĪīĬĭĮįİĴĵĶķĹĺĻļĽľ" - "ŃńŅņŇňŌōŎŏŐőŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſ‗‚‛„•‹" - "›‼‾⁄₣₤₧₩∆−∕∙∟≈▪▫▬►◄◊◘◙◦☺☻☼♦♫" - ), - 993: "✀", - 1024: ( - "¡¤§¨ª\u00ad®²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘ" - "ΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТ" - "УФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄€℉" - "ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝" - "⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑" - "┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣" - "▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑" - "㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖" - "㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝" - "!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\" - "]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - }, - "한컴 고딕": { - 161: "\u0387", - 254: "ι", - 260: "²³¹", - 300: "´", - 317: "Ι", - 378: "ª", - 385: "º", - 436: "⁑", - 446: "¡§¸", - 448: "υ", - 473: "ν", - 477: "ψ", - 478: "\u00ad", - 486: "ː˛′″⁴ⁿ₁₂₃₄∂、。【】〔〕", - 501: "σ", - 525: "κ", - 529: "ε", - 544: "я", - 547: "γ", - 549: "β", - 552: "ρ", - 556: "θ", - 560: "δ", - 572: "Τ", - 575: "μ", - 581: "Υ", - 582: "ο", - 584: "Ζ", - 586: "•", - 588: "ζ", - 593: "λτ", - 595: "αη", - 600: "Λ", - 607: "Χ", - 608: "ξ", - 609: "Γ", - 620: "Σ", - 624: "ΞΦ", - 625: "Ε", - 637: "ω", - 650: "Ωπ", - 653: "ΑΔ", - 656: "φ", - 657: "Ψχ", - 660: "Ρ", - 664: "ΒΚ", - 666: "Π", - 669: "¿", - 672: "―", - 676: "ΘΟ", - 680: "€", - 694: "Η", - 728: "Ν", - 800: "¨¶øþ", - 826: "Μ", - 892: "¤®¼½¾ÆÐØÞßæðŒœ†‡™", - 932: ( - "đĦħıIJijĸĿŀŁłʼnŊŋŦŧˇ˘˙˚˝ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгде" - "жзийклмнопрстуфхцчшщъыьэюё‥℉ℓ№℡ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧" - "∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙ" - "ⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳" - "┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000" - "〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿" - "㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾" - "㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGH" - "IJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - 970: "◉◯☐☑❍", - }, - "함초롬바탕": { - 0: "\u302a\u302b", - 157: "˙", - 161: "·", - 168: "ː", - 257: "˛", - 264: "˚", - 286: "¦", - 287: "ìíîïĩīĭįıĺļΙ", - 288: "ĵ", - 289: "․‧", - 290: "⁚", - 291: "‚‛⁏⁝⁞", - 296: "´", - 300: "\u00a0", - 305: "ÌÍÎÏĨĪĬĮİ", - 313: "\uf09e\uf0a0", - 315: "Ĵ", - 320: "¡²³¹⁴ⁿ₁₂₃₄", - 330: "ι", - 335: "‖′‵", - 336: "ſ", - 356: "ţŧ", - 364: "ł", - 369: "‣", - 374: "¨", - 377: "˘", - 385: "\uf0fa", - 386: "ˇ", - 396: "º‹›", - 399: "•", - 411: "„‟", - 422: "ľ", - 426: "ŀ", - 433: "ª", - 434: "ť", - 435: "˝", - 438: "‡", - 440: "«»", - 447: "τ‼", - 456: "\u00ad⁃", - 458: "\uf027\uf073\uf09f\uf0a7", - 472: "⁅⁆", - 474: "″‶", - 478: "ŕŗř", - 480: "‽", - 483: "\uf0f9", - 485: ( - "〿。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロ" - "ワン゙゚ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑→↓" - "■○" - ), - 486: "źżž⁎⁑", - 496: "śŝşš", - 498: "§", - 500: "【】〔〕〖〗〘〙〚〛\uf07f", - 511: "₫", - 517: "₰", - 518: "её", - 524: "δ", - 525: "‸", - 528: "‐‑", - 531: "⁊\uf07d\uf07e", - 533: "ζξ", - 534: "сэ", - 536: "èéêëēĕėęěν", - 537: "β", - 538: "з⁖", - 540: "х", - 541: "у", - 542: "μ", - 543: "ýÿŷ", - 544: "ß", - 549: "ь\uf047\uf048", - 550: "µ¿", - 552: "çćĉċčρ", - 554: "\uf035", - 555: "ε⁒", - 558: "†⁕", - 560: "ŋа", - 561: "¢", - 562: "ĝğġģ", - 564: "¬", - 566: "κ", - 568: "£", - 569: "àáâãäåāăą", - 570: "ðοо₤", - 571: "б", - 572: "гт", - 573: "γ⁗", - 574: "ij", - 575: "¯Þ", - 576: "Ρ", - 578: "\uf077", - 579: "‗", - 580: "ķ", - 584: "IJ", - 587: "Β\uf041", - 588: "òóôõöōŏő", - 590: "η", - 591: "υ", - 592: "В", - 593: "θ", - 594: "‾", - 595: "₦", - 598: "к", - 599: "в", - 600: "φ", - 601: "₠₪", - 602: "З", - 603: "⁙\uf036", - 605: "ĹĻĽĿ", - 606: "¶Р₲", - 608: "þΖря‴‷₵", - 609: "ΕЁБЕ", - 610: "¤", - 612: "¸Γ", - 613: "₴", - 615: "ĸ", - 617: "χий", - 622: "Г", - 624: "⁈⁘", - 625: "‒", - 626: "ŹŻŽ", - 627: "ÈÉÊËĒĔĖĘĚŚŜŞŠ", - 630: "ч", - 632: "₣", - 634: "ц⁉", - 635: "ñùúûüĥńņňũūŭůűų⁄", - 636: "\uf0fb", - 637: "₱", - 638: "Ł", - 640: "đ‥", - 642: "ĶΚЯ", - 646: "ΤТ⁋⁌⁍", - 649: "Ь", - 650: "₭", - 651: "\uf053", - 654: "₮", - 655: "н", - 656: "€", - 657: "σ", - 658: "С", - 660: "ŔŖŘα\uf04e", - 661: "ΞЭ", - 664: "ŢŤŦ", - 665: "ħлп₥", - 666: "ψ⁁₡₢", - 672: "К", - 674: "\uf043\uf044", - 683: "ĜĞĠĢ", - 684: "ď⁛", - 685: "ÇøĆĈĊČ", - 688: "⁓", - 693: "\uf058", - 695: "Δм", - 696: "ØΘΟО", - 697: "Π", - 700: "Ч\uf032\uf033", - 703: "ΥΧХ", - 704: "ΑА", - 705: "ÝʼnŶŸ", - 706: "ÀÁÂÃÄÅĀĂĄ", - 707: "¥λ", - 709: "ъ", - 710: "д", - 714: "πω", - 716: "ŊΗΝН", - 719: "ĎИЙ", - 720: "ŵ", - 721: "Ω", - 723: "\uf057", - 731: "ÙÚÛÜŨŪŬŮŰŲ", - 732: "ÒÓÔÕÖŌŎŐ", - 734: "ÑĤŃŅŇПЦ", - 735: "ΛЛ", - 744: "Д", - 746: "Ψ", - 747: "ΦФ\uf055\uf056\uf06c\uf06e\uf074", - 750: "У", - 755: "Σ", - 762: "Ħ", - 768: "Ð", - 769: "Đ⁜₳", - 770: "‿⁀⁔", - 776: "\uf0e3\uf0e4\uf0e5\uf0e6", - 780: "\uf069", - 781: "ж", - 783: "\uf0f5\uf0f6\uf0f7\uf0f8", - 787: "\uf0fc", - 789: "Ъ", - 793: "\uf042", - 794: "₩\uf059\uf0d7\uf0d8", - 795: "ю", - 799: "⁐", - 800: "©®", - 806: "ы", - 810: "₨", - 811: "\uf0f1\uf0f2\uf0f4", - 813: "\uf054", - 821: "ΜМ", - 825: "шщ", - 843: "\uf04a\uf04b\uf04c", - 849: "\uf04f", - 865: "ШЩ", - 873: "\uf0eb\uf0ec\uf0ed\uf0ee", - 874: "Ы", - 875: "―", - 877: "œ", - 878: "⁇", - 880: "\uf052", - 885: "\uf05a", - 887: "\uf051", - 891: "æ\uf03b\uf03e\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0", - 893: "\uf029\uf034\uf03c\uf03d\uf049\uf05b\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0fd\uf0fe", - 894: "\uf025", - 896: "\uf05c", - 898: "ф", - 909: "⁂", - 910: "Ŵ", - 911: "\uf03f\uf040", - 921: "Œ", - 929: "Ж\uf066", - 933: "\uf063", - 940: "\uf03a\uf062", - 943: "\uf045\uf046", - 947: "\uf038\uf064", - 948: "Ю", - 953: "\uf06d\uf0a6", - 956: "‱", - 957: "₧", - 959: "Æ", - 963: "\uf060", - 970: ( - "¼½¾\u205f₯℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∊∋∌∍∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡" - "∢∣∤∥∦∧∨∩∪∫∬∭∮∯∰∱∲∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝" - "≞≟≠≡≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙" - "⊚⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕" - "⋖⋗⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬" - "⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠" - "┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱" - "▴▵▶▷▸▹►▻▼▽▾▿◀◁◂◃◄◅◈◉◊◌◍◎◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳" - "◴◵◶◷◸◹◺◻◼◽◾◿☀☁☂☃☄☇☈☉☊☋☌☍☎☏☐☑☒☓☔☕☖☗☘☙☚☛☝☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳" - "☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯" - "♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚇⚈⚉⚊⚋⚌⚍⚎⚏⚐⚑⚒⚓⚔⚕⚖⚗⚘⚙⚚⚛⚜⚠⚡⚢⚣⚤⚥⚦⚧⚨⚩⚪⚫⚬⚭⚮" - "⚯⚰⚱⚲✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸✹✺✻✼" - "✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❙❚❛❜❝❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻❼❽❾❿➀" - "➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻➼➽➾\u3000、" - "。〃〄々〆〇〒〓〜〝〞〟〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖" - "㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛" - "㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%" - "&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a" - "bcdefghijklmnopqrstuvwxyz{|}~⦅⦆ᅠ¢£¬ ̄¦¥₩" - ), - 980: "\uf0df\uf0e0", - 987: "\uf075", - 1000: "\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4", - 1012: "☜☞", - 1025: "\uf065", - 1031: "\uf021", - 1036: "\uf0ff", - 1047: "\uf0c7\uf0c8\uf0c9\uf0ca", - 1051: "\uf06a", - 1054: "\uf05f", - 1060: "\uf078\uf079\uf0f3", - 1065: "\uf068", - 1067: "\uf0e7\uf0e8", - 1073: "\uf037", - 1078: "\uf039", - 1083: "\uf028", - 1089: "\uf050", - 1091: "\uf061", - 1096: "\uf030\uf067", - 1111: "\uf04d", - 1133: "\uf02a\uf02b", - 1145: "\uf022", - 1156: "\uf05e", - 1171: "\uf02c\uf02d", - 1216: "\uf026", - 1253: "\uf0d5\uf0d6", - 1271: "\uf06b", - 1300: "\uf023", - }, - "함초롬돋움": { - 0: "\u302a\u302b", - 157: "˙", - 161: "·", - 168: "ː", - 240: "´", - 257: "˛", - 258: "ĺļ", - 264: "˚", - 268: "ĵ", - 271: "ìíîïĩīĭįı", - 287: "Ι", - 288: "‚‛", - 289: "․‧", - 290: "⁚", - 291: "⁏⁝⁞", - 300: "\u00a0", - 309: "ſ", - 313: "\uf09e\uf0a0", - 317: "ÌÍÎÏĨĪĬĮİ", - 320: "²³¹⁴ⁿ₁₂₃₄", - 330: "ι", - 333: "¡", - 334: "ł", - 335: "‖′‵", - 349: "ţŧ", - 361: "ľ", - 369: "‣", - 373: "¸", - 377: "˘", - 378: "ªť", - 382: "ŀ", - 385: "º\uf0fa", - 386: "ˇ", - 396: "‹›", - 399: "•", - 427: "ŕŗř", - 435: "˝", - 438: "‡", - 447: "τ‼", - 451: "„", - 456: "⁃", - 458: "\uf027\uf073\uf09f\uf0a7", - 464: "¦", - 466: "ýÿŷ", - 472: "⁅⁆", - 474: "″‶", - 478: "\u00ad¯", - 479: "źżž", - 480: "‽", - 483: "\uf0f9", - 485: ( - "〿。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロ" - "ワン゙゚ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑→↓" - "■○" - ), - 486: "§⁎⁑", - 488: "‟", - 489: "ij", - 500: "ð【】〔〕〖〗〘〙〚〛\uf07f", - 511: "₫", - 513: "çćĉċčśŝşš", - 514: "¢¨", - 515: "Ĵ", - 517: "₰", - 518: "её", - 524: "δ", - 525: "‸", - 528: "‐‑", - 531: "¬⁊\uf07d\uf07e", - 533: "ζξ", - 534: "Þсэ", - 535: "«", - 536: "»ν", - 537: "β", - 538: "з⁖", - 540: "х", - 541: "þу", - 542: "μ", - 543: "¶", - 549: "ь\uf047\uf048", - 552: "ρ", - 554: "\uf035", - 555: "¥µε⁒", - 556: "£", - 558: "†⁕", - 559: "ķĸ", - 560: "а", - 563: "àáâãäåāăąĝğġģ", - 566: "κ", - 567: "èéêëēĕėęě", - 570: "¤¿οо₤", - 571: "б", - 572: "Ŧгт", - 573: "ŢŤγ⁗", - 576: "Ρ", - 578: "\uf077", - 579: "‗", - 581: "ÝŶŸ", - 582: "òóôõöøōŏő", - 583: "ß", - 584: "ĹĻĽĿŁŹŻŽ", - 587: "Β\uf041", - 590: "η", - 591: "υ", - 592: "В", - 593: "θ", - 594: "ĥħ‾", - 595: "ñùúûüńņňŋũūŭůűų₦", - 598: "к", - 599: "в", - 600: "φ", - 601: "₠₪", - 602: "З", - 603: "⁙\uf036", - 604: "đ", - 606: "Р₲", - 608: "Ζря‴‷₵", - 609: "ΕЁБЕ", - 612: "Γ", - 613: "₴", - 617: "ŚŜŞŠχий", - 622: "Г", - 624: "⁈⁘", - 625: "ÈÉÊËĒĔĖĘĚ‒", - 630: "ч", - 632: "₣", - 633: "ÇĆĈĊČ", - 634: "ц⁉", - 635: "⁄", - 636: "\uf0fb", - 637: "₱", - 640: "‥", - 642: "ΚЯ", - 645: "ĜĞĠĢ", - 646: "ΤТ⁋⁌⁍", - 649: "Ь", - 650: "₭", - 651: "\uf053", - 654: "ÀÁÂÃÄÅĀĂĄ₮", - 655: "н", - 656: "€", - 657: "σ", - 658: "С", - 660: "α\uf04e", - 661: "ΞЭ", - 662: "ď", - 664: "Ķ", - 665: "лп₥", - 666: "ψ⁁₡₢", - 672: "К", - 674: "\uf043\uf044", - 676: "ÒÓÔÕÖØŌŎŐ", - 683: "ŔŖŘ", - 684: "⁛", - 688: "⁓", - 693: "ʼn\uf058", - 694: "ĤĦ", - 695: "Δм", - 696: "ΘΟО", - 697: "Π", - 700: "Ч\uf032\uf033", - 701: "ÐĎĐ", - 702: "ÙÚÛÜŨŪŬŮŰŲ", - 703: "ΥΧХ", - 704: "ΑА", - 707: "λ", - 709: "ъ", - 710: "д", - 714: "πω", - 716: "ΗΝН", - 719: "ИЙ", - 721: "Ω", - 723: "\uf057", - 728: "ÑŃŅŇŊ", - 734: "ПЦ", - 735: "ΛЛ", - 744: "Д", - 746: "Ψ", - 747: "ΦФ\uf055\uf056\uf06c\uf06e\uf074", - 750: "У", - 755: "Σ", - 760: "ŵ", - 769: "⁜₳", - 770: "‿⁀⁔", - 776: "\uf0e3\uf0e4\uf0e5\uf0e6", - 780: "\uf069", - 781: "ж", - 782: "IJ", - 783: "\uf0f5\uf0f6\uf0f7\uf0f8", - 787: "\uf0fc", - 789: "Ъ", - 793: "\uf042", - 794: "₩\uf059\uf0d7\uf0d8", - 795: "ю", - 799: "⁐", - 806: "ы", - 810: "₨", - 811: "\uf0f1\uf0f2\uf0f4", - 813: "\uf054", - 821: "ΜМ", - 825: "шщ", - 843: "\uf04a\uf04b\uf04c", - 847: "æ", - 849: "\uf04f", - 858: "©®", - 865: "ШЩ", - 873: "\uf0eb\uf0ec\uf0ed\uf0ee", - 874: "Ы", - 875: "―", - 878: "⁇", - 880: "\uf052", - 885: "\uf05a", - 887: "\uf051", - 891: "\uf03b\uf03e\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0", - 893: "\uf029\uf034\uf03c\uf03d\uf049\uf05b\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0fd\uf0fe", - 894: "\uf025", - 896: "\uf05c", - 897: "Ŵ", - 898: "ф", - 909: "⁂", - 911: "\uf03f\uf040", - 929: "Ж\uf066", - 933: "\uf063", - 934: "Œ", - 940: "\uf03a\uf062", - 943: "\uf045\uf046", - 947: "\uf038\uf064", - 948: "Ю", - 950: "œ", - 953: "\uf06d\uf0a6", - 956: "‱", - 957: "₧", - 963: "\uf060", - 967: "Æ", - 970: ( - "¼½¾\u205f₯℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∊∋∌∍∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡" - "∢∣∤∥∦∧∨∩∪∫∬∭∮∯∰∱∲∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝" - "≞≟≠≡≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙" - "⊚⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕" - "⋖⋗⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬" - "⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠" - "┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱" - "▴▵▶▷▸▹►▻▼▽▾▿◀◁◂◃◄◅◈◉◊◌◍◎◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳" - "◴◵◶◷◸◹◺◻◼◽◾◿☀☁☂☃☄☇☈☉☊☋☌☍☎☏☐☑☒☓☔☕☖☗☘☙☚☛☝☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳" - "☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯" - "♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚇⚈⚉⚊⚋⚌⚍⚎⚏⚐⚑⚒⚓⚔⚕⚖⚗⚘⚙⚚⚛⚜⚠⚡⚢⚣⚤⚥⚦⚧⚨⚩⚪⚫⚬⚭⚮" - "⚯⚰⚱⚲✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸✹✺✻✼" - "✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❙❚❛❜❝❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻❼❽❾❿➀" - "➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻➼➽➾\u3000、" - "。〃〄々〆〇〒〓〜〝〞〟〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖" - "㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛" - "㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%" - "&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a" - "bcdefghijklmnopqrstuvwxyz{|}~⦅⦆ᅠ¢£¬ ̄¦¥₩" - ), - 980: "\uf0df\uf0e0", - 987: "\uf075", - 1000: "\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4", - 1012: "☜☞", - 1025: "\uf065", - 1031: "\uf021", - 1036: "\uf0ff", - 1047: "\uf0c7\uf0c8\uf0c9\uf0ca", - 1051: "\uf06a", - 1054: "\uf05f", - 1060: "\uf078\uf079\uf0f3", - 1065: "\uf068", - 1067: "\uf0e7\uf0e8", - 1073: "\uf037", - 1078: "\uf039", - 1083: "\uf028", - 1089: "\uf050", - 1091: "\uf061", - 1096: "\uf030\uf067", - 1111: "\uf04d", - 1133: "\uf02a\uf02b", - 1145: "\uf022", - 1156: "\uf05e", - 1171: "\uf02c\uf02d", - 1216: "\uf026", - 1253: "\uf0d5\uf0d6", - 1271: "\uf06b", - 1300: "\uf023", - }, - "맑은 고딕": { - 330: "·", - 377: "˛", - 416: "˙", - 430: "¸", - 467: "ː", - 473: "‚′", - 490: "¦", - 499: "ł", - 504: "ìíîïı", - 552: "ι", - 553: "ÌÍÎÏΙ", - 590: "´˚", - 592: "¡", - 633: "˘", - 641: "\uf09e\uf0a0", - 645: "∙", - 660: "‹›", - 670: "˝", - 679: "ℓ", - 695: "ŀ", - 706: "ŧ", - 720: "\u00a0", - 729: "⁴", - 732: "¹", - 764: "²³", - 776: "„″", - 778: "ˇ", - 783: "†‡", - 788: "₁₂₃₄", - 790: "\uf0fa", - 801: "г", - 816: "ⁿ", - 821: "ª", - 840: "\u00ad", - 855: "•", - 856: "т", - 864: "¨", - 887: "š", - 895: "‥", - 901: "¯", - 902: "º", - 917: "ε", - 925: "ζ", - 930: "ξ₮", - 932: "з", - 935: "\uf073\uf09f\uf0a7", - 937: "§", - 938: "\uf027", - 942: "¿", - 946: "ž", - 952: "х", - 954: "₰", - 956: "¶", - 968: "çс", - 969: "э", - 983: "ĿŁ", - 985: "ΓГ", - 987: "\uf0f9", - 999: "〔〕", - 1006: "ij", - 1009: "ýÿу", - 1016: "τ", - 1021: "₣", - 1024: "ᅠᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ\uf07f", - 1031: "₭", - 1036: "ĸк", - 1040: "λ", - 1048: "я", - 1052: "ь", - 1053: "«»", - 1059: "ÈÉÊËΕЁЕ", - 1061: "【】", - 1065: "àáâãäåа", - 1066: "Ξ", - 1077: "Σ", - 1084: "γ", - 1087: "\uf07d\uf07e", - 1093: "ŦΤТ", - 1094: "κ", - 1096: "èéêëелё", - 1101: "ν", - 1102: "♩", - 1107: "в₪", - 1112: "Š", - 1116: "∮", - 1119: "∂", - 1122: "∃", - 1125: "\uf047\uf048", - 1128: "¢£¥₤", - 1129: "χ€∫", - 1131: "ßЗ", - 1132: "₡₢", - 1136: "\uf035", - 1140: "д", - 1141: "β", - 1152: "υ", - 1154: "ÝŸΥ", - 1168: "¤", - 1169: "ÞΡР", - 1170: "ð", - 1174: "♭", - 1181: "\uf077", - 1183: "ħч", - 1184: "ñùúûüŋ‼", - 1186: "У", - 1192: "Б", - 1193: "ŽΖ", - 1195: "ΒВ", - 1202: "σ", - 1203: "\uf041", - 1204: "ηЬ", - 1208: "µμнп", - 1209: "ΚК", - 1213: "б", - 1214: "ий", - 1217: "◌", - 1224: "δ", - 1226: "ρ", - 1227: "òóôõöøοо", - 1228: "θ₫", - 1229: "₱", - 1230: "þр", - 1231: "đΧХ", - 1234: "ъ", - 1235: "Я", - 1236: "\uf036", - 1253: "ц", - 1262: "ʼn", - 1280: "♀", - 1288: "α", - 1292: "∑", - 1294: "Э", - 1300: "ÇС", - 1304: "₠\uf0fb", - 1309: "π", - 1313: "Λ", - 1322: "IJ", - 1333: "\uf053", - 1347: "Δ", - 1348: "ÀÁÂÃÄÅΑА", - 1350: "₦", - 1352: "\uf04e", - 1365: "√", - 1366: "∠∴∵", - 1380: "Ч", - 1382: "\uf043\uf044", - 1401: "∥∧∨∼∽≒≡", - 1406: "Л", - 1409: "♪", - 1419: "\uf058", - 1425: "Å∀", - 1428: "ф", - 1434: "\uf032\uf033", - 1435: "¬", - 1436: "≠≤≥", - 1439: "ÙÚÛÜ", - 1446: "Д", - 1460: "∇", - 1463: "φ", - 1464: "♂", - 1465: "м", - 1469: "Ð", - 1476: "Ъы", - 1482: "\uf057", - 1484: "ĦΗН", - 1491: "ΠП", - 1511: "Ф", - 1530: "\uf055\uf056\uf06c\uf06e\uf074", - 1534: "⁈⁉", - 1549: "Ц", - 1553: "ж", - 1564: "₩", - 1567: "ÑŊΝ", - 1568: "ИЙ", - 1570: "ψ", - 1576: "Φ", - 1580: "∏", - 1584: "ÒÓÔÕÖØΘΟО", - 1585: "ΩΩ", - 1591: "\uf0e3\uf0e4\uf0e5\uf0e6", - 1598: "\uf069", - 1601: "\uf0f5\uf0f6\uf0f7\uf0f8", - 1609: "\uf0fc", - 1624: "Ψ\uf042", - 1625: "™", - 1628: "\uf059\uf0d7\uf0d8", - 1629: "Ы", - 1661: "\uf0f1\uf0f2\uf0f4", - 1665: "\uf054", - 1672: "ш", - 1695: "ω", - 1699: "ю", - 1716: "∝", - 1718: "∞", - 1721: "щ", - 1728: "\uf04a\uf04b\uf04c", - 1739: "\uf04f", - 1748: "æ", - 1781: "₨", - 1788: "\uf0eb\uf0ec\uf0ed\uf0ee", - 1797: "Æ", - 1802: "₥\uf052", - 1804: "Ж", - 1814: "\uf05a", - 1817: "\uf051", - 1825: ( - "\uf029\uf034\uf03b\uf03c\uf03d\uf03e\uf049\uf05b\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7" - "\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0\uf0fd\uf0fe" - ), - 1829: "\uf025", - 1836: "\uf05c", - 1862: "\uf03f\uf040", - 1870: "⅞", - 1872: "©®", - 1876: "¼", - 1878: "ΜМ", - 1884: "⁇", - 1903: "\uf066", - 1909: "♬", - 1911: "\uf063", - 1925: "\uf03a\uf062", - 1929: "\uf045\uf046", - 1931: "⅛", - 1937: "\uf064", - 1940: "\uf038", - 1945: "¾", - 1946: "℉℡⅓⅔↔↕↖↗↘↙⇒⇔∈∋∩∪∬≪≫⊂⊃⊆⊇⊙⊥⌒", - 1950: "½œ", - 1952: "\uf06d\uf0a6", - 1954: "Œ", - 1974: "\uf060", - 1982: "☃", - 1986: "Ш", - 2007: "\uf0df\uf0e0", - 2010: "⅜", - 2012: "⅝", - 2022: "\uf075", - 2047: "Щ", - 2048: ( - "―⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎" - "┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊" - "╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♠♡♣♤♥♧♨\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘" - "㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝" - "㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'" - "()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abc" - "defghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4" - ), - 2097: "\uf065", - 2111: "\uf021", - 2119: "\uf0ff", - 2134: "Ю", - 2145: "\uf0c7\uf0c8\uf0c9\uf0ca", - 2149: "\uf06a", - 2160: "\uf05f", - 2171: "\uf078\uf079\uf0f3", - 2178: "\uf068", - 2186: "\uf0e7\uf0e8", - 2197: "\uf037", - 2208: "\uf039", - 2219: "\uf028", - 2231: "\uf050", - 2234: "\uf061", - 2246: "\uf030\uf067", - 2275: "\uf04d", - 2306: "₧", - 2320: "\uf02a\uf02b", - 2342: "\uf022", - 2347: "№", - 2354: "₯", - 2369: "\uf05e", - 2398: "\uf02c\uf02d", - 2492: "\uf026", - 2566: "\uf0d5\uf0d6", - 2603: "\uf06b", - 2662: "\uf023", - }, - "Segoe UI Symbol": { - 561: "\u202f", - 569: "\u0387", - 621: "❟", - 1024: "❕❗", - 1067: "❠", - 1128: "⚳⚴⚵⚷⚸", - 1401: "⚹⚺⚻⚼", - 1671: "⚝", - 1764: "⚾⛳⛵⛶⛽", - 1847: "⚽", - 1987: "⚶", - 2048: ( - "⚞⚟⚿⛀⛁⛂⛃⛄⛅⛆⛇⛈⛉⛊⛋⛌⛍⛎⛏⛐⛑⛒⛓⛔⛕⛖⛗⛘⛙⛚⛛⛜⛝⛞⛟⛠⛡⛢⛣⛤⛥⛦⛧⛨⛩⛪⛫⛬⛭⛮⛯⛰⛱⛲⛴⛷⛸⛹⛺⛻" - "⛼⛾⛿✀✅✊✋✨❌❎❓❔➕➖➗➰➿" - ), - }, - "Wingdings": { - 641: "\uf09e\uf0a0", - 789: "\uf0fa", - 937: "\uf073\uf09f\uf0a7", - 938: "\uf027", - 987: "\uf0f9", - 1086: "\uf07d\uf07e", - 1124: "\uf047\uf048", - 1135: "\uf035", - 1183: "\uf077", - 1203: "\uf041", - 1233: "\uf036", - 1301: "\uf0fb", - 1332: "\uf053", - 1352: "\uf04e", - 1381: "\uf043\uf044", - 1420: "\uf058", - 1431: "\uf032\uf033", - 1480: "\uf057", - 1529: "\uf055\uf056\uf06c\uf06e\uf074", - 1589: "\uf0e3\uf0e4\uf0e5\uf0e6", - 1597: "\uf069", - 1601: "\uf0f5\uf0f6\uf0f7\uf0f8", - 1609: "\uf0fc", - 1624: "\uf042", - 1627: "\uf059\uf0d7\uf0d8", - 1660: "\uf0f1\uf0f2\uf0f4", - 1665: "\uf054", - 1727: "\uf04a\uf04b\uf04c", - 1739: "\uf04f", - 1787: "\uf0eb\uf0ec\uf0ed\uf0ee", - 1803: "\uf052", - 1813: "\uf05a", - 1819: "\uf051", - 1825: ( - "\uf03b\uf03e\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9" - "\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7\uf0b8\uf0b9" - "\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db" - "\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0" - ), - 1826: ( - "\uf029\uf034\uf03c\uf03d\uf049\uf05b\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087" - "\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0fd\uf0fe" - ), - 1830: "\uf025", - 1834: "\uf05c", - 1863: "\uf03f\uf040", - 1902: "\uf066", - 1911: "\uf063", - 1924: "\uf03a", - 1927: "\uf062", - 1929: "\uf045\uf046", - 1937: "\uf064", - 1941: "\uf038", - 1951: "\uf06d\uf0a6", - 1974: "\uf060", - 2006: "\uf0df\uf0e0", - 2020: "\uf075", - 2048: ( - "\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1" - "\uf0d2\uf0d3\uf0d4" - ), - 2099: "\uf065", - 2110: "\uf021", - 2119: "\uf0ff", - 2146: "\uf0c7\uf0c8\uf0c9\uf0ca", - 2150: "\uf06a", - 2159: "\uf05f", - 2171: "\uf078\uf079\uf0f3", - 2181: "\uf068", - 2186: "\uf0e7\uf0e8", - 2196: "\uf037", - 2208: "\uf039", - 2220: "\uf028", - 2230: "\uf050", - 2233: "\uf061", - 2245: "\uf030\uf067", - 2275: "\uf04d", - 2319: "\uf02a\uf02b", - 2344: "\uf022", - 2368: "\uf05e", - 2399: "\uf02c\uf02d", - 2492: "\uf026", - 2566: "\uf0d5\uf0d6", - 2603: "\uf06b", - 2665: "\uf023", - 2751: "\uf031", - 2752: "\uf024", - 2951: "\uf02e", - 2956: "\uf02f", - }, - "Symbol": { - 342: "\uf0a4", - 410: "\uf07c", - 506: "\uf0a2", - 512: "\uf020\uf02c\uf02e\uf0d7", - 561: "\uf0f2", - 569: "\uf02f\uf03a\uf03b", - 674: "\uf069\uf0e1\uf0f1", - 682: "\uf021\uf028\uf029\uf049\uf05b\uf05d", - 786: "\uf0e6\uf0e7\uf0e8\uf0e9\uf0ea\uf0eb\uf0f6\uf0f7\uf0f8\uf0f9\uf0fa\uf0fb", - 819: "\uf0b0", - 842: "\uf067\uf0b2", - 899: "\uf027\uf056\uf065\uf074", - 909: "\uf03f", - 942: "\uf0b7", - 983: "\uf07b\uf07d", - 1010: "\uf078", - 1012: "\uf064\uf07a\uf0b6\uf0e0\uf0ec\uf0ed\uf0ee\uf0ef\uf0fc\uf0fd\uf0fe", - 1024: "\uf023\uf02a\uf030\uf031\uf032\uf033\uf034\uf035\uf036\uf037\uf038\uf039\uf05f\uf060\uf0a6", - 1067: "\uf066\uf06e\uf071", - 1124: ( - "\uf024\uf02b\uf02d\uf03c\uf03d\uf03e\uf040\uf062\uf063\uf06b\uf06c\uf06f\uf070\uf072\uf07e\uf0a3" - "\uf0b1\uf0b3\uf0b4\uf0b8\uf0b9\uf0ba\uf0bb\uf0d6" - ), - 1139: "\uf052", - 1180: "\uf06d\uf075", - 1212: "\uf053", - 1235: "\uf047\uf068\uf06a\uf073\uf0ad\uf0af\uf0bd\uf0d9\uf0da\uf0dd\uf0df", - 1251: "\uf045\uf054\uf05a", - 1253: "\uf044", - 1270: "\uf0a1", - 1292: "\uf04a\uf061", - 1321: "\uf058", - 1348: "\uf05e\uf0bf", - 1366: "\uf042", - 1405: "\uf04c\uf077\uf079\uf0c1\uf0f3\uf0f4\uf0f5", - 1413: "\uf055", - 1460: "\uf022\uf076\uf0a5\uf0b5\uf0c9\uf0ca\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d1\uf0d8\uf0e5", - 1479: "\uf041\uf043\uf048\uf04b\uf04e\uf04f", - 1518: "\uf051", - 1542: "\uf0a7\uf0a8\uf0a9\uf0aa", - 1563: "\uf046", - 1573: "\uf050\uf057\uf0c4\uf0c5\uf0c7\uf0c8\uf0d0", - 1593: "\uf026", - 1610: "\uf0e4", - 1618: "\uf0d2\uf0d3\uf0e2\uf0e3", - 1628: "\uf059\uf0c2", - 1686: "\uf0c0\uf0c6\uf0d5", - 1706: "\uf025", - 1767: "\uf05c", - 1821: "\uf04d", - 1823: "\uf0d4", - 2021: "\uf0ac\uf0ae\uf0c3\uf0dc\uf0de", - 2048: "\uf0bc\uf0be", - 2134: "\uf0ab\uf0db", - }, - "HY헤드라인M": { - 1: "\u302a\u302b", - 165: "·", - 228: "ι", - 256: "¦", - 276: "‚‛", - 285: "Ι", - 298: "ìíîïįĵĺļ", - 321: "\uf09e\uf0a0", - 360: "ĩīĭ", - 374: "г", - 379: "„‟", - 384: "¯ÌÍÎÏĨĪĬĮİţſ", - 393: "ľ", - 395: "\uf0fa", - 406: "τ", - 426: "ŕŗř", - 448: "к", - 452: "ζ", - 457: "ε", - 459: "ξ", - 469: "Ĵт\uf027\uf073\uf09f\uf0a7", - 470: "з", - 481: "źżž", - 495: "\uf0f9", - 496: "ť", - 512: ( - "«»àáâãäåāăąćĉċčśŝşšγκλνсух・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニ" - "ヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚ᅠ\uf07f" - ), - 523: "э", - 532: "ç", - 534: "чь", - 538: "χ", - 544: "в\uf07d\uf07e", - 554: "µèéêëñòóôõöùúûüēĕėęěĝğġģĥķńņňōŏőũūŭůűų", - 555: "Гпя", - 560: "υ", - 563: "\uf047\uf048", - 564: "Γ", - 566: "н", - 568: "\uf035", - 570: "δηθοаеорё", - 572: "ий", - 583: "ρ", - 587: "бц", - 589: "β", - 590: "μ", - 592: "α\uf077", - 597: "ýÿŷК", - 598: "дл", - 602: "\uf041", - 618: "\uf036", - 619: "З", - 626: "ΖΤТ", - 632: "σ", - 633: "Σ", - 640: "ĹĻĽŚŜŞŠъ", - 651: "У", - 652: "\uf0fb", - 664: "φ", - 666: "Ξ", - 667: "\uf053", - 672: "БЛЬ", - 676: "\uf04e", - 682: "ÈÉÊËÝĆĈĊČĒĔĖĘĚŔŖŘŶŸ", - 683: "ΑΒΕΚΡΥΧАВЕРХЧ", - 684: "ΔΛЁ", - 685: "ж", - 690: "Ç", - 691: "\uf043\uf044", - 693: "ď", - 694: "Д", - 705: "м", - 707: "π", - 710: "\uf058", - 717: "\uf032\uf033", - 725: "ÒÓÔÕÖĎĐĜĞĠĢŌŎŐ", - 730: "ψ", - 736: "ИЙПЭы", - 740: "ΗΝΠНСЯ", - 741: "\uf057", - 758: "Ц", - 765: "\uf055\uf056\uf06c\uf06e\uf074", - 766: "Ω", - 768: "ÀÁÂÃÄÅÑÙÚÛÜĀĂĄĤĶŃŅŇŢŤŨŪŬŮŰŲю", - 779: "Ф", - 795: "\uf0e3\uf0e4\uf0e5\uf0e6", - 797: "ΘΟО", - 799: "\uf069", - 800: "ω", - 802: "©\uf0f5\uf0f6\uf0f7\uf0f8", - 806: "\uf0fc", - 810: "ŵ", - 811: "Ъ", - 812: "\uf042", - 814: "\uf059\uf0d7\uf0d8", - 817: "Φ", - 822: "ш", - 831: "\uf0f1\uf0f2\uf0f4", - 833: "\uf054", - 843: "фщ", - 853: "ΜМ", - 856: "Ψ", - 864: "\uf04a\uf04b\uf04c", - 870: "\uf04f", - 894: "\uf0eb\uf0ec\uf0ed\uf0ee", - 901: "\uf052", - 907: "Ы\uf05a", - 911: "\uf051", - 913: ( - "\uf029\uf034\uf03b\uf03c\uf03d\uf03e\uf049\uf05b\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7" - "\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0\uf0fd\uf0fe" - ), - 915: "\uf025", - 918: "\uf05c", - 933: "\uf03f\uf040", - 939: "Ш", - 946: "Ж", - 952: "\uf066", - 956: "\uf063", - 960: "Щ", - 963: "\uf03a\uf062", - 966: "\uf045\uf046", - 970: "\uf038\uf064", - 976: "\uf06d\uf0a6", - 981: "Ŵ", - 987: "\uf060", - 1004: "\uf0df\uf0e0", - 1011: "\uf075", - 1024: ( - "¡¢£¤¥§¨ª¬\u00ad®²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝―‖†‡" - "‥′″‾⁴ⁿ₁₂₃₄₩€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡" - "≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦ" - "ⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀" - "╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◉◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃々〆【】〒〓〔〕〜" - "〞〟㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿" - "㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾" - "㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGH" - "IJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - "\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4" - ), - 1035: "Ю", - 1050: "\uf065", - 1056: "\uf021", - 1061: "\uf0ff", - 1073: "\uf0c7\uf0c8\uf0c9\uf0ca", - 1075: "\uf06a", - 1080: "\uf05f", - 1086: "\uf078\uf079\uf0f3", - 1091: "\uf068", - 1093: "\uf0e7\uf0e8", - 1099: "\uf037", - 1104: "\uf039", - 1110: "\uf028", - 1116: "\uf050", - 1117: "\uf061", - 1123: "\uf030\uf067", - 1138: "\uf04d", - 1160: "\uf02a\uf02b", - 1171: "\uf022", - 1184: "\uf05e", - 1201: "\uf02c\uf02d", - 1246: "\uf026", - 1283: "\uf0d5\uf0d6", - 1302: "\uf06b", - 1333: "\uf023", - }, - "휴먼명조": { - 1: "\u302a\u302b", - 164: "·", - 228: "ι", - 256: "¦", - 276: "‚‛", - 284: "Ι", - 296: "⁚", - 298: "ìíîïįĵĺļ", - 321: "\uf09e\uf0a0", - 360: "ĩīĭ", - 374: "г", - 380: "„‟", - 384: "¯ÌÍÎÏĨĪĬĮİţſ", - 393: "\uf0fa", - 394: "ľ", - 404: "τ", - 426: "ŕŗř", - 448: "к", - 452: "ζ", - 456: "ε", - 458: "ξ", - 467: "\uf073\uf09f\uf0a7", - 470: "Ĵзт", - 471: "\uf027", - 482: "źżž", - 486: "‶", - 495: "\uf0f9", - 496: "ť", - 512: ( - "¢£«»àáâãäåāăąćĉċčśŝşšγκλνсух・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテト" - "ナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚ᅠ\uf07f" - ), - 522: "э", - 532: "ç", - 534: "чь", - 538: "χ", - 544: "в\uf07d\uf07e", - 550: "⁖", - 554: "µèéêëñòóôõöùúûüēĕėęěĝğġģĥķńņňōŏőũūŭůűųГпя", - 560: "υ", - 563: "\uf047\uf048", - 564: "Γ", - 566: "н", - 568: "\uf035", - 570: "δηθοаеорё", - 572: "ий⁕", - 582: "ρ", - 586: "бц", - 590: "βμ", - 592: "α\uf077", - 596: "К", - 598: "ýÿŷдл", - 602: "\uf041", - 615: "\uf036", - 618: "З", - 620: "₲", - 626: "ΖΤТ", - 632: "σ", - 634: "Σ", - 640: "ĹĻĽŚŜŞŠъ", - 650: "У⁉\uf0fb", - 664: "φ", - 666: "Ξ", - 667: "\uf053", - 672: "БЛЬ", - 676: "\uf04e", - 682: "¥ÈÉÊËÝĆĈĊČĒĔĖĘĚŔŖŘŶŸЧ", - 684: "ΑΒΔΕΚΛΡΥΧЁАВЕРХ", - 686: "ж", - 689: "\uf043\uf044", - 690: "Ç", - 694: "ďД", - 704: "м", - 706: "π", - 710: "\uf058", - 717: "\uf032\uf033", - 726: "ÒÓÔÕÖĎĐĜĞĠĢŌŎŐ", - 730: "ψ", - 736: "ИЙПЭы", - 740: "ΗΝΠНСЯ", - 741: "\uf057", - 758: "Ц", - 765: "\uf055\uf056\uf06c\uf06e\uf074", - 766: "Ω", - 768: "ÀÁÂÃÄÅÑÙÚÛÜĀĂĄĤĶŃŅŇŢŤŨŪŬŮŰŲю", - 778: "Ф", - 795: "\uf0e3\uf0e4\uf0e5\uf0e6", - 796: "ΘΟО", - 799: "\uf069\uf0f5\uf0f6\uf0f7\uf0f8", - 800: "ω", - 802: "©®", - 804: "¬\uf0fc", - 810: "ŵЪ", - 812: "\uf042", - 814: "₩\uf059\uf0d7\uf0d8", - 818: "Φ", - 822: "ш", - 830: "₨", - 831: "\uf0f1\uf0f2\uf0f4", - 833: "\uf054", - 842: "фщ", - 854: "ΜМ", - 856: "Ψ", - 864: "\uf04a\uf04b\uf04c", - 870: "\uf04f", - 894: "\uf0eb\uf0ec\uf0ed\uf0ee", - 900: "⁇", - 901: "\uf052", - 905: "\uf05a", - 906: "Ы", - 911: "\uf051", - 913: "\uf03b\uf03e\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0", - 915: "\uf029\uf034\uf03c\uf03d\uf049\uf05b\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0fd\uf0fe", - 916: "\uf025", - 918: "\uf05c", - 933: "\uf03f\uf040", - 938: "Ш", - 946: "Ж", - 952: "\uf066", - 956: "\uf063", - 960: "Щ", - 963: "\uf03a\uf045\uf046\uf062", - 968: "\uf064", - 970: "\uf038", - 976: "\uf06d\uf0a6", - 982: "Ŵ", - 987: "\uf060", - 994: ( - "₯∁∄∅∆∉∊∌∍∎∐−∓∔∕∖∗∘∙∛∜∟∡∢∣∤∦∭∯∰∱∲∳∶∷∸∹∺∻∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≓" - "≔≕≖≗≘≙≚≛≜≝≞≟≢≣≦≧≨≩≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊄⊅⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊚" - "⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗" - "⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿▢▪▫▬▭▮▯▰▱▴▵▸▹►▻▾▿◂◃◄" - "◅◉◊◌◍◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷◸◹◺◻◼◽◾◿☀☁☂☃☄☇☈☉☊" - "☋☌☍☐☑☒☓☔☕☖☗☘☙☚☛☝☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♁♃♄♅♆♇♈♉♊♋♌" - "♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♢♦♫♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚇⚈⚉⚊⚋⚌⚍⚎⚏⚐⚑⚒⚓" - "⚔⚕⚖⚗⚘⚙⚚⚛⚜⚠⚡⚢⚣⚤⚥⚦⚧⚨⚩⚪⚫⚬⚭⚮⚯⚰⚱⚲✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣" - "✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❙❚❛❜❝❞❡❢❣❤❥❦❧❨" - "❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧" - "➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻➼➽➾〄〇〜〝〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾⦅⦆¦" - ), - 1004: "\uf0df\uf0e0", - 1011: "\uf075", - 1024: ( - "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝―†‡‥′″⁴ⁿ₁" - "₂₃₄℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙" - "⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍" - "┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉" - "╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃々〆【】〒〓〔〕〞〟㈀㈁㈂㈃㈄㈅㈆㈇㈈" - "㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍" - "㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉" - "㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRS" - "TUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc" - "\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4" - ), - 1034: "Ю", - 1050: "\uf065", - 1056: "\uf021", - 1061: "\uf0ff", - 1075: "\uf0c7\uf0c8\uf0c9\uf0ca", - 1076: "\uf06a", - 1080: "\uf05f", - 1086: "\uf078\uf079\uf0f3", - 1089: "\uf068", - 1095: "\uf0e7\uf0e8", - 1099: "\uf037", - 1104: "\uf039", - 1110: "\uf028", - 1116: "\uf050\uf061", - 1123: "\uf030\uf067", - 1138: "\uf04d", - 1160: "\uf02a\uf02b", - 1171: "\uf022", - 1184: "\uf05e", - 1201: "\uf02c\uf02d", - 1246: "\uf026", - 1283: "\uf0d5\uf0d6", - 1302: "\uf06b", - 1331: "\uf023", - }, - "한컴산뜻돋움": { - 161: "·", - 254: "ι", - 260: "²³¹", - 264: "\u00a0", - 300: "´", - 313: "\uf09e\uf0a0", - 317: "Ι", - 378: "ª", - 385: "º\uf0fa", - 436: "⁑", - 446: "¡§¸", - 448: "υ", - 458: "\uf027\uf073\uf09f\uf0a7", - 461: "г", - 473: "ν", - 477: "ψ", - 478: "\u00ad", - 483: "\uf0f9", - 486: "ː˛′″⁴ⁿ₁₂₃₄∂、。【】〔〕", - 490: "сэ", - 500: "\uf07f", - 501: "σ", - 507: "б", - 510: "т", - 525: "κ", - 528: "х", - 529: "ε", - 530: "у", - 531: "\uf07d\uf07e", - 532: "з", - 536: "ь", - 539: "к", - 540: "д", - 547: "γа", - 549: "β\uf047\uf048", - 552: "ρ", - 554: "\uf035", - 556: "θ", - 559: "её", - 560: "δ", - 566: "вя", - 568: "У", - 572: "Τ", - 575: "μ", - 577: "о", - 578: "\uf077", - 581: "Υ", - 582: "ο", - 584: "Ζ", - 586: "Рж•", - 587: "Г\uf041", - 588: "ζр", - 593: "λτ", - 595: "αη", - 596: "ЁЕъ", - 597: "ч", - 600: "Λ", - 603: "\uf036", - 606: "З", - 607: "Χпц", - 608: "ξ", - 609: "Γ", - 617: "Хийн", - 618: "л", - 620: "Σ", - 621: "Т", - 622: "Б", - 624: "ΞΦ", - 625: "Ε", - 627: "ВЬ", - 628: "К", - 636: "\uf0fb", - 637: "ω", - 639: "СЭ", - 644: "А", - 645: "Я", - 650: "Ωπ", - 651: "\uf053", - 653: "ΑΔ", - 656: "φ", - 657: "Ψχ", - 660: "Ρ\uf04e", - 664: "ΒΚ", - 666: "Π", - 667: "Ъф", - 669: "¿", - 672: "―", - 674: "\uf043\uf044", - 676: "ΘΟ", - 680: "€", - 688: "ПЧ", - 689: "Д", - 690: "Ц", - 693: "\uf058", - 694: "Η", - 695: "ы", - 697: "Л", - 700: "\uf032\uf033", - 710: "ИЙ", - 718: "Н", - 723: "\uf057", - 728: "Ν", - 730: "м", - 742: "ю", - 747: "\uf055\uf056\uf06c\uf06e\uf074", - 752: "ЖО", - 755: "шщ", - 761: "Ф", - 776: "\uf0e3\uf0e4\uf0e5\uf0e6", - 780: "\uf069", - 783: "\uf0f5\uf0f6\uf0f7\uf0f8", - 787: "\uf0fc", - 793: "\uf042", - 794: "\uf059\uf0d7\uf0d8", - 800: "¨¶øþ", - 807: "Ю", - 811: "\uf0f1\uf0f2\uf0f4", - 813: "\uf054", - 819: "Ы", - 826: "Μ", - 843: "\uf04a\uf04b\uf04c", - 849: "\uf04f", - 873: "\uf0eb\uf0ec\uf0ed\uf0ee", - 880: "\uf052", - 884: "М", - 885: "\uf05a", - 887: "\uf051", - 891: "\uf03b\uf03e\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0", - 892: "¤©®¼½¾ÆÐØÞßæðŒœ†‡™", - 893: "\uf029\uf034\uf03c\uf03d\uf049\uf05b\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0fd\uf0fe", - 894: "\uf025", - 896: "\uf05c", - 904: "ШЩ", - 911: "\uf03f\uf040", - 929: "\uf066", - 932: ( - "đĦħıIJijĸĿŀŁłʼnŊŋŦŧˇ˘˙˚˝‥℉ℓ№℡ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬" - "∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞ" - "ⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸" - "┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000〃〓㈀㈁㈂" - "㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄" - "㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃" - "㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLM" - "NOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - 933: "\uf063", - 940: "\uf03a\uf062", - 943: "\uf045\uf046", - 947: "\uf038\uf064", - 953: "\uf06d\uf0a6", - 963: "\uf060", - 970: "◉◯☐☑❍", - 980: "\uf0df\uf0e0", - 987: "\uf075", - 1000: "\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4", - 1025: "\uf065", - 1031: "\uf021", - 1036: "\uf0ff", - 1047: "\uf0c7\uf0c8\uf0c9\uf0ca", - 1051: "\uf06a", - 1054: "\uf05f", - 1060: "\uf078\uf079\uf0f3", - 1065: "\uf068", - 1067: "\uf0e7\uf0e8", - 1073: "\uf037", - 1078: "\uf039", - 1083: "\uf028", - 1089: "\uf050", - 1091: "\uf061", - 1096: "\uf030\uf067", - 1111: "\uf04d", - 1133: "\uf02a\uf02b", - 1145: "\uf022", - 1156: "\uf05e", - 1171: "\uf02c\uf02d", - 1216: "\uf026", - 1253: "\uf0d5\uf0d6", - 1271: "\uf06b", - 1300: "\uf023", - }, - "휴먼고딕": { - 1: "\u302a\u302b", - 164: "\u0387", - 228: "ι", - 256: "¦", - 276: "‚‛", - 284: "Ι", - 296: "․‧⁚", - 298: "ìíîïįĵĺļ⁏⁝⁞", - 344: "‖‵", - 360: "ĩīĭ", - 374: "г", - 378: "‣", - 380: "„‟", - 384: "¯ÌÍÎÏĨĪĬĮİţſ", - 394: "ľ", - 404: "τ", - 406: "‹›", - 408: "•", - 426: "ŕŗř", - 448: "к", - 452: "ζ", - 456: "ε", - 458: "ξ‼", - 466: "⁃", - 470: "Ĵзт", - 482: "źżž", - 484: "⁅⁆", - 486: "‶", - 492: "‽", - 496: ( - "ť〿。「」、ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑" - "→↓■○" - ), - 498: "⁎⁑", - 512: ( - "¢£«»àáâãäåāăąćĉċčśŝşšγκλνсух〖〗〘〙〚〛・ヲァィゥェォャュョッーアイウエオカキクケコサシスセ" - "ソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚ᅠ" - ), - 522: "э", - 524: "₫", - 530: "₰", - 532: "ç", - 534: "чь", - 538: "χ‸", - 540: "‐‑", - 544: "в⁊", - 550: "⁖", - 554: "µèéêëñòóôõöùúûüēĕėęěĝğġģĥķńņňōŏőũūŭůűųГпя", - 560: "υ", - 564: "Γ", - 566: "н", - 568: "⁒", - 570: "δηθοаеорё", - 572: "ий⁕", - 582: "ρ", - 584: "₤", - 586: "бц⁗", - 590: "βμ", - 592: "α‗", - 596: "К", - 598: "ýÿŷдл", - 608: "‾", - 610: "₦", - 616: "₠₪", - 618: "З⁙", - 620: "₲", - 622: "‴‷₵", - 626: "ΖΤТ", - 628: "₴", - 632: "σ", - 634: "Σ", - 638: "⁈⁘", - 640: "ĹĻĽŚŜŞŠŹŻŽъ‒", - 648: "₣", - 650: "У⁄⁉", - 652: "₱", - 662: "⁋⁌⁍", - 664: "φ", - 666: "Ξ₭", - 670: "₮", - 672: "БЛЬ€", - 680: "₥", - 682: "¥ÈÉÊËÝĆĈĊČĒĔĖĘĚŔŖŘŶŸЧ⁁₡₢", - 684: "ΑΒΔΕΚΛΡΥΧЁАВЕРХ", - 686: "ж", - 690: "Ç", - 694: "ďД", - 700: "⁛", - 704: "м⁓", - 706: "π", - 726: "ÒÓÔÕÖĎĐĜĞĠĢŌŎŐ", - 730: "ψ", - 736: "ИЙПЭы", - 740: "ΗΝΠНСЯ", - 758: "Ц", - 766: "Ω", - 768: "ÀÁÂÃÄÅÑÙÚÛÜĀĂĄĤĶŃŅŇŢŤŨŪŬŮŰŲю", - 778: "Ф", - 788: "‿⁀⁔⁜₳", - 796: "ΘΟО", - 800: "ω", - 802: "©®", - 804: "¬", - 810: "ŵЪ", - 814: "₩", - 818: "Φ⁐", - 822: "ш", - 830: "₨", - 842: "фщ", - 854: "ΜМ", - 856: "Ψ", - 900: "⁇", - 906: "Ы", - 930: "⁂", - 938: "Ш", - 946: "Ж", - 960: "Щ", - 978: "‱", - 980: "₧", - 982: "Ŵ", - 994: ( - "₯∁∄∅∆∉∊∌∍∎∐−∓∔∕∖∗∘∙∛∜∟∡∢∣∤∦∭∯∰∱∲∳∶∷∸∹∺∻∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≓" - "≔≕≖≗≘≙≚≛≜≝≞≟≢≣≦≧≨≩≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊄⊅⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊚" - "⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗" - "⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿▢▪▫▬▭▮▯▰▱▴▵▸▹►▻▾▿◂◃◄" - "◅◉◊◌◍◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷◸◹◺◻◼◽◾◿☀☁☂☃☄☇☈☉☊" - "☋☌☍☐☑☒☓☔☕☖☗☘☙☚☛☝☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♁♃♄♅♆♇♈♉♊♋♌" - "♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♢♦♫♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚇⚈⚉⚊⚋⚌⚍⚎⚏⚐⚑⚒⚓" - "⚔⚕⚖⚗⚘⚙⚚⚛⚜⚠⚡⚢⚣⚤⚥⚦⚧⚨⚩⚪⚫⚬⚭⚮⚯⚰⚱⚲✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣" - "✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❙❚❛❜❝❞❡❢❣❤❥❦❧❨" - "❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧" - "➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻➼➽➾〄〇〜〝〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾⦅⦆¦" - ), - 1024: ( - "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝―†‡‥′″⁴ⁿ₁" - "₂₃₄℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙" - "⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍" - "┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉" - "╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍" - "㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒" - "㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖" - "㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" - "YZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - 1034: "Ю", - }, - "한컴돋움": { - 218: "⁏", - 232: "⁚⁝⁞", - 235: "ìíïįı", - 236: "ĺļ", - 241: "ī", - 256: "¦îĵ", - 265: "ÌÍÏĪĬĮİ", - 268: "ł", - 270: "ĭ", - 297: "Î", - 298: "Ĩĩ‚‛", - 311: "❟", - 320: "ľŀ", - 321: "ţŧ", - 328: "ŕŗř", - 329: "²³", - 341: "´¸", - 352: "ſ", - 384: "¹º", - 413: "ª", - 425: "¡", - 427: "ť⁎", - 469: "„‟", - 475: "⁖", - 488: "⚬", - 492: "ýŷźżž", - 496: "Ĵ", - 512: "\u00a0¨«\u00ad¯»¼½¾ÿij\u202f・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚ᅠ", - 522: "ķĸ", - 527: "śŝşš", - 533: "⁙", - 546: "⚘", - 553: "ĹĻĽĿ", - 564: "⚨⚲", - 573: "¢çèéêëēĕėęĥħ", - 574: "£¤§¶", - 582: "ñùúûüńņňʼnŋũūŭůűų", - 587: "Ł", - 590: "⚚", - 597: "µ¿àáâãäåāăąćĉċčěŢŤŦ", - 613: "ğġģ", - 614: "ÝðòóôõöøþōŏőŶŸ", - 619: "ŹŻŽ", - 640: "¥ßđĝ", - 644: "ÈÉÊËĒĔĖĘĚ", - 655: "ŚŜŞŠ", - 657: "⁘⁛", - 668: "⁗", - 671: "Ķ", - 675: "⚭", - 681: "ÀÁÂÃÄÅÞĀĂĄ", - 684: "ŔŖŘ", - 697: "⁕", - 701: "⚹⚺⚻⚼", - 711: "⚥⚦", - 712: "ÑŃŅŇŊ", - 720: "¬", - 737: "ĆĈĊČ⚐⚑", - 741: "ĤĦ", - 742: "ÐÙÚÛÜďŨŪŬŮŰŲŵ", - 768: "ÇÒÓÔÕÖØĎĜĞĠĢIJŌŎŐ", - 769: "Đ", - 802: "©®", - 815: "⁔", - 819: "⚢", - 822: "⁓", - 830: "æ", - 853: "⁇", - 864: "⚩", - 882: "◸◹◺◿", - 895: "⚣⚤", - 896: "œ", - 915: "Ŵ", - 920: "⚊⚋⚌⚍⚎⚏", - 954: "⚮", - 957: "Œ", - 958: "Æ", - 994: "⚶", - 1024: "⁜々〆〒〓〞〟", - 1116: "⚯", - 1406: "◻◼◽◾☔☕☘♾♿⚒⚓⚔⚕⚖⚗⚙⚛⚜⚠⚡⚧⚪⚫⚰⚱⚽⚾⛄⛅⛈⛎⛏⛑⛓⛔⛩⛪⛰⛱⛲⛳⛴⛵⛷⛸⛹⛺⛽✅✊✋✨❌❎❓❔❕❗➕➖➗➰➿", - }, - "HY울릉도M": { - 165: "\u0387", - 512: ( - "\u00a0¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöù" - "úûüýÿ" - ), - 1024: ( - "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘΙ" - "ΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТУ" - "ФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄℉ℓ№" - "℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟" - "⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓" - "└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥" - "▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓" - "㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘" - "㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"" - "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^" - "_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - }, - "HY울릉도B": { - 512: ( - "\u00a0¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöù" - "úûüýÿ" - ), - 1024: ( - "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘΙ" - "ΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТУ" - "ФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄℉ℓ№" - "℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟" - "⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓" - "└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥" - "▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖" - "㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛" - "㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%" - "&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a" - "bcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - }, - "HY중고딕": { - 165: "·", - 321: "\uf09e\uf0a0", - 395: "\uf0fa", - 469: "\uf027\uf073\uf09f\uf0a7", - 495: "\uf0f9", - 512: ( - "\u00a0¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöù" - "úûüýÿ\uf07f" - ), - 544: "\uf07d\uf07e", - 563: "\uf047\uf048", - 568: "\uf035", - 592: "\uf077", - 602: "\uf041", - 618: "\uf036", - 652: "\uf0fb", - 667: "\uf053", - 676: "\uf04e", - 691: "\uf043\uf044", - 710: "\uf058", - 717: "\uf032\uf033", - 741: "\uf057", - 765: "\uf055\uf056\uf06c\uf06e\uf074", - 795: "\uf0e3\uf0e4\uf0e5\uf0e6", - 799: "\uf069", - 802: "\uf0f5\uf0f6\uf0f7\uf0f8", - 806: "\uf0fc", - 812: "\uf042", - 814: "\uf059\uf0d7\uf0d8", - 831: "\uf0f1\uf0f2\uf0f4", - 833: "\uf054", - 864: "\uf04a\uf04b\uf04c", - 870: "\uf04f", - 894: "\uf0eb\uf0ec\uf0ed\uf0ee", - 901: "\uf052", - 907: "\uf05a", - 911: "\uf051", - 913: ( - "\uf029\uf034\uf03b\uf03c\uf03d\uf03e\uf049\uf05b\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7" - "\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0\uf0fd\uf0fe" - ), - 915: "\uf025", - 918: "\uf05c", - 933: "\uf03f\uf040", - 952: "\uf066", - 956: "\uf063", - 963: "\uf03a\uf062", - 966: "\uf045\uf046", - 970: "\uf038\uf064", - 976: "\uf06d\uf0a6", - 987: "\uf060", - 1004: "\uf0df\uf0e0", - 1011: "\uf075", - 1024: ( - "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘΙ" - "ΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТУ" - "ФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄℉ℓ№" - "℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟" - "⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓" - "└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥" - "▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓" - "㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘" - "㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"" - "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^" - "_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4" - ), - 1050: "\uf065", - 1056: "\uf021", - 1061: "\uf0ff", - 1073: "\uf0c7\uf0c8\uf0c9\uf0ca", - 1075: "\uf06a", - 1080: "\uf05f", - 1086: "\uf078\uf079\uf0f3", - 1091: "\uf068", - 1093: "\uf0e7\uf0e8", - 1099: "\uf037", - 1104: "\uf039", - 1110: "\uf028", - 1116: "\uf050", - 1117: "\uf061", - 1123: "\uf030\uf067", - 1138: "\uf04d", - 1160: "\uf02a\uf02b", - 1171: "\uf022", - 1184: "\uf05e", - 1201: "\uf02c\uf02d", - 1246: "\uf026", - 1283: "\uf0d5\uf0d6", - 1302: "\uf06b", - 1333: "\uf023", - }, - "HY견고딕": { - 165: "\u0387", - 512: ( - "\u00a0¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöù" - "úûüýÿ" - ), - 1024: ( - "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘΙ" - "ΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТУ" - "ФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄℉ℓ№" - "℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟" - "⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓" - "└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥" - "▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓" - "㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘" - "㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"" - "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^" - "_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - }, - "HY신명조": { - 165: "\u0387", - 512: ( - "\u00a0¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöù" - "úûüýÿ" - ), - 1024: ( - "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘΙ" - "ΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТУ" - "ФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄℉ℓ№" - "℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟" - "⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓" - "└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥" - "▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓" - "㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘" - "㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"" - "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^" - "_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - }, - "HY태백B": { - 228: 'ι', - 276: '‚‛', - 285: 'Ι', - 294: 'Ϊ', - 296: '․‧', - 298: 'įĵĺļ', - 328: '⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉', - 343: '‖‵', - 346: 'ί', - 360: 'ĩīĭ', - 378: '‣', - 379: '„‟', - 384: 'ĨĪĬĮİţſ', - 393: 'ľ', - 405: 'τ', - 406: '‹›', - 409: '•', - 426: 'ŕŗř', - 452: 'ζ', - 457: 'ε', - 458: '‼', - 459: 'ξ', - 469: 'Ĵ', - 481: 'źżž', - 496: 'ť', - 512: '\xa0¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöùúûüýÿāăąćĉċčśŝşšγκλν', - 513: 'ς', - 538: 'χ', - 541: '‐‑', - 554: 'ēĕėęěĝğġģĥķńņňōŏőũūŭůűų', - 560: 'υ', - 564: 'Γ', - 570: 'δηθο', - 577: 'έ', - 583: 'ρ', - 588: 'fi', - 589: 'β', - 590: 'μ', - 592: 'α', - 593: '‗', - 597: 'ŷ', - 603: 'fl', - 604: 'ή', - 605: 'ΰ', - 608: '‾', - 623: '‴', - 626: 'ΖΤ', - 632: 'σ', - 633: 'Σ', - 640: 'ĹĻĽŚŜŞŠŹŻŽ‒', - 650: '⁄', - 664: 'φ', - 666: 'Ξ', - 672: '€', - 682: 'ĆĈĊČĒĔĖĘĚŔŖŘŶŸ', - 683: 'ΑΒΕΚΡΥΧ', - 684: 'ΔΛά', - 693: 'ď', - 707: 'π', - 720: 'Ϋ', - 725: 'ĎĐĜĞĠĢŌŎŐ', - 730: 'ψ', - 740: 'ΗΝΠ', - 766: 'Ω', - 768: 'ĀĂĄĤĶŃŅŇŢŤŨŪŬŮŰŲ', - 797: 'ΘΟ', - 800: 'ω', - 810: 'ŵ', - 813: '₩', - 817: 'Φ', - 853: 'Μ', - 856: 'Ψ', - 979: '‱', - 981: 'Ŵ', - 993: '℮−∕∙≈◊', - 1024: '¡¤§¨ª\xad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩', - }, - "HY그래픽": { - 512: ( - "\u00a0¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöù" - "úûüýÿ" - ), - 1024: ( - "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘΙ" - "ΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТУ" - "ФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄℉ℓ№" - "℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟" - "⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓" - "└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥" - "▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓" - "㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘" - "㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"" - "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^" - "_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - }, - "한컴바탕": { - 165: "\u0387", - 166: "˙", - 178: "․‧", - 224: "ː˚", - 229: "⁃", - 256: "¦", - 267: "‐", - 276: "˛‚‛′‵", - 298: "ìíîïįıĵĺļł", - 328: "⁅⁆", - 332: "‹›", - 336: "˘", - 341: "´¸‖", - 360: "ĩīĭ", - 363: "˝", - 365: "⁁", - 368: "²³", - 369: "‑", - 377: "ŀ", - 379: "„‟", - 384: "\u00ad¯¹ÌÍÎÏĨĪĬĮİţŧſΙ", - 393: "ľ", - 404: "‸", - 408: "ι", - 425: "ˇ", - 426: "¡ŕŗř", - 430: "з", - 441: "‒", - 445: "а", - 447: "″", - 451: "г", - 452: "‼", - 461: "ε", - 465: "ь", - 467: "⁊", - 469: "Ĵ", - 471: "сэ⁴ⁿ₁₂₃₄", - 474: "•", - 477: "‣", - 480: "ªº", - 481: "źżž", - 485: "в‶", - 492: "её†‡‽⁑⁒", - 493: "я", - 496: "ť", - 502: "ζξт", - 512: ( - "\u00a0¢£¤§¨«»¿àáâãäåāăąćĉċčśŝşš\u202f⁇⁎⁏⁓⁔⁕⁖⁗⁘⁙⁚⁛⁜⁝⁞\u205f∘∙\u3000⦅⦆。「」、・ヲァィゥェォャ" - "ュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚ᅠᄀᄁᆪᄂᆬᆭᄃᄄ" - "ᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑→↓■○" - ), - 516: "ко", - 521: "χ", - 523: "б", - 527: "Злч", - 532: "ç", - 534: "ρъ", - 538: "ijτ", - 542: "р", - 543: "υ", - 547: "у", - 549: "д", - 550: "п", - 553: "αх", - 554: "µèéêëðñòóôõöøùúûüþēĕėęěĝğġģĥħķĸńņňŋōŏőũūŭůűųδκνοσ", - 561: "‗", - 562: "đ", - 565: "‴‷", - 573: "ийнц", - 574: "γ", - 575: "¼½¾", - 577: "Р", - 579: "π", - 580: "‥", - 585: "μ", - 594: "ηЬ", - 597: "ýÿŷ", - 600: "φ", - 604: "БГ", - 616: "Ξ", - 625: "Γ", - 628: "ЁЕ", - 636: "Т", - 638: "θ", - 640: "¶ßĹĻĽŁŚŜŞŠŹŻŽΖΡλω⁋⁌⁍", - 641: "ф‾", - 655: "м", - 670: "βВ", - 674: "Δ", - 677: "СЭ", - 682: "¥ÈÉÊËÝÞĆĈĊČĒĔĖĘĚŔŖŘŶŸΒΕΥΧ", - 683: "ʼn", - 690: "Ç€", - 693: "ďы", - 707: "ψКЧЯ", - 708: "Л", - 715: "Ъ", - 717: "Π", - 725: "ÐÒÓÔÕÖØĎĐĜĞĠĢŌŎŐΘΟ", - 734: "ж", - 736: "Д", - 738: "У", - 742: "Ω", - 743: "О", - 752: "⁄", - 753: "ĿΦ", - 757: "Х", - 759: "IJΨ", - 768: "ÀÁÂÃÄÅÑÙÚÛÜĀĂĄĤĦĶŃŅŇŊŢŤŦŨŪŬŮŰŲΑΗΚΛΝΤАИЙНПЦю", - 788: "Ф", - 790: "шщ", - 800: "Σ", - 802: "©®", - 804: "¬", - 810: "ŵ", - 817: "⁈⁉", - 823: "‿⁀⁐", - 849: "œ", - 865: "æ", - 903: "Ы", - 918: "М", - 938: "Μ", - 940: "Œ", - 962: "Ж", - 981: "Ŵ", - 1024: ( - "ÆШЩЮ―‱⁂℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∊∋∌∍∎∏∐∑−∓∔∕∖∗√∛∜∝∞∟∠∡" - "∢∣∤∥∦∧∨∩∪∫∬∭∮∯∰∱∲∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝" - "≞≟≠≡≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙" - "⊚⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕" - "⋖⋗⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬" - "⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠" - "┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱" - "▴▵▶▷▸▹►▻▼▽▾▿◀◁◂◃◄◅◈◉◊◌◍◎◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳" - "◴◵◶◷◸◹◺◻◼◽◾◿☀☁☂☃☄☇☈☉☊☋☌☍☎☏☐☑☒☓☔☕☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱" - "☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭" - "♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚇⚈⚉⚊⚋⚌⚍⚎⚏⚐⚑⚒⚓⚔⚕⚖⚗⚘⚙⚚⚛⚜⚝⚞⚟⚠⚡⚢⚣⚤⚥⚦⚧⚨⚩" - "⚪⚫⚬⚭⚮⚯⚰⚱⚲⚳⚴⚵⚶⚷⚸⚹⚺⚻⚼⚽⚾⚿⛀⛁⛂⛃⛄⛅⛆⛇⛈⛉⛊⛋⛌⛍⛎⛏⛐⛑⛒⛓⛔⛕⛖⛗⛘⛙⛚⛛⛜⛝⛞⛟⛠⛡⛢⛣⛤⛥" - "⛦⛧⛨⛩⛪⛫⛬⛭⛮⛯⛰⛱⛲⛳⛴⛵⛶⛷⛸⛹⛺⛻⛼⛽⛾⛿✀✁✂✃✄✅✆✇✈✉✊✋✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡" - "✢✣✤✥✦✧✨✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝" - "❞❟❠❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➕➖➗➘➙" - "➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➰➱➲➳➴➵➶➷➸➹➺➻➼➽➾➿、。〃〄々〆〇【】〒〓〔〕〖〗〘〙〚〛〜〝〞" - "〟〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾〿㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣" - "㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥" - "㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./" - "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijk" - "lmnopqrstuvwxyz{|}~¢£¬ ̄¦¥₩" - ), - }, - "한컴 윤고딕 230": { - 275: "ː", - 280: "′", - 308: "ÌÍÎÏìíîïĬĭĮįİıĺļ", - 318: "ĵ", - 326: "ſ", - 330: "〔〕", - 340: "´¸˘˙˚˛", - 350: "\u00a0", - 354: "ţŧ", - 360: "²³¹⁴ⁿ₁₂₃₄", - 374: "ª", - 390: "()[]", - 400: "¦", - 402: "Ĩĩ", - 411: "Īī", - 420: "ˇ˝", - 429: "ŕŗř", - 438: "º", - 442: "ľ", - 450: "【】{}", - 460: "∂", - 470: "″", - 488: "ł", - 493: "ť", - 500: "¨¯", - 515: "\u00ad", - 543: "Ĵ", - 546: "ij", - 560: "ŀ", - 566: "źżž", - 575: "śŝşš", - 577: "¶", - 600: "ýÿŷ", - 611: "£ĹĻĽĿ", - 616: "¢çćĉċč", - 621: "ķĸ", - 628: "ð", - 629: "¤èéêëòóôõöøēĕėęěōŏő", - 630: "‥", - 634: "ŹŻŽ", - 640: "µùúûüũūŭůűų", - 645: "ŢŤŦ", - 649: "ñńņňŋ", - 650: "ĥħ", - 664: "ÈÉÊËĒĔĖĘĚŚŜŞŠ", - 675: "þĝğġģ", - 678: "àáâãäåāăąđ", - 680: "¥ÝÞŶŸ", - 682: "Ł", - 685: "¬", - 693: "ŔŖŘ", - 700: "αβγδεζηθικλμνξοπρστυφχψωабвгдежзийклмнопрстуфхцчшщъыьэюяё", - 702: "ß", - 714: "Ķ", - 733: "ÀÁÂÃÄÅÙÚÛÜĀĂĄĎĐŨŪŬŮŰŲ", - 742: "«»", - 743: "ĤĦ", - 744: "ʼn", - 752: "ÑŃŅŇŊ", - 773: "ÇĆĈĊČ", - 782: "Ð", - 788: "ď", - 791: "IJ", - 792: "ĜĞĠĢ", - 794: "ÒÓÔÕÖØŌŎŐ", - 799: "ŵ", - 900: ( - "¡§®¼½¾¿ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫ" - "ЬЭЮЯ―†‡€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂" - "⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━" - "│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅" - "╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍" - "㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒" - "㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖" - "㏘㏛㏜㏝!"#$%&'*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "\^_`abcdefghijklmnopqrstuvwxyz|~¢£¬ ̄¥₩" - ), - 906: "©", - 913: "Ŵ", - 979: "Œ", - 1022: "œ", - 1027: "Ææ", - }, - "한컴 윤고딕 240": { - 248: "ː", - 252: "′", - 297: "〔〕", - 308: "ÌÍÎÏìíîïĬĭĮįİıĺļ", - 318: "ĵ", - 326: "ſ", - 340: "´¸˘˙˚˛", - 350: "\u00a0", - 354: "ţŧ", - 360: "²³¹⁴ⁿ₁₂₃₄", - 374: "ª", - 390: "()[]", - 400: "¦", - 402: "Ĩĩ", - 411: "Īī", - 414: "∂", - 420: "ˇ˝", - 423: "″", - 429: "ŕŗř", - 438: "º", - 442: "ľ", - 450: "【】{}", - 480: "/", - 488: "ł", - 493: "ť", - 500: "¯", - 515: "\u00ad", - 546: "ij", - 560: "ŀ", - 564: "Ĵ", - 566: "źżž", - 575: "§śŝşš", - 577: "¶", - 600: "ýÿŷ", - 611: "£ĹĻĽĿ", - 616: "¢çćĉċč", - 621: "ķĸ", - 628: "ð", - 629: "¤èéêëòóôõöøēĕėęěōŏő", - 630: "‥", - 634: "ŹŻŽ", - 640: "µùúûüũūŭůűų", - 645: "ŢŤŦ", - 649: "ñńņňŋ", - 650: "ĥħ", - 664: "ÈÉÊËĒĔĖĘĚŚŜŞŠ", - 675: "þĝğġģ", - 678: "àáâãäåāăąđ", - 680: "¥ÝÞŶŸ", - 682: "Ł", - 685: "¬", - 693: "ŔŖŘ", - 700: "αβγδεζηθικλμνξοπρστυφχψω", - 702: "ß", - 714: "Ķ", - 733: "ÀÁÂÃÄÅÙÚÛÜĀĂĄĎĐŨŪŬŮŰŲ", - 742: "«»", - 743: "ĤĦ", - 744: "ʼn", - 752: "ÑŃŅŇŊ", - 773: "ÇĆĈĊČ", - 782: "Ð", - 788: "ď", - 791: "IJ", - 792: "ĜĞĠĢ", - 794: "ÒÓÔÕÖØŌŎŐ", - 799: "ŵ", - 800: "абвгдежзийклмнопрстуфхцчшщъыьэюяё", - 900: ( - "¡¨®¼½¾¿ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫ" - "ЬЭЮЯ―†‡€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂" - "⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━" - "│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅" - "╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍" - "㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒" - "㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖" - "㏘㏛㏜㏝!"#$%&'*+,-.0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\" - "^_`abcdefghijklmnopqrstuvwxyz|~¢£¬ ̄¥₩" - ), - 906: "©", - 913: "Ŵ", - 979: "Œ", - 1022: "œ", - 1027: "Ææ", - }, - "한컴 윤고딕 250": { - 222: "ι", - 248: "ː", - 252: "′", - 270: "‚‛", - 278: "Ι", - 289: "․", - 297: "〔〕", - 308: "ÌÍÎÏìíîïĬĭĮįİıĺļ", - 318: "ĵ", - 326: "ſ", - 335: "‖‵", - 340: "´¸˘˙˚˛", - 350: "\u00a0", - 354: "ţŧ", - 360: "²³¹⁴ⁿ₁₂₃₄", - 370: "„‟", - 374: "ª", - 390: "()[]", - 395: "τ", - 396: "‹›", - 399: "•", - 400: "¦", - 402: "Ĩĩ", - 411: "Īī", - 414: "∂", - 420: "ˇ˝", - 423: "″", - 429: "ŕŗř", - 438: "º", - 441: "ζ", - 442: "ľ", - 446: "ε", - 447: "‼", - 448: "ξ", - 450: "【】{}", - 474: "‶", - 486: "⁎⁑", - 488: "ł", - 493: "ť", - 500: "¨¯γκλν〖〗〘〙", - 515: "\u00ad", - 525: "χ", - 528: "‐", - 546: "ij", - 547: "υ", - 551: "Γ", - 556: "ηθο", - 557: "δ", - 560: "ŀ", - 564: "Ĵ", - 566: "źżž", - 569: "ρ", - 575: "§śŝşšβ", - 576: "μ", - 577: "¶", - 578: "α", - 600: "ýÿŷ", - 608: "‴", - 611: "£ĹĻĽĿΖΤ", - 616: "¢çćĉċč", - 617: "σ", - 618: "Σ", - 621: "ķĸ", - 628: "ð", - 629: "¤èéêëòóôõöøēĕėęěōŏő", - 630: "‥", - 634: "ŹŻŽ⁉", - 640: "µùúûüũūŭůűų", - 645: "ŢŤŦ", - 646: "⁌⁍", - 648: "φ", - 649: "ñńņňŋ", - 650: "ĥħΞ", - 664: "ÈÉÊËĒĔĖĘĚŚŜŞŠ", - 667: "ΑΒΕΚΡΥΧ", - 668: "ΔΛ", - 675: "þĝğġģ", - 678: "àáâãäåāăąđ", - 680: "¥ÝÞŶŸ", - 682: "Ł", - 685: "¬", - 690: "π", - 693: "ŔŖŘ", - 702: "ß", - 713: "ψ", - 714: "Ķ", - 722: "ΗΝΠ", - 733: "ÀÁÂÃÄÅÙÚÛÜĀĂĄĎĐŨŪŬŮŰŲ", - 742: "«»", - 743: "ĤĦ", - 744: "ʼn", - 748: "Ω", - 752: "ÑŃŅŇŊ", - 770: "⁔", - 773: "ÇĆĈĊČ", - 778: "ΘΟ", - 781: "ω", - 782: "Ð", - 788: "ď", - 791: "IJ", - 792: "ĜĞĠĢ", - 794: "ÒÓÔÕÖØŌŎŐ", - 798: "Φ", - 799: "ŵ", - 833: "Μ", - 835: "Ψ", - 878: "⁇", - 900: ( - "¡®¼½¾¿―†‡€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕ" - "ⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽" - "◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋" - "㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'*+,-./0123456789:;<=>?" - "@ABCDEFGHIJKLMNOPQRSTUVWXYZ\^_`abcdefghijklmnopqrstuvwxyz|~¢£¬ ̄¥₩" - ), - 906: "©", - 909: "⁂", - 913: "Ŵ", - 970: ( - "∆∉∌∓∟∢∦∶∷≃≅≈≐≑≓≚≢≦≧≮≯≰≱≲≳≶≷≹≺≻⊀⊁⊄⊅⊊⊋⊕⊖⊗⊣⊤⊻⊼⋎⋏⋚⋛⋮⋯▭▱▵▹▿◃◉◊◌◍◦◯◻◼☐☕☝☟☯♦♯✖✚✠✣✱✽✿❀❁❇❍❖❶❷❸❹❺❻❼❽❾❿➊➋➌➍➎➏➐➑" - "➒➓➔➛➜➞➡➤➲➵〠〶¦" - ), - 979: "Œ", - 1000: "〒〞〟", - 1022: "œ", - 1027: "Ææ", - }, - "한컴 윤고딕 720": { - 134: "˙", - 203: "˛", - 207: "ː∶", - 226: "˚", - 232: "ı", - 234: "ĺļ", - 236: "ìíį", - 240: "‚․", - 241: "Ι", - 242: "ι", - 248: "ÌÍĮİ", - 288: "´′", - 290: "\u00a0", - 296: "‛", - 327: "ŧ", - 333: "ŕŗř", - 338: "˘", - 340: "ţ", - 341: "ſ", - 350: "、。", - 355: "ĵ", - 360: "˝", - 373: "¸ˇ", - 380: "¦‵‶⁑", - 384: "ł", - 399: "§", - 400: "²³¹⁴ⁿ₁₂₃₄", - 410: "„", - 432: "śŝşš", - 436: "τ", - 440: "″", - 448: "‹›", - 450: "ÎÏîïĨĩĬĭľŀť‟", - 452: "з", - 461: "ν", - 470: "〞〟", - 471: "ª", - 480: "º", - 487: "т", - 490: "⁌⁍", - 491: "я", - 495: "ij", - 500: "źżž〘〙", - 502: "çćĉċč", - 505: "б【】〔〕〖〗", - 508: "с", - 511: "Ĵķ", - 513: "κ", - 515: "ĸк", - 520: "ь", - 522: "ε", - 524: "ă", - 525: "ýÿŷ", - 526: "àáâãäåāąа", - 533: "υгℓ", - 534: "х", - 535: "γ", - 536: "ρу", - 537: "β", - 539: "Ŀ", - 540: "ĹĻĽχ", - 541: "èéêëēĕėęěеё", - 542: "У", - 544: "¨θ", - 547: "Τ", - 548: "δ", - 549: "Ŧ", - 550: "ĪīŚŜŞŠ", - 552: "р", - 555: "Т", - 559: "ŢŤ", - 560: "э", - 563: "μ", - 567: "ŶŸΥΧ", - 569: "Ζв", - 571: "ΓΞΣ", - 573: "Ε", - 574: "о", - 575: "ðч", - 577: "ζХ", - 579: "Ý", - 581: "ŹŻŽЗн", - 582: "ñĥńņň", - 583: "µαη", - 584: "òóôõöōŏő", - 585: "ÈÉÊËĒĔĖĘĚЁЕЬ", - 589: "ĝğġģ‥", - 590: "¯", - 591: "Г", - 592: "Ρ", - 593: "л", - 596: "ξЧ", - 598: "ùúûüũūŭůűų", - 600: "Ω", - 602: "ß", - 603: "λ", - 604: "Р", - 607: "Þο", - 608: "ŋп", - 612: "Φ", - 614: "Κ", - 617: "ц", - 619: "øΒΠ", - 623: "П", - 625: "ΔΛψ", - 626: "ĶКЯ", - 627: "þ", - 630: "\u00ad‐", - 631: "БВъ", - 633: "σ", - 635: "ŔŖŘ", - 638: "π", - 640: "Łм", - 645: "ΨΩφ", - 656: "ий", - 657: "ÇĆĈĊČСЭ", - 660: "ωд", - 661: "ÀÁÂÃÄÅ", - 665: "Α", - 672: "Η", - 674: "Ν", - 677: "ĀĂĄА", - 680: "Л", - 681: "Ц", - 683: "ĎĐŃŊ", - 684: "ÙÚÛÜĤħŨŪŬŮŰŲН", - 686: "ÑŅŇИЙ", - 701: "ĜĞĠĢ", - 708: "ʼn", - 712: "IJ", - 716: "ж", - 720: "¬¬", - 726: "ш", - 728: "ŵ", - 730: "đю", - 740: "щ", - 749: "Ш", - 750: "ÒÓÔÕÖďŌŎŐО", - 757: "Ħ", - 758: "Д", - 761: "ΘΟ", - 773: "ØФ", - 779: "Ð", - 785: "ы", - 791: "Щ", - 797: "Ъ", - 816: "Μ", - 828: "М", - 845: "Ŵ", - 850: "©®", - 870: "Ы", - 880: ( - "¡¢£¤¥«¶»¼½¾¿Ææ―‖†‡•‴‼⁂⁇⁉⁎⁔€℉№℡™Å⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∆∇∈∉∋∌∏∑∓√∝" - "∞∟∠∢∥∦∧∨∩∪∫∬∮∴∵∷∼∽≃≅≈≐≑≒≓≚≠≡≢≤≥≦≧≪≫≮≯≰≱≲≳≶≷≹≺≻⊀⊁⊂⊃⊄⊅⊆⊇⊊⊋⊣⊤⊥⊻" - "⊼⋎⋏⋚⋛⋮⋯⌒─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻" - "┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▭▱▵▶▷▹▼▽▿◀◁◃◈◊◌◍◎◐◑◦◻◼☎☏☕☜☝☞☟☯♀♂♠♡♣♤" - "♥♦♧♨♩♪♬♭♯✖✚✠✣✱✽✿❀❁❇❍❖➔➛➜➞➡➤➵\u3000〃〒〓〠㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝" - "㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'" - "()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abc" - "defghijklmnopqrstuvwxyz{|}~¢£ ̄¦¥₩" - ), - 882: "Ю", - 900: "Ж", - 915: "ф", - 917: "Œ", - 955: "œ", - 1015: "☐➲", - 1033: ( - "⊕⊖⊗⊙⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ◉◯❶❷" - "❸❹❺❻❼❽❾❿➊➋➌➍➎➏➐➑➒➓〶㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫" - "㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿" - ), - }, - "한컴 윤고딕 760": { - 210: "˙", - 215: "˛", - 220: "․", - 250: "ː∶", - 254: "ι", - 274: "‚", - 282: "ìíįıļ", - 290: "‛", - 295: "Ι", - 297: "ÌÍĮİ", - 300: "\u00a0", - 310: "´", - 319: "ĺ", - 320: "˚", - 331: "′", - 348: "˘", - 350: "、。", - 374: "ſ", - 380: "˝‵‶", - 385: "¸", - 390: "⁑〖〗", - 396: "ţŧ", - 407: "ˇ", - 417: "ŕŗ", - 420: "ĵ", - 425: "ĭ", - 430: "Ĭ", - 435: "‹›", - 440: "§", - 443: "¦", - 445: "î", - 450: "ř", - 452: "ï", - 458: "Î", - 460: "ĩ", - 464: "ŀ", - 470: "„‟〞〟", - 473: "з", - 474: "Ĩ", - 475: "Ï", - 480: "²³¹⁴ⁿ₁₂₃₄", - 484: "ľ", - 493: "τ", - 495: "śŝşš", - 500: "ªº", - 510: "【】〔〕〘〙", - 515: "ь", - 520: "⁌⁍", - 526: "″", - 535: "к", - 540: "ł", - 544: "¨", - 548: "г", - 550: "бя", - 554: "ε", - 555: "κ", - 556: "υ", - 557: "Ĵ", - 560: "Īī", - 564: "ijх", - 568: "źżž", - 569: "в", - 574: "çćĉċčсэ", - 575: "ρ", - 578: "ť", - 582: "ĸ", - 584: "ķβ", - 590: "Γ", - 594: "ýÿŷУу", - 597: "àáâãäåāăąа", - 598: "δℓ", - 602: "т", - 607: "Þα", - 608: "ξ", - 616: "ĹĻĽĿ", - 617: "ν", - 619: "èéêëēĕėęěенё", - 625: "μσ", - 626: "ð", - 627: "ŚŜŞŠζ", - 628: "п", - 629: "þ", - 631: "Εъ", - 634: "ο", - 637: "ŢŤŦψТ", - 638: "θ", - 640: "ßч", - 641: "γ", - 643: "З‥", - 645: "Σц", - 650: "\u00ad¯Г‐", - 652: "Ζ", - 655: "Υ", - 657: "òóôõöøōŏőηо", - 658: "д", - 659: "ÝĥŶŸŹŻŽХ", - 663: "ħΧЧ", - 665: "ΡΤ", - 667: "ÈÉÊËĒĔĖĘĚΞЁЕ", - 668: "µñùúûüńņňŋũūŭůűų", - 673: "ĝğġģ", - 675: "Ь", - 678: "λий", - 679: "м", - 683: "πφ", - 685: "χ", - 686: "р", - 687: "ΒР", - 689: "л", - 695: "Ł", - 710: "IJ", - 711: "ш", - 712: "ĶК", - 713: "Π", - 715: "ω", - 717: "БВ", - 718: "Κ", - 721: "ŔŖŘЯ", - 726: "đΨ", - 730: "ж", - 733: "ΑΩ", - 738: "Ω", - 745: "ÇĆĈĊČΔСЭ", - 747: "щ", - 750: "Η", - 752: "Ν", - 755: "Ц", - 760: "Пы", - 762: "Λ", - 764: "Ñ", - 767: "ÀÁÂÃÄÅĀĂĄŊА", - 770: "Д", - 774: "ÙÚÛÜĎŨŪŬŮŰŲ", - 775: "ŃŅŇИЙ", - 776: "ĤН", - 790: "Л", - 793: "ĜĞĠĢ", - 800: "Φ", - 806: "ď", - 807: "ʼn", - 810: "ÐШЪ", - 813: "Θ", - 815: "ю", - 822: "ŵ", - 827: "Ħ", - 832: "Ο", - 836: "ĐФ", - 841: "ÒÓÔÕÖØŌŎŐО", - 860: "Щ", - 890: "Ы", - 897: "Μ", - 912: "Å", - 918: "©®", - 919: "ф", - 920: "М", - 960: ( - "¡¢£¤¥«¬¶»¼½¾¿―‖†‡•‴‼⁂⁇⁉⁎⁔€℉№℡™⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∆∇∈∉∋∌∏∑∓√∝∞∟" - "∠∢∥∦∧∨∩∪∫∬∮∴∵∷∼∽≃≅≈≐≑≒≓≚≠≡≢≤≥≦≧≪≫≮≯≰≱≲≳≶≷≹≺≻⊀⊁⊂⊃⊄⊅⊆⊇⊊⊋⊣⊤⊥⊻⊼⋎" - "⋏⋚⋛⋮⋯⌒─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽" - "┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▭▱▶▷▼▽◀◁◈◊◌◍◎◐◑◻☎☏☕☜☝☞☟☯♀♂♠♡♣♤♥♧♨♩♪♬♭♯" - "✖✚✠✣✱✽✿❀❁❇❍❖➔➛➜➞➡➤➵\u3000〃〒〓〠㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦" - "㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0" - "123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkl" - "mnopqrstuvwxyz{|}~¢£¬ ̄¦¥₩" - ), - 965: "Ŵ", - 970: "Ю", - 977: "æ", - 991: "Æ", - 998: "▵▹▿◃◦", - 1003: "Œ", - 1018: "◼♦", - 1057: "œ", - 1060: "Ж", - 1118: ( - "⊕⊖⊗⊙⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ◉◯☐❶" - "❷❸❹❺❻❼❽❾❿➊➋➌➍➎➏➐➑➒➓➲〶㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩" - "㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿" - ), - }, - "한컴 윤체 L": { - 194: "İıļ", - 212: "ː", - 216: "′", - 223: "ÌÍ", - 231: "í", - 240: "´ì", - 244: "¦", - 252: "Įį", - 254: "〔〕", - 271: "ĺ", - 300: "¸ľ˙˛[]", - 320: "\u00a0{}", - 339: "Ïîï", - 345: "Î", - 349: "²³¹ĵ₁₂₃", - 350: "()", - 354: "∂", - 360: "⁴ⁿ₄", - 362: "ŕŗřţŧſ″", - 397: "¡", - 402: "¶", - 407: "ĩ", - 408: "ij", - 420: "Ĩ", - 430: "ˇ˘˚˝", - 431: "ª", - 436: "Ĭĭ", - 450: "【】", - 453: "śŝşš", - 463: "º", - 464: "\u00ad", - 475: "Īī", - 484: "ť", - 490: "§", - 496: "źżž", - 500: "¨", - 501: "ŀ", - 516: "ĹĻĽĿ", - 524: "Þ", - 535: "ÈÉÊËĒĔĖĘĚ", - 548: "«»", - 552: "ł", - 553: "ŋ", - 554: "ðñùúûüĥńņňũūŭůűŹŻŽ", - 560: "‥", - 562: "ß", - 563: "Ŧ", - 564: "ŢŤ", - 574: "ýþÿķĸŔŖŘŚŜŞŠŷ", - 578: "ų", - 583: "Ķ", - 592: "ÙÚÛÜŨŪŬŮŰŲ", - 595: "¢çćĉċč", - 602: "Ĵ", - 611: "òóôõöøōŏő", - 612: "èéêëēĕėęěĤ", - 624: "¤µ", - 631: "ÑĝğġģŃŅŇŊ", - 633: "£", - 641: "àáâãäåāăą", - 665: "¯", - 670: "Ď", - 677: "IJ", - 680: "Ł", - 681: "Ħ", - 688: "¥¿ÝħŶŸ", - 714: "¬", - 737: "Ð", - 743: "ʼn", - 746: "ÀÁÂÃÄÅ", - 758: "ď", - 776: "ĀĂĄđ", - 800: "αβγδεζηθικλμνξοπρστυφχψω", - 804: "ÇĆĈĊČĐŵ", - 823: "ĜĞĠĢ", - 824: "¼½¾", - 834: "ÒÓÔÕÖØŌŎŐ", - 850: ( - "©®ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯа" - "бвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇" - "∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵" - "ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩" - "┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡" - "♣♤♥♧♨♩♪♬♭\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰" - "㉱㉲㉳㉴㉵㉶㉷㉸㉹㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳" - "㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'*+,-./0123456789:;<=>?" - "@ABCDEFGHIJKLMNOPQRSTUVWXYZ\^_`abcdefghijklmnopqrstuvwxyz|~¢" - "£¬ ̄¥₩" - ), - 877: "Ŵ", - 914: "Æ", - 940: "Œ", - 970: "æ", - 1000: "㉺", - 1100: "œ", - }, - "한컴 소망 M": { - 222: 'ι', - 238: '¦', - 270: '‚‛', - 275: 'ː', - 278: 'Ι', - 280: '′', - 287: 'Ϊ', - 289: '․‧', - 320: '⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉', - 330: '〔〕', - 335: '‖‵', - 338: 'ί', - 355: 'ĵ', - 360: '˙˚', - 369: '‣', - 370: '„‟', - 380: '¸˛', - 390: '()[]', - 395: 'τ', - 396: '‹›', - 399: '•', - 400: '´', - 401: 'ìíîïĺļ', - 420: '§²³¹ÌÍÎÏĨĪīĬĭĮįİı⁴ⁿ₁₂₃₄', - 436: 'ĩ', - 441: 'ζ', - 446: 'ε', - 447: '‼', - 448: 'ξ', - 450: '\xa0ſ【】{}', - 458: 'ľ', - 460: '∂', - 470: '″', - 474: 'ª', - 475: 'ţŧ', - 476: 'º', - 500: 'ˇ˘˝γκλν', - 501: 'ς', - 510: 'ť', - 511: '\xad', - 525: 'χ', - 528: '‐‑', - 542: '¶', - 544: '¨‥', - 547: 'υ', - 551: 'Γ', - 556: 'ηθο', - 557: 'δ', - 560: 'ij', - 563: 'έ', - 565: 'ŕŗř', - 569: 'ρ', - 574: 'ŀ', - 575: 'β', - 576: 'μ', - 577: 'ł', - 578: 'α', - 579: '‗', - 590: 'ή', - 591: 'ΰ', - 594: '‾', - 608: '‴', - 610: 'śŝşš', - 611: 'ΖΤ', - 617: 'σ', - 618: 'Σ', - 619: '«»', - 625: '‒', - 630: 'Ĵ', - 635: '⁄', - 641: 'µ', - 648: 'φ', - 650: 'Ξ', - 655: 'źżž', - 667: 'ΑΒΕΚΡΥΧ', - 668: '¢ΔΛά', - 675: 'çćĉċč', - 689: 'ß', - 690: 'π', - 695: 'èéêëēĕėęě', - 701: 'ð', - 703: 'Ϋ', - 707: 'òóôõöøōŏő', - 713: 'ψ', - 714: 'ĥ', - 716: 'Þ', - 721: 'ŚŜŞŠ', - 722: 'ΗΝΠ', - 725: 'àáâãäåāăą', - 737: 'ýÿŷ', - 740: 'ĹĻĽĿ', - 748: 'Ω', - 750: 'ÈÉÊËĒĔĖĚ', - 757: '£', - 765: 'ĝğġģ', - 769: 'ħ', - 770: '¬¯', - 773: 'þ', - 774: 'ñńņňŋ', - 776: 'ùúûüũūŭůűų', - 778: 'ΘΟ', - 780: 'ķĸ', - 781: 'Ęω', - 786: 'ŹŻŽ', - 794: '₩', - 798: 'Φ', - 800: 'ŢŤŦабвгдежзийклмнопрстуфхцчшщъыьэюяё', - 813: 'đ', - 815: 'ŔŖŘ', - 818: 'ď', - 819: 'Ł', - 833: 'Μ', - 835: 'Ψ', - 841: 'Ð', - 857: 'ÇĆĈĊČ', - 860: 'ĎĶ', - 861: 'ĤĦ', - 865: 'ÑŃŅŇŊ', - 871: 'ʼn', - 875: '¥', - 879: 'Đ', - 880: 'ÙÚÛÜÝŨŪŬŮŰŲŶŸ¥', - 890: 'ÒÓÔÕÖØŌŎŐ', - 900: 'ĜĞĠĢ', - 918: 'IJ', - 934: 'ÀÁÂÃÄÅĀĂĄ', - 947: 'ŵ', - 956: '‱', - 970: '℮−∕∙≈◊', - 1000: '¡¤©®¼½¾¿ŴЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ―†‡€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\^_`abcdefghijklmnopqrstuvwxyz|~¢£¬ ̄₩', - 1048: 'Œ', - 1075: 'œ', - 1097: 'æ', - 1107: 'Æ', - }, - "한컴 소망 B": { - 222: 'ι', - 238: '¦', - 270: '‚‛', - 275: 'ː', - 278: 'Ι', - 280: '′', - 287: 'Ϊ', - 289: '․‧', - 320: '⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉', - 330: '〔〕', - 335: '‖‵', - 338: 'ί', - 360: '˙˚', - 369: 'ĵ‣', - 370: '„‟', - 380: '¸˛', - 390: '()[]', - 395: 'τ', - 396: '‹›', - 399: '•', - 400: '´', - 420: '§²³¹⁴ⁿ₁₂₃₄', - 425: 'ìíîïĩīĭįıĺļ', - 441: 'ζ', - 446: 'ε', - 447: '‼', - 448: 'ξ', - 450: '\xa0ÌÍÎÏĨĪĬĮİſ【】{}', - 460: '∂', - 470: '″', - 474: 'ª', - 476: 'º', - 483: 'ľ', - 500: '˝γκλν', - 501: 'ς', - 509: 'ţťŧ', - 511: '\xad', - 525: 'χ', - 528: '‐‑', - 542: '¶', - 547: 'υ', - 550: 'ˇ˘', - 551: 'Γ', - 556: 'ηθο', - 557: 'δ', - 563: 'έ', - 569: 'ρ', - 574: 'ŀ', - 575: 'β', - 576: 'μ', - 577: 'ł', - 578: 'α', - 579: '‗', - 585: 'ŕŗř', - 590: 'ή', - 591: 'ΰ', - 594: '‾', - 608: '‴', - 611: 'ΖΤ', - 614: '¨', - 617: 'σ', - 618: 'Σ', - 619: '«»ij', - 620: '‥', - 625: '‒', - 630: 'Ĵśŝşš', - 635: '⁄', - 648: 'φ', - 650: 'Ξ', - 655: 'źżž', - 663: 'µ', - 667: 'ΑΒΕΚΡΥΧ', - 668: '¢ΔΛά', - 675: 'çćĉċč', - 690: 'π', - 699: 'èéêëēĕėęě', - 700: 'ß', - 701: 'ð', - 703: 'Ϋ', - 713: 'òóôõöøōŏőψ', - 716: 'Þ', - 721: 'ŚŜŞŠ', - 722: 'ΗΝΠ', - 725: 'àáâãäåāăą', - 737: 'ÿŷ', - 740: 'ĹĻĽĿŁ', - 748: 'Ω', - 750: 'ÈÉÊËĒĔĖĚ', - 757: '£ĸ', - 765: 'ĝğġģ', - 769: 'ĥ', - 770: '¬¯', - 771: 'ý', - 773: 'þ', - 774: 'ñùúûüńņňŋũūŭůűų', - 778: 'ΘΟ', - 780: 'ķ', - 781: 'Ęω', - 786: 'ŹŻŽ', - 794: '₩', - 798: 'Φ', - 800: 'ŢŤŦабвгдежзийклмнопрстуфхцчшщъыьэюяё', - 813: 'đ', - 815: 'ŔŖŘ', - 818: 'ď', - 825: 'ħ', - 833: 'Μ', - 835: 'Ψ', - 841: 'Ð', - 857: 'ÇĆĈĊČ', - 860: 'ĎĶ', - 861: 'ĤĦ', - 865: 'ÑŃŅŇŊ', - 871: 'ʼn', - 875: '¥', - 879: 'Đ', - 880: 'ÙÚÛÜÝŨŪŬŮŰŲŶŸ', - 890: 'ÒÓÔÕÖØŌŎŐ', - 910: 'ĜĞĠĢ', - 934: 'ÀÁÂÃÄÅĀĂĄ', - 940: 'IJ', - 947: 'ŵ', - 956: '‱', - 970: '℮−∕∙≈◊', - 1000: '¡¤©®¼½¾¿ŴЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ―†‡€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\^_`abcdefghijklmnopqrstuvwxyz|~¢£¬ ̄¥₩', - 1053: 'Œ', - 1075: 'œ', - 1097: 'æ', - 1107: 'Æ', - }, - "한컴 백제 B": { - 200: "˙", - 234: "ìíîïıː", - 238: "¦′", - 244: "ÌÍÎÏİĺļ", - 281: "〔〕", - 287: "´", - 308: "Į", - 315: "į", - 350: "²³¸¹˛⁴ⁿ₁₂₃₄", - 360: "ˇ˚˝", - 390: "()[]", - 391: "∂", - 398: "ţŧ", - 399: "ĵ", - 400: "″", - 401: "ľ", - 404: "ŀ", - 414: "Ĭ", - 417: "ĭ", - 425: "\u00ad", - 431: "ſ", - 432: "ĨĴ", - 434: "§", - 436: "ĩ", - 440: "ij", - 450: "ī˘‥【】{}", - 456: "ł", - 458: "Ī", - 470: "ŕŗř", - 474: "ª", - 476: "º", - 484: "Þ", - 487: "ĹĻĽĿ", - 519: "ŢŤŦ", - 530: "ť", - 541: "ýÿŷ", - 553: "śŝşš", - 567: "IJ", - 574: "ÝŶŸźżž", - 577: "«¯»", - 585: "¶", - 589: "ŹŻŽ", - 596: "çćĉċč", - 600: "Ł", - 607: "ÀÁÂÃÄÅĀĂķ", - 610: "èéêëēĕėęě", - 611: "ðŚŜŞŠ", - 621: "ÈÉÊËĒĔĖĚ", - 629: "ĸ", - 635: "òóôõöøōŏő", - 637: "µ", - 640: "Ķ", - 642: "ùúûüũūŭůű", - 644: "¥", - 651: "ñńņňŋ", - 657: "ĝğġģĥ", - 660: "ßĘ", - 662: "àáâãäåþāăĤŔŖŘ", - 677: "ÙÚÛÜŨŪŬŮŰŲ", - 683: "ų", - 684: "ÑŃŅŇŊ", - 691: "ħ", - 695: "Ď", - 700: "αβγδεζηθικλμνξοπρστυφχψωабвгдежзийклмнопрстуфхцчшщъыьэюяё", - 701: "¤", - 704: "Ħ", - 709: "ą", - 717: "ÇĆĈĊČ", - 733: "¬", - 735: "ÐĄĐ", - 740: "đ", - 742: "ĜĞĠĢ", - 764: "ʼn", - 770: "©", - 772: "ÒÓÔÕÖØŌŎŐ", - 782: "ď", - 816: "ŵ", - 838: "Ŵ", - 850: ( - "¡¢£¨®¼½¾¿ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩ" - "ЪЫЬЭЮЯ―†‡€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪" - "≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ" - "─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃" - "╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋" - "㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐" - "㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐" - "㏓㏖㏘㏛㏜㏝!"#$%&'*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" - "YZ\^_`abcdefghijklmnopqrstuvwxyz|~¢£¬ ̄¥₩" - ), - 894: "Æ", - 932: "Œ", - 1040: "æ", - 1057: "œ", - }, - "한컴 백제 M": { - 200: "˙", - 234: "ìíîïıː", - 238: "¦′", - 244: "ÌÍÎÏİĺļ", - 281: "〔〕", - 287: "´", - 292: "Įį", - 321: "Ĵ", - 350: "²³¸¹˛⁴ⁿ₁₂₃₄", - 360: "ˇ˚˝", - 385: "ſ", - 390: "()[]", - 391: "∂", - 398: "ţŧ", - 399: "ĵ", - 400: "˘″", - 401: "ľ", - 404: "ŀ", - 414: "Ĭ", - 417: "ĭ", - 425: "\u00ad", - 430: "ij", - 432: "Ĩ", - 434: "§", - 436: "ĩ", - 450: "ī‥【】{}", - 456: "ł", - 458: "Ī", - 470: "ŕŗř", - 474: "ª", - 476: "º", - 484: "Þ", - 487: "ĹĻĽĿ", - 519: "ŢŤŦ", - 532: "ť", - 541: "ýÿŷ", - 553: "śŝşš", - 554: "IJĸ", - 574: "ÝŶŸźżž", - 577: "«¯»", - 585: "¶", - 589: "ŹŻŽ", - 596: "çćĉċč", - 600: "Ł", - 607: "ÀÁÂÃÄÅĀĂķ", - 610: "èéêëēĕėęě", - 611: "ðŚŜŞŠ", - 621: "ÈÉÊËĒĔĖĘĚ", - 635: "òóôõöøōŏő", - 637: "µ", - 640: "Ķ", - 642: "ùúûüũūŭůű", - 644: "¥", - 651: "ñńņňŋ", - 657: "ĝğġģĥ", - 660: "ß", - 662: "àáâãäåþāăĤŔŖŘ", - 671: "ÙÚÛÜŨŪŬŮŰŲ", - 683: "ų", - 684: "ÑŃŅŇŊ", - 691: "ħ", - 695: "Ď", - 700: "αβγδεζηθικλμνξοπρστυφχψωабвгдежзийклмнопрстуфхцчшщъыьэюяё", - 701: "¤", - 704: "ÇĦ", - 709: "ą", - 717: "ĆĈĊČ", - 727: "đ", - 733: "¬", - 735: "ÐĄĐ", - 742: "ĜĞĠĢ", - 764: "ʼn", - 770: "©", - 772: "ÒÓÔÕÖØŌŎŐ", - 782: "ď", - 816: "ŵ", - 838: "Ŵ", - 850: ( - "¡¢£¨®¼½¾¿ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩ" - "ЪЫЬЭЮЯ―†‡€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪" - "≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ" - "─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃" - "╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋" - "㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐" - "㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐" - "㏓㏖㏘㏛㏜㏝!"#$%&'*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" - "YZ\^_`abcdefghijklmnopqrstuvwxyz|~¢£¬ ̄¥₩" - ), - 887: "Æ", - 905: "Œ", - 1040: "æ", - 1057: "œ", - }, - "한컴 바겐세일 B": { - 226: "¦", - 240: "´", - 278: "ĺļ", - 280: "′", - 281: "ìíîīĭįı", - 292: "ÌÍÎÏĨĪĬĮİ", - 293: "ï", - 310: "ĵ", - 320: "Ĵ()", - 330: "〔〕", - 350: "[]{}", - 359: "ſ", - 360: "ţ", - 365: "ĩ", - 370: "ŧ", - 380: "²³¹⁴ⁿ₁₂₃₄", - 400: "¸˙˚˛", - 411: "ł", - 423: "ľ", - 430: "ˇ˘˝", - 450: "【】", - 455: "ŕŗř", - 460: "∂", - 462: "źżž", - 470: "″", - 474: "ť", - 475: "śŝşš", - 492: "º", - 493: "¢çćĉċč", - 494: "ŀ", - 496: "\u00ad", - 498: "§", - 500: "«»", - 524: "¨", - 537: "Þ", - 542: "ĹĻĽĿ", - 544: "þ", - 549: "èéêëēĕėęě", - 554: "ðýŷ", - 560: "ŹŻŽ", - 566: "òóôõöøĥōŏő", - 570: "ñńņňŋ", - 571: "µùúûüķĸũūŭůűų", - 573: "ÈÉÊËĒĔĖĘĚ", - 577: "ŚŜŞŠ", - 581: "Ł", - 586: "đ", - 588: "ªàáâãäåāăąĝğġģ", - 590: "ŢŤŦ", - 591: "ßij", - 600: "‥", - 603: "ħ", - 608: "¶", - 612: "IJ", - 621: "¬", - 630: "Ķ", - 635: "ŔŖŘ", - 642: "ÇĆĈĊČ", - 644: "ÀÁÂÃÄÅĀĂĄ", - 650: "¥ÝŶŸ", - 657: "ĜĞĠĢ", - 658: "ÑĤĦŃŅŇŊ", - 660: "≠", - 667: "ÙÚÛÜŨŪŬŮŰŲ", - 680: "ĎĐ", - 690: "ʼn", - 700: "αβγδεζηθικλμνξοπρστυφχψωабвгдежзийклмнопрстуфхцчшщъыьэюяё", - 701: "ÒÓÔÕÖØŌŎŐ", - 706: "¯", - 718: "Ð", - 724: "ŵ", - 727: "ď", - 800: ( - "¡£¤®¼½¾¿ːΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩ" - "ЪЫЬЭЮЯ―†‡€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≡≤≥≪≫" - "⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─" - "━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄" - "╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌" - "㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑" - "㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓" - "㏖㏘㏛㏜㏝!"#$%&'*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXY" - "Z\^_`abcdefghijklmnopqrstuvwxyz|~¢£¬ ̄¥₩" - ), - 830: "©", - 874: "Œ", - 881: "Ŵ", - 904: "æ", - 908: "œ", - 922: "Æ", - }, - "한컴 바겐세일 M": { - 226: "¦", - 240: "´", - 275: "ː", - 278: "ĺļ", - 280: "′", - 281: "ìíîīĭįı", - 292: "ÌÍÎÏĨĪĬĮİ", - 293: "ï", - 305: "¡", - 310: "ĵ", - 320: "Ĵ()", - 330: "〔〕", - 335: "¸", - 337: "˙", - 338: "˛", - 346: "˚", - 350: "[]{}", - 359: "ſ", - 360: "ţ", - 365: "ĩ", - 370: "ŧ", - 380: "²³¹⁴ⁿ₁₂₃₄", - 411: "ł", - 420: "˝", - 423: "ľ", - 450: "【】", - 455: "ŕŗř", - 460: "∂", - 462: "źżž", - 468: "ˇ˘", - 470: "″", - 474: "ť", - 475: "śŝşš", - 484: "¿", - 492: "º", - 493: "¢çćĉċč", - 494: "ŀ", - 496: "¨\u00ad", - 498: "§", - 500: "«»", - 512: "‥", - 537: "Þ", - 542: "ĹĻĽĿ", - 544: "þ", - 549: "èéêëēĕėęě", - 554: "ðýÿŷ", - 560: "ŹŻŽ", - 561: "¤", - 566: "òóôõöøĥōŏő", - 570: "ñńņňŋ", - 571: "µùúûüķĸũūŭůűų", - 573: "ÈÉÊËĒĔĖĘĚ", - 577: "ŚŜŞŠ", - 581: "Ł", - 586: "đ", - 588: "ªàáâãäåāăąĝğġģ", - 590: "ŢŤŦ", - 591: "ßij", - 603: "ħ", - 608: "¶", - 612: "IJ", - 621: "¬", - 628: "≠", - 630: "Ķ", - 635: "ŔŖŘ", - 642: "ÇĆĈĊČ", - 644: "ÀÁÂÃÄÅĀĂĄ", - 650: "¥ÝŶŸ", - 657: "ĜĞĠĢ", - 658: "ÑĤĦŃŅŇŊ", - 667: "ÙÚÛÜŨŪŬŮŰŲ", - 680: "ĎĐ", - 690: "ʼn", - 700: "αβγδεζηθικλμνξοπρστυφχψωабвгдежзийклмнопрстуфхцчшщъыьэюяё", - 701: "ÒÓÔÕÖØŌŎŐ", - 706: "¯", - 718: "Ð", - 724: "ŵ", - 727: "ď", - 800: ( - "£¼½¾ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮ" - "Я―†‡€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≡≤≥≪≫⊂⊃⊆⊇⊙" - "⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍" - "┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉" - "╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑" - "㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖" - "㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝" - "!"#$%&'*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\^_`" - "abcdefghijklmnopqrstuvwxyz|~¢£¬ ̄¥₩" - ), - 830: "©®", - 874: "Œ", - 881: "Ŵ", - 904: "æ", - 908: "œ", - 922: "Æ", - }, - "새굴림": { - 256: "¦ìíîïīĭįıĵĺļľł∙", - 293: "ĩ", - 299: "ÌÍÎÏĨĪĬĮİΙ", - 320: "\u0387ŀ˙˚˛", - 341: "¸ŕŗřţťŧ‚‛", - 384: "²³´¹ſˇ˘ι•′‹›∫▪▫◦", - 427: "¡⁄∕", - 448: "ªº˝ⁿ", - 512: "\u00a0¨«\u00ad¯»ýÿŷźżžζνξгух‗„″‾ℓ", - 555: "ĴķĸśŝşšκУк", - 561: "ь", - 562: "√", - 576: "¤§¶¼½¾γεзлчя†‡⅛⅜⅝⅞∂", - 577: "β", - 585: "δд", - 596: "Þ", - 597: "¢µ¿àáâãäåçèéêëùúûüāăąćĉċčēĕėęěĥħijĹĻĽĿŁŢŤŦũūŭůűųΤμτυχТЧаестё", - 609: "£ΓГ", - 623: "ц", - 628: "∆", - 640: "¥ÝßðñòóôõöøþďđĝğġģńņňŋōŏőŶŸŹŻŽΖΥΧαηορσφЗХбвийнопръэ‼♀♂", - 673: "Ь", - 683: "ÀÁÂÃÄÅÈÉÊËĀĂĄĒĔĖĘĚĶŚŜŞŠΕΚΛΡЁАБЕКР", - 704: "ΑΣΨθλπ―∏♪", - 719: "Π", - 720: "¬", - 725: "ŔŖŘΒВЯ", - 729: "Л", - 736: "ы∩", - 738: "ʼn", - 749: "ψ", - 756: "Ц", - 768: "ÇÐÑÙÚÛÜĆĈĊČĎĐĤĦIJŃŅŇŊŨŪŬŮŰŲŵΗΝΩωИЙНСЪЭжмф€Ω↕►◄♠", - 769: "Δ", - 781: "♫", - 790: "П", - 793: "◊♦", - 802: "©®", - 806: "æ", - 811: "ÒÓÔÕÖØŌŎŐΘΟΦО", - 812: "♥", - 832: "ΞДФшщ∑", - 853: "ĜĞĠĢ−≈≠≡≤≥", - 856: "М", - 864: "♣", - 865: "Ы", - 896: "œΜ", - 911: "ю", - 935: "∞", - 936: "▼", - 938: "☼", - 939: "Ŵ", - 960: "ÆШЩ", - 989: "Ж", - 1006: "∟", - 1024: ( - "ŒːЮ‥⁴₁₂₃₄℉№℡™Å⅓⅔↔↖↗↘↙⇒⇔∀∃∇∈∋∝∠∥∧∨∪∬∮∴∵∼∽≒≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥" - "⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙" - "┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▬▶" - "▷▽◀◁◈◎◐◑◘◙☎☏☜☞☺☻♡♤♧♨♩♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛" - "㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠" - "㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*" - "+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdef" - "ghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - }, - "한컴 말랑말랑 Regular": { - 161: "\u0387", - 208: "′", - 226: "¡", - 235: "ıι", - 300: "\u00a0", - 330: "ː∶", - 357: "г", - 368: "˙", - 378: "″", - 379: "Ι", - 390: "∫", - 400: "²³´¸¹ˇ˘˚˛⁴ⁿ", - 405: "ŀ", - 420: "、。", - 426: "ŧ", - 428: "¨˝", - 440: "εзть₁₂₃₄", - 451: "ξ", - 460: "łζв", - 465: "я", - 468: "ij", - 470: "¿", - 476: "ч", - 484: "\u00adх", - 490: "∮", - 495: "п", - 500: "Г‖∥", - 502: "и", - 508: "λ", - 510: "§ℓ", - 517: "й", - 520: "ªºγτ【】〔〕", - 524: "ĸκк", - 529: "ĿΓ", - 530: "Σ", - 531: "ŦΤТ", - 534: "ΕЁЕ∃", - 535: "У", - 536: "ц", - 537: "н", - 540: "лъ", - 541: "с", - 545: "ν", - 547: "∂", - 550: "υ†‡≤≥", - 560: "δ", - 562: "д", - 564: "э", - 565: "β", - 568: "Ζ", - 570: "ßЗ", - 574: "у", - 577: "ŋη", - 580: "θ≡", - 587: "ΒБВЬ‥", - 590: "ΡР", - 592: "её", - 595: "μ", - 598: "ΦФ", - 600: "ð∑", - 602: "Я", - 606: "ΚК", - 608: "οо", - 610: "Ł", - 615: "Ξ", - 619: "Ч", - 620: "π∠", - 622: "ø", - 624: "б", - 626: "ΧχХ", - 629: "þΥαρар", - 630: "Δ", - 639: "ж", - 640: "∬", - 650: "£¶≒£", - 652: "ħ", - 660: "φы", - 670: "ИЙ≠", - 673: "¥¥", - 676: "СЭ", - 678: "ʼn", - 680: "Ŋ", - 685: "Þ", - 687: "ΑΛА∀", - 690: "ΗΝНш", - 693: "Å", - 694: "ΨΩΩ", - 696: "¤", - 699: "ΠП", - 700: "∏", - 706: "Ц", - 707: "đ", - 710: "Л", - 714: "ψ", - 717: "щ", - 720: "σ", - 740: "ωД", - 741: "Ъ", - 750: "⊥", - 780: "∧∨∩∪", - 783: "«»≪≫", - 790: "Ħю", - 793: "IJ", - 800: "Ð⌒", - 808: "€", - 810: "Ø", - 823: "ΘΟО", - 838: "м", - 860: "Ж", - 862: "Ы", - 870: "⊆⊇", - 880: ( - "¢¬¼½¾ÆŒ―℉№℡™⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∇∈√∝∞∴∵∼∽⊂⊃⊙⋯─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├" - "┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀" - "◁◈◉◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000〃〓!"#$%&'()*+,-./0123456789:;<=>?@AB" - "CDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~" - "¢¬ ̄₩" - ), - 923: "æ", - 924: "Ш", - 940: "∋", - 960: "Щ", - 961: "ΜМ", - 992: "ф", - 1000: ( - "©®⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ㈀㈁㈂㈃㈄㈅" - "㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊" - "㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆" - "㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝" - ), - 1023: "œ", - 1051: "Ю", - }, - "MD개성체": { - 972: ( - "⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ、。㈀㈁㈂㈃㈄㈅" - "㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻!"#$%&'()" - "*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdef" - "ghijklmnopqrstuvwxyz{|} ̄₩" - ), - 1024: ( - "\u00a0¡¢£¤¥¦§¨©ª«¬\u00ad®¯²³´µ¶¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞß" - "àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ" - ), - }, - "한컴 말랑말랑 Bold": { - 230: "ι", - 258: "′", - 270: "¡", - 276: "ı", - 300: "\u00a0", - 330: "ː∶", - 368: "˙", - 369: "г", - 394: "Ι", - 400: "²³´¸¹ˇ˘˚˛⁴ⁿ₁₂₃₄", - 410: "∫", - 420: "、。", - 428: "¨˝", - 434: "ŀ", - 436: "ŧ", - 437: "т", - 448: "″", - 460: "εз", - 462: "ь", - 471: "ł", - 479: "я", - 480: "ζξ", - 486: "ч", - 487: "в", - 500: "\u00adх‖∥", - 507: "¿", - 510: "§", - 514: "∮", - 517: "ий", - 520: "【】〔〕", - 522: "п", - 526: "ΓГ", - 530: "ªºΕЁЕ∃", - 532: "ij", - 533: "λ", - 535: "ĸκк", - 536: "ℓ", - 537: "н", - 544: "τ", - 545: "γъ", - 547: "ц", - 550: "†‡≤≥", - 551: "ŦΤТ", - 552: "сэ", - 553: "У", - 554: "л", - 557: "∂", - 560: "δ", - 564: "ν", - 569: "Ζ", - 570: "Συ", - 572: "д", - 579: "З", - 582: "χ", - 585: "ΒβБВЬ", - 587: "η", - 588: "у", - 590: "ΡРеё", - 592: "ŋ", - 596: "θ", - 598: "‥≡", - 600: "ßð∑", - 601: "Я", - 605: "ΚК", - 610: "Ł", - 612: "ΦФ", - 620: "Ŀ∠", - 622: "οо", - 623: "μ", - 629: "Ξ", - 630: "ΥΧХ", - 632: "Ч", - 639: "αρар", - 649: "øб", - 650: "¶", - 651: "þ", - 653: "ж", - 656: "π", - 658: "ħ", - 664: "φ", - 668: "≒", - 674: "ы", - 680: "£∬£", - 682: "ИЙ", - 683: "ʼn", - 684: "ΑΛА∀", - 685: "Þ", - 688: "≠", - 689: "СЭ", - 690: "П", - 696: "¤Δ", - 697: "ш", - 700: "¥ΗΝН¥", - 710: "ŊΠ", - 712: "∏", - 722: "đ", - 726: "Ц", - 727: "щ", - 728: "Л", - 730: "ΩσΩ", - 734: "Ψψ", - 735: "Ъ", - 750: "⊥", - 769: "Д", - 770: "ω", - 783: "«»≪≫", - 790: "∧∨∩∪", - 800: "⌒", - 802: "ю", - 809: "IJ", - 812: "Ð", - 816: "Ø", - 819: "€", - 820: "Ħ", - 848: "ΘΟОм", - 876: "⊆⊇", - 880: ( - "¢¬¼½¾Æ―℉№℡™Å⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∇∈∝∞∴∵∼∽⊂⊃⊙⋯─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝" - "┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁" - "◈◉◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000〃〓!"#$%&'()*+,-./0123456789:;<=>?@ABC" - "DEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢" - "¬ ̄₩" - ), - 899: "Ы", - 904: "Ж", - 934: "Ш", - 940: "∋", - 943: "æ", - 950: "Œ", - 972: "ΜМ", - 979: "Щ", - 980: "√", - 992: "ф", - 1000: ( - "©®⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ㈀㈁㈂㈃㈄㈅" - "㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊" - "㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆" - "㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝" - ), - 1027: "œ", - 1068: "Ю", - }, - "KoPub돋움체 Light": { - 160: "·", - 167: "⁄", - 223: "ι", - 260: "𐤟", - 280: "²³¹⁴ⁿ₁₂₃₄", - 289: "․", - 290: "ìíîǐỉị", - 294: "ˮ", - 300: "¡", - 312: "\uf09e\uf0a0", - 319: "º", - 335: "‖", - 352: "ī", - 365: "г", - 385: "\uf0fa", - 396: "τ", - 400: "•‣", - 438: "к", - 440: "ζ", - 447: "εξ", - 450: "§¸ː˛′″∂、。【】〔〕", - 451: "з", - 458: "т\uf0a7\uf027\uf073\uf09f", - 483: "\uf0f9", - 485: "「」■", - 486: "¿", - 500: "γκλνсухàáâãäāăǎạảấầẩẫậắằẳặ・\U000f0800\U000f0854\U000f0855\uf07f", - 506: "¢", - 510: "э", - 520: "¥", - 521: "чь", - 525: "χ", - 527: "‐", - 531: "в\uf07d\uf07e", - 533: "£«»", - 540: "èéêñòóôõöùúûüēěōũūơưǒǔǚǜẹẻẽếềểễệọỏốồổỗộớờởỡợụủ", - 542: "Гпя", - 547: "υ", - 549: "\uf047\uf048", - 550: "Γ", - 552: "н", - 554: "\uf035", - 556: "δηθοаеорё", - 559: "ий", - 565: "ứừửữự", - 569: "ρ", - 570: "−", - 573: "бц", - 576: "βμ", - 578: "α\uf077", - 583: "Кдлỷ", - 587: "\uf041", - 589: "ʹ", - 600: "ß◦", - 603: "\uf036", - 604: "З", - 610: "ΖΤ", - 611: "Т", - 616: "σ", - 618: "Σ", - 625: "‒ъ", - 635: "У", - 636: "\uf0fb", - 647: "φ", - 650: "Ξ", - 651: "\uf053", - 656: "БЛЬ", - 660: "\uf04e", - 667: "ΑΒΔΕΚΛΡΥΧЁАВЕРХЧÉ", - 669: "ж", - 674: "Ç\uf043\uf044", - 677: "Д", - 688: "м", - 690: "π", - 693: "\uf058", - 700: "\uf032\uf033", - 706: "©", - 707: "Đ", - 712: "ψ", - 719: "ИЙПЭы", - 722: "НСЯ", - 723: "ΗΝΠ\uf057", - 740: "Ц", - 747: "Ω\uf055\uf056\uf06c\uf06e\uf074", - 750: "юÀÁÄÜ", - 760: "Ф", - 776: "\uf0e3\uf0e4\uf0e5\uf0e6", - 778: "ΘΟО", - 780: "ω\uf069", - 783: "\uf0f5\uf0f6\uf0f7\uf0f8", - 787: "\uf0fc", - 792: "Ъ", - 793: "\uf042", - 794: "\uf059\uf0d7\uf0d8", - 798: "Φ", - 799: "¼½¾⅓⅔⅛⅜⅝⅞", - 802: "ш", - 811: "\uf0f1\uf0f2\uf0f4", - 813: "\uf054", - 823: "фщ", - 832: "Μ", - 833: "М", - 836: "Ψ", - 843: "\uf04a\uf04b\uf04c", - 849: "\uf04f", - 873: "\uf0eb\uf0ec\uf0ed\uf0ee", - 880: "\uf052", - 885: "Ы\uf05a", - 887: "\uf051", - 891: "\uf03b\uf03e\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0", - 893: "\uf029\uf034\uf03c\uf03d\uf049\uf05b\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0fd\uf0fe", - 894: "\uf025", - 896: "\uf05c", - 900: ( - "¤¨ª\u00ad®´¶ÆÐØÞæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ↔↕↖↗↘↙⇒⇔" - "∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱" - "⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥" - "┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞" - "♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌" - "㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑" - "㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓" - "㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVW" - "XYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩ぁあぃいぅうぇえぉおかがきぎく" - "ぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりる" - "れろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピ" - "フブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ" - ), - 911: "\uf03f\uf040", - 917: "Ш", - 923: "Ж", - 929: "\uf066", - 933: "\uf063", - 938: "Щ", - 940: "\uf03a\uf062", - 943: "\uf045\uf046", - 947: "\uf038\uf064", - 953: "\uf06d\uf0a6", - 963: "\uf060", - 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", - 980: "\uf0df\uf0e0", - 987: "\uf075", - 1000: "・ー\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4", - 1010: "Ю", - 1025: "\uf065", - 1031: "\uf021", - 1036: "\uf0ff", - 1047: "\uf0c7\uf0c8\uf0c9\uf0ca", - 1051: "\uf06a", - 1054: "\uf05f", - 1060: "\uf078\uf079\uf0f3", - 1065: "\uf068", - 1067: "\uf0e7\uf0e8", - 1073: "\uf037", - 1078: "\uf039", - 1083: "\uf028", - 1089: "\uf050", - 1091: "\uf061", - 1096: "\uf030\uf067", - 1111: "\uf04d", - 1133: "\uf02a\uf02b", - 1145: "\uf022", - 1156: "\uf05e", - 1171: "\uf02c\uf02d", - 1216: "\uf026", - 1253: "\uf0d5\uf0d6", - 1271: "\uf06b", - 1300: "\uf023", - }, - "KoPub돋움체 Medium": { - 160: "·", - 167: "⁄", - 223: "ι", - 260: "𐤟", - 280: "²³¹⁴ⁿ₁₂₃₄", - 289: "․", - 290: "ìíîǐỉị", - 294: "ˮ", - 300: "¡", - 312: "\uf09e\uf0a0", - 319: "º", - 335: "‖", - 352: "ī", - 365: "г", - 396: "τ", - 400: "•‣", - 438: "к", - 440: "ζ", - 447: "εξ", - 450: "§¸ː˛′″∂、。【】〔〕", - 451: "з", - 458: "т\uf0a7", - 485: "「」■", - 486: "¿", - 500: "γκλνсухàáâãäāăǎạảấầẩẫậắằẳặ・\U000f0800\U000f0854\U000f0855", - 506: "¢", - 510: "э", - 520: "¥", - 521: "чь", - 525: "χ", - 527: "‐", - 531: "в", - 533: "£«»", - 540: "èéêñòóôõöùúûüēěōũūơưǒǔǚǜẹẻẽếềểễệọỏốồổỗộớờởỡợụủ", - 542: "Гпя", - 547: "υ", - 550: "Γ", - 552: "н", - 556: "δηθοаеорё", - 559: "ий", - 565: "ứừửữự", - 569: "ρ", - 570: "−", - 573: "бц", - 576: "βμ", - 578: "α", - 583: "Кдлỷ", - 589: "ʹ", - 600: "ß◦", - 604: "З", - 610: "ΖΤ", - 611: "Т", - 616: "σ", - 618: "Σ", - 625: "‒ъ", - 635: "У", - 647: "φ", - 650: "Ξ", - 656: "БЛЬ", - 667: "ΑΒΔΕΚΛΡΥΧЁАВЕРХЧÉ", - 669: "ж", - 674: "Ç", - 677: "Д", - 688: "м", - 690: "π", - 706: "©", - 707: "Đ", - 712: "ψ", - 719: "ИЙПЭы", - 722: "НСЯ", - 723: "ΗΝΠ", - 740: "Ц", - 747: "Ω", - 750: "юÀÁÄÜ", - 760: "Ф", - 778: "ΘΟО", - 780: "ω", - 787: "\uf0fc", - 792: "Ъ", - 798: "Φ", - 799: "¼½¾⅓⅔⅛⅜⅝⅞", - 802: "ш", - 823: "фщ", - 832: "Μ", - 833: "М", - 836: "Ψ", - 885: "Ы", - 900: ( - "¤¨ª\u00ad®´¶ÆÐØÞæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ↔↕↖↗↘↙⇒⇔" - "∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱" - "⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥" - "┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞" - "♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌" - "㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑" - "㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓" - "㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVW" - "XYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩ぁあぃいぅうぇえぉおかがきぎく" - "ぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりる" - "れろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピ" - "フブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ" - ), - 917: "Ш", - 923: "Ж", - 938: "Щ", - 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", - 1000: "・ー\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851", - 1010: "Ю", - }, - "KoPub돋움체 Bold": { - 160: "·", - 167: "⁄", - 223: "ι", - 260: "𐤟", - 280: "²³¹⁴ⁿ₁₂₃₄", - 289: "․", - 290: "ìíîǐỉị", - 294: "ˮ", - 300: "¡", - 312: "\uf09e\uf0a0", - 319: "º", - 335: "‖", - 352: "ī", - 365: "г", - 396: "τ", - 400: "•‣", - 438: "к", - 440: "ζ", - 447: "εξ", - 450: "§¸ː˛′″∂、。【】〔〕", - 451: "з", - 458: "т\uf0a7", - 485: "「」■", - 486: "¿", - 500: "γκλνсухàáâãäāăǎạảấầẩẫậắằẳặ・\U000f0800\U000f0854\U000f0855", - 506: "¢", - 510: "э", - 520: "¥", - 521: "чь", - 525: "χ", - 527: "‐", - 531: "в", - 533: "£«»", - 540: "èéêñòóôõöùúûüēěōũūơưǒǔǚǜẹẻẽếềểễệọỏốồổỗộớờởỡợụủ", - 542: "Гпя", - 547: "υ", - 550: "Γ", - 552: "н", - 556: "δηθοаеорё", - 559: "ий", - 565: "ứừửữự", - 569: "ρ", - 570: "−", - 573: "бц", - 576: "βμ", - 578: "α", - 583: "Кдлỷ", - 589: "ʹ", - 600: "ß◦", - 604: "З", - 610: "ΖΤ", - 611: "Т", - 616: "σ", - 618: "Σ", - 625: "‒ъ", - 635: "У", - 647: "φ", - 650: "Ξ", - 656: "БЛЬ", - 667: "ΑΒΔΕΚΛΡΥΧЁАВЕРХЧÉ", - 669: "ж", - 674: "Ç", - 677: "Д", - 688: "м", - 690: "π", - 706: "©", - 707: "Đ", - 712: "ψ", - 719: "ИЙПЭы", - 722: "НСЯ", - 723: "ΗΝΠ", - 740: "Ц", - 747: "Ω", - 750: "юÀÁÄÜ", - 760: "Ф", - 778: "ΘΟО", - 780: "ω", - 787: "\uf0fc", - 792: "Ъ", - 798: "Φ", - 799: "¼½¾⅓⅔⅛⅜⅝⅞", - 802: "ш", - 823: "фщ", - 832: "Μ", - 833: "М", - 836: "Ψ", - 885: "Ы", - 900: ( - "¤¨ª\u00ad®´¶ÆÐØÞæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ↔↕↖↗↘↙⇒⇔" - "∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱" - "⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥" - "┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞" - "♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌" - "㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑" - "㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓" - "㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVW" - "XYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩ぁあぃいぅうぇえぉおかがきぎく" - "ぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりる" - "れろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピ" - "フブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ" - ), - 917: "Ш", - 923: "Ж", - 938: "Щ", - 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", - 1000: "・ー\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851", - 1010: "Ю", - }, - "KoPub바탕체 Light": { - 160: "·", - 167: "⁄", - 223: "ι", - 260: "𐤟", - 280: "²³¹º⁴₁₂₃₄", - 289: "․", - 290: "ìíîǐỉị", - 294: "ˮ", - 312: "¡\uf09e\uf0a0", - 335: "‖", - 346: "ⁿ", - 352: "ī", - 365: "г", - 385: "\uf0fa", - 396: "τ", - 400: "•‣", - 438: "к", - 440: "«»ζ", - 447: "εξ", - 450: "§¸ː˛′″∂、。【】〔〕", - 451: "з", - 458: "т\uf0a7\uf027\uf073\uf09f", - 468: "¿", - 483: "\uf0f9", - 485: "「」■", - 500: "γκλνсухàáâãäāăǎạảấầẩẫậắằẳặ・\U000f0800\U000f0854\U000f0855\uf07f", - 510: "э", - 521: "чь", - 525: "χ", - 527: "‐", - 531: "в\uf07d\uf07e", - 536: "¢", - 540: "èéêñòóôõöùúûüēěōũūơưǒǔǚǜẹẻẽếềểễệọỏốồổỗộớờởỡợụủ", - 542: "Гпя", - 547: "υ", - 549: "\uf047\uf048", - 550: "Γ", - 552: "н", - 554: "\uf035", - 555: "£", - 556: "δηθοаеорё", - 559: "ий", - 565: "ứừửữự", - 569: "ρ", - 570: "−", - 573: "бц", - 576: "βμ", - 578: "α\uf077", - 583: "Кдлỷ", - 587: "\uf041", - 589: "ʹ", - 600: "◦", - 603: "\uf036", - 604: "З", - 610: "ΖΤ", - 611: "Т", - 616: "σ", - 618: "Σ", - 620: "ß", - 625: "‒ъ", - 635: "У", - 636: "\uf0fb", - 647: "φ", - 650: "Ξ", - 651: "\uf053", - 656: "БЛЬ", - 660: "\uf04e", - 667: "ΑΒΔΕΚΛΡΥΧЁАВЕРХЧÉ", - 669: "ж", - 674: "Ç\uf043\uf044", - 677: "Д", - 688: "м", - 690: "π", - 693: "\uf058", - 700: "\uf032\uf033", - 706: "¥", - 707: "Đ", - 712: "ψ", - 719: "ИЙПЭы", - 722: "НСЯ", - 723: "ΗΝΠ\uf057", - 740: "Ц", - 747: "Ω\uf055\uf056\uf06c\uf06e\uf074", - 750: "юÀÁÄÜ", - 760: "Ф", - 776: "\uf0e3\uf0e4\uf0e5\uf0e6", - 778: "ΘΟО", - 780: "ω\uf069", - 783: "\uf0f5\uf0f6\uf0f7\uf0f8", - 787: "\uf0fc", - 792: "Ъ", - 793: "\uf042", - 794: "\uf059\uf0d7\uf0d8", - 798: "Φ", - 802: "ш", - 811: "\uf0f1\uf0f2\uf0f4", - 813: "\uf054", - 823: "фщ", - 832: "Μ", - 833: "М", - 836: "Ψ", - 843: "\uf04a\uf04b\uf04c", - 849: "\uf04f", - 873: "\uf0eb\uf0ec\uf0ed\uf0ee", - 880: "\uf052", - 885: "Ы\uf05a", - 887: "\uf051", - 891: "\uf03b\uf03e\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0", - 893: "\uf029\uf034\uf03c\uf03d\uf049\uf05b\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0fd\uf0fe", - 894: "\uf025", - 896: "\uf05c", - 900: ( - "¤¨©ª\u00ad®´¶¼½¾ÆÐØÞæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ⅓⅔⅛⅜" - "⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧" - "⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛" - "├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽" - "◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂" - "㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄" - "㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃" - "㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLM" - "NOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩ぁあぃいぅ" - "うぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめ" - "もゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナ" - "ニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ" - ), - 911: "\uf03f\uf040", - 917: "Ш", - 923: "Ж", - 929: "\uf066", - 933: "\uf063", - 938: "Щ", - 940: "\uf03a\uf062", - 943: "\uf045\uf046", - 947: "\uf038\uf064", - 953: "\uf06d\uf0a6", - 963: "\uf060", - 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", - 980: "\uf0df\uf0e0", - 987: "\uf075", - 1000: "・ー\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4", - 1010: "Ю", - 1025: "\uf065", - 1031: "\uf021", - 1036: "\uf0ff", - 1047: "\uf0c7\uf0c8\uf0c9\uf0ca", - 1051: "\uf06a", - 1054: "\uf05f", - 1060: "\uf078\uf079\uf0f3", - 1065: "\uf068", - 1067: "\uf0e7\uf0e8", - 1073: "\uf037", - 1078: "\uf039", - 1083: "\uf028", - 1089: "\uf050", - 1091: "\uf061", - 1096: "\uf030\uf067", - 1111: "\uf04d", - 1133: "\uf02a\uf02b", - 1145: "\uf022", - 1156: "\uf05e", - 1171: "\uf02c\uf02d", - 1216: "\uf026", - 1253: "\uf0d5\uf0d6", - 1271: "\uf06b", - 1300: "\uf023", - }, - "KoPub바탕체 Medium": { - 160: "·", - 167: "⁄", - 223: "ι", - 260: "𐤟", - 280: "²³¹º⁴₁₂₃₄", - 289: "․", - 290: "ìíîǐỉị", - 294: "ˮ", - 312: "¡\uf09e\uf0a0", - 335: "‖", - 346: "ⁿ", - 352: "ī", - 365: "г", - 396: "τ", - 400: "•‣", - 438: "к", - 440: "«»ζ", - 447: "εξ", - 450: "§¸ː˛′″∂、。【】〔〕", - 451: "з", - 458: "т\uf0a7", - 468: "¿", - 485: "「」■", - 500: "γκλνсухàáâãäāăǎạảấầẩẫậắằẳặ・\U000f0800\U000f0854\U000f0855", - 510: "э", - 521: "чь", - 525: "χ", - 527: "‐", - 531: "в", - 536: "¢", - 540: "èéêñòóôõöùúûüēěōũūơưǒǔǚǜẹẻẽếềểễệọỏốồổỗộớờởỡợụủ", - 542: "Гпя", - 547: "υ", - 550: "Γ", - 552: "н", - 555: "£", - 556: "δηθοаеорё", - 559: "ий", - 565: "ứừửữự", - 569: "ρ", - 570: "−", - 573: "бц", - 576: "βμ", - 578: "α", - 583: "Кдлỷ", - 589: "ʹ", - 600: "◦", - 604: "З", - 610: "ΖΤ", - 611: "Т", - 616: "σ", - 618: "Σ", - 620: "ß", - 625: "‒ъ", - 635: "У", - 647: "φ", - 650: "Ξ", - 656: "БЛЬ", - 667: "ΑΒΔΕΚΛΡΥΧЁАВЕРХЧÉ", - 669: "ж", - 674: "Ç", - 677: "Д", - 688: "м", - 690: "π", - 706: "¥", - 707: "Đ", - 712: "ψ", - 719: "ИЙПЭы", - 722: "НСЯ", - 723: "ΗΝΠ", - 740: "Ц", - 747: "Ω", - 750: "юÀÁÄÜ", - 760: "Ф", - 778: "ΘΟО", - 780: "ω", - 787: "\uf0fc", - 792: "Ъ", - 798: "Φ", - 802: "ш", - 823: "фщ", - 832: "Μ", - 833: "М", - 836: "Ψ", - 885: "Ы", - 900: ( - "¤¨©ª\u00ad®´¶¼½¾ÆÐØÞæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ⅓⅔⅛⅜" - "⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧" - "⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛" - "├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽" - "◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂" - "㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄" - "㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃" - "㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLM" - "NOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩ぁあぃいぅ" - "うぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめ" - "もゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナ" - "ニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ" - ), - 917: "Ш", - 923: "Ж", - 938: "Щ", - 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", - 1000: "・ー\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851", - 1010: "Ю", - }, - "KoPub바탕체 Bold": { - 160: "·", - 167: "⁄", - 223: "ι", - 260: "𐤟", - 280: "²³¹º⁴₁₂₃₄", - 289: "․", - 290: "ìíîǐỉị", - 294: "ˮ", - 312: "¡\uf09e\uf0a0", - 335: "‖", - 346: "ⁿ", - 352: "ī", - 365: "г", - 396: "τ", - 400: "•‣", - 438: "к", - 440: "«»ζ", - 447: "εξ", - 450: "§¸ː˛′″∂、。【】〔〕", - 451: "з", - 458: "т\uf0a7", - 468: "¿", - 485: "「」■", - 500: "γκλνсухàáâãäāăǎạảấầẩẫậắằẳặ・\U000f0800\U000f0854\U000f0855", - 510: "э", - 521: "чь", - 525: "χ", - 527: "‐", - 531: "в", - 536: "¢", - 540: "èéêñòóôõöùúûüēěōũūơưǒǔǚǜẹẻẽếềểễệọỏốồổỗộớờởỡợụủ", - 542: "Гпя", - 547: "υ", - 550: "Γ", - 552: "н", - 555: "£", - 556: "δηθοаеорё", - 559: "ий", - 565: "ứừửữự", - 569: "ρ", - 570: "−", - 573: "бц", - 576: "βμ", - 578: "α", - 583: "Кдлỷ", - 589: "ʹ", - 600: "◦", - 604: "З", - 610: "ΖΤ", - 611: "Т", - 616: "σ", - 618: "Σ", - 620: "ß", - 625: "‒ъ", - 635: "У", - 647: "φ", - 650: "Ξ", - 656: "БЛЬ", - 667: "ΑΒΔΕΚΛΡΥΧЁАВЕРХЧÉ", - 669: "ж", - 674: "Ç", - 677: "Д", - 688: "м", - 690: "π", - 706: "¥", - 707: "Đ", - 712: "ψ", - 719: "ИЙПЭы", - 722: "НСЯ", - 723: "ΗΝΠ", - 740: "Ц", - 747: "Ω", - 750: "юÀÁÄÜ", - 760: "Ф", - 778: "ΘΟО", - 780: "ω", - 787: "\uf0fc", - 792: "Ъ", - 798: "Φ", - 802: "ш", - 823: "фщ", - 832: "Μ", - 833: "М", - 836: "Ψ", - 885: "Ы", - 900: ( - "¤¨©ª\u00ad®´¶¼½¾ÆÐØÞæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ⅓⅔⅛⅜" - "⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧" - "⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛" - "├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽" - "◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂" - "㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄" - "㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃" - "㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLM" - "NOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩ぁあぃいぅ" - "うぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめ" - "もゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナ" - "ニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ" - ), - 917: "Ш", - 923: "Ж", - 938: "Щ", - 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", - 1000: "・ー\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851", - 1010: "Ю", - }, - "KoPubWorld돋움체 Light": { - 160: "·", - 167: "⁄", - 223: "ι", - 232: "ìíîïĩīĭįİıĵĺļłſǐỉị", - 257: "¦", - 260: "𐤟", - 280: "²³¹⁴ⁿ₁₂₃₄", - 283: "ÌÍÎÏĨĪĬĮ", - 289: "․", - 290: "\u00a0", - 294: "ˮ", - 300: "¡", - 312: "\uf09e\uf0a0", - 319: "´º", - 320: "¨", - 325: "ľ", - 335: "‖", - 341: "ŕŗřţŧ", - 349: "ŀ", - 365: "г", - 396: "τ", - 400: "•‣", - 424: "ť", - 433: "\u00ad", - 438: "к", - 440: "ζ", - 447: "εξ", - 450: "ː˛′″∂、。【】〔〕", - 451: "зźżž", - 458: "т\uf0a7", - 473: "ij", - 485: "「」■", - 486: "¿", - 500: "Ĵусхγκλν・\U000f0800\U000f0854\U000f0855", - 503: "ỷ", - 504: "ýÿŷ", - 506: "¢ªàáâãäåçāăąćĉċčķĸśŝşš", - 507: "ǎạảấầẩẫậắằẳặ", - 510: "э", - 520: "¥", - 521: "чь", - 523: "¶", - 525: "χ", - 527: "‐", - 529: "¯", - 531: "в", - 533: "£¤§«»", - 542: "япГ", - 547: "υ", - 549: "òóôõöøōŏőǒọỏốồổỗộ", - 550: "Γ", - 552: "нµ", - 555: "ĹĻĽĿŁŢŤŦŹŻŽ", - 556: "аоðерёδηθο", - 559: "ий¬", - 562: "èéêëñùúûüþđēĕėęěĝğġģĥħńņňŋũūŭůűų", - 563: "ǔǚǜẹẻẽếềểễệụủ", - 569: "ρ", - 570: "−", - 573: "цб", - 576: "βμ", - 578: "α", - 583: "лКд", - 585: "ß", - 589: "ʹ", - 600: "◦", - 601: "ŚŜŞŠ", - 604: "З", - 609: "ÈÉÊËÝĒĔĖĘĚĶŶŸ", - 610: "ΖΤ", - 611: "Т", - 616: "σ", - 618: "Σ", - 625: "ъ‒", - 635: "У", - 636: "ďơớờởỡợ", - 647: "φ", - 650: "Ξ", - 655: "Þ", - 656: "ЛБЬưứừửữự", - 661: "ʼn", - 662: "ÀÁÂÃÄÅĀĂĄ", - 664: "ÇĆĈĊČŔŖŘ", - 667: "ЁЕРХАВЧΑΒΔΕΚΛΡΥΧ", - 669: "ж", - 677: "Д", - 688: "м", - 690: "π", - 706: "©®", - 712: "ψĜĞĠĢ", - 713: "ÐĎĐ", - 718: "ÑÙÚÛÜĤĦŃŅŇŨŪŬŮŰŲ", - 719: "ЭПИЙŊы", - 722: "СЯН", - 723: "ΗΝΠ", - 740: "Ц", - 747: "Ω", - 750: "ю", - 758: "ÒÓÔÕÖØIJŌŎŐ", - 760: "Ф", - 778: "ОΘΟ", - 780: "ω", - 787: "\uf0fc", - 792: "Ъ", - 798: "Φ", - 799: "¼½¾⅓⅔⅛⅜⅝⅞", - 802: "шŵ", - 823: "фщ", - 832: "Μ", - 833: "¸М", - 836: "Ψ", - 857: "æ", - 885: "Ы", - 900: ( - "ˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆" - "⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│" - "┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆" - "╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈" - "➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰" - "㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲" - "㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<" - "=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwx" - "yz{|}~¢£¬ ̄¥₩ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはば" - "ぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジス" - "ズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵ" - "ヶ・ー" - ), - 917: "Ш", - 923: "Ж", - 938: "œЩ", - 967: "Æ", - 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", - 987: "Œ", - 990: "Ŵ", - 1000: "\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851", - 1010: "Ю", - }, - "KoPubWorld돋움체 Medium": { - 160: "·", - 167: "⁄", - 223: "ι", - 232: "ìíîïĩīĭįİıĵĺļłſǐỉị", - 257: "¦", - 260: "𐤟", - 280: "²³¹⁴ⁿ₁₂₃₄", - 283: "ÌÍÎÏĨĪĬĮ", - 289: "․", - 290: "\u00a0", - 294: "ˮ", - 300: "¡", - 312: "\uf09e\uf0a0", - 319: "´º", - 320: "¨", - 325: "ľ", - 335: "‖", - 341: "ŕŗřţŧ", - 349: "ŀ", - 365: "г", - 396: "τ", - 400: "•‣", - 424: "ť", - 433: "\u00ad", - 438: "к", - 440: "ζ", - 447: "εξ", - 450: "ː˛′″∂、。【】〔〕", - 451: "зźżž", - 458: "т\uf0a7", - 473: "ij", - 485: "「」■", - 486: "¿", - 500: "Ĵусхγκλν・\U000f0800\U000f0854\U000f0855", - 503: "ỷ", - 504: "ýÿŷ", - 506: "¢ªàáâãäåçāăąćĉċčķĸśŝşš", - 507: "ǎạảấầẩẫậắằẳặ", - 510: "э", - 520: "¥", - 521: "чь", - 523: "¶", - 525: "χ", - 527: "‐", - 529: "¯", - 531: "в", - 533: "£¤§«»", - 542: "япГ", - 547: "υ", - 549: "òóôõöøōŏőǒọỏốồổỗộ", - 550: "Γ", - 552: "нµ", - 555: "ĹĻĽĿŁŢŤŦŹŻŽ", - 556: "аоðерёδηθο", - 559: "ий¬", - 562: "èéêëñùúûüþđēĕėęěĝğġģĥħńņňŋũūŭůűų", - 563: "ǔǚǜẹẻẽếềểễệụủ", - 569: "ρ", - 570: "−", - 573: "цб", - 576: "βμ", - 578: "α", - 583: "лКд", - 585: "ß", - 589: "ʹ", - 600: "◦", - 601: "ŚŜŞŠ", - 604: "З", - 609: "ÈÉÊËÝĒĔĖĘĚĶŶŸ", - 610: "ΖΤ", - 611: "Т", - 616: "σ", - 618: "Σ", - 625: "ъ‒", - 635: "У", - 636: "ďơớờởỡợ", - 647: "φ", - 650: "Ξ", - 655: "Þ", - 656: "ЛБЬưứừửữự", - 661: "ʼn", - 662: "ÀÁÂÃÄÅĀĂĄ", - 664: "ÇĆĈĊČŔŖŘ", - 667: "ЁЕРХАВЧΑΒΔΕΚΛΡΥΧ", - 669: "ж", - 677: "Д", - 688: "м", - 690: "π", - 706: "©®", - 712: "ψĜĞĠĢ", - 713: "ÐĎĐ", - 718: "ÑÙÚÛÜĤĦŃŅŇŨŪŬŮŰŲ", - 719: "ЭПИЙŊы", - 722: "СЯН", - 723: "ΗΝΠ", - 740: "Ц", - 747: "Ω", - 750: "ю", - 758: "ÒÓÔÕÖØIJŌŎŐ", - 760: "Ф", - 778: "ОΘΟ", - 780: "ω", - 787: "\uf0fc", - 792: "Ъ", - 798: "Φ", - 799: "¼½¾⅓⅔⅛⅜⅝⅞", - 802: "шŵ", - 823: "фщ", - 832: "Μ", - 833: "¸М", - 836: "Ψ", - 857: "æ", - 885: "Ы", - 900: ( - "ˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆" - "⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│" - "┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆" - "╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈" - "➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰" - "㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲" - "㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<" - "=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwx" - "yz{|}~¢£¬ ̄¥₩ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはば" - "ぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジス" - "ズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵ" - "ヶ・ー" - ), - 917: "Ш", - 923: "Ж", - 938: "œЩ", - 967: "Æ", - 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", - 987: "Œ", - 990: "Ŵ", - 1000: "\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851", - 1010: "Ю", - }, - "KoPubWorld돋움체 Bold": { - 160: "·", - 167: "⁄", - 223: "ι", - 232: "ìíîïĩīĭįİıĵĺļłſǐỉị", - 257: "¦", - 260: "𐤟", - 280: "²³¹⁴ⁿ₁₂₃₄", - 283: "ÌÍÎÏĨĪĬĮ", - 289: "․", - 290: "\u00a0", - 294: "ˮ", - 300: "¡", - 312: "\uf09e\uf0a0", - 319: "´º", - 320: "¨", - 325: "ľ", - 335: "‖", - 341: "ŕŗřţŧ", - 349: "ŀ", - 365: "г", - 396: "τ", - 400: "•‣", - 424: "ť", - 433: "\u00ad", - 438: "к", - 440: "ζ", - 447: "εξ", - 450: "ː˛′″∂、。【】〔〕", - 451: "зźżž", - 458: "т\uf0a7", - 473: "ij", - 485: "「」■", - 486: "¿", - 500: "Ĵусхγκλν・\U000f0800\U000f0854\U000f0855", - 503: "ỷ", - 504: "ýÿŷ", - 506: "¢ªàáâãäåçāăąćĉċčķĸśŝşš", - 507: "ǎạảấầẩẫậắằẳặ", - 510: "э", - 520: "¥", - 521: "чь", - 523: "¶", - 525: "χ", - 527: "‐", - 529: "¯", - 531: "в", - 533: "£¤§«»", - 542: "япГ", - 547: "υ", - 549: "òóôõöøōŏőǒọỏốồổỗộ", - 550: "Γ", - 552: "нµ", - 555: "ĹĻĽĿŁŢŤŦŹŻŽ", - 556: "аоðерёδηθο", - 559: "ий¬", - 562: "èéêëñùúûüþđēĕėęěĝğġģĥħńņňŋũūŭůűų", - 563: "ǔǚǜẹẻẽếềểễệụủ", - 569: "ρ", - 570: "−", - 573: "цб", - 576: "βμ", - 578: "α", - 583: "лКд", - 585: "ß", - 589: "ʹ", - 600: "◦", - 601: "ŚŜŞŠ", - 604: "З", - 609: "ÈÉÊËÝĒĔĖĘĚĶŶŸ", - 610: "ΖΤ", - 611: "Т", - 616: "σ", - 618: "Σ", - 625: "ъ‒", - 635: "У", - 636: "ďơớờởỡợ", - 647: "φ", - 650: "Ξ", - 655: "Þ", - 656: "ЛБЬưứừửữự", - 661: "ʼn", - 662: "ÀÁÂÃÄÅĀĂĄ", - 664: "ÇĆĈĊČŔŖŘ", - 667: "ЁЕРХАВЧΑΒΔΕΚΛΡΥΧ", - 669: "ж", - 677: "Д", - 688: "м", - 690: "π", - 706: "©®", - 712: "ψĜĞĠĢ", - 713: "ÐĎĐ", - 718: "ÑÙÚÛÜĤĦŃŅŇŨŪŬŮŰŲ", - 719: "ЭПИЙŊы", - 722: "СЯН", - 723: "ΗΝΠ", - 740: "Ц", - 747: "Ω", - 750: "ю", - 758: "ÒÓÔÕÖØIJŌŎŐ", - 760: "Ф", - 778: "ОΘΟ", - 780: "ω", - 787: "\uf0fc", - 792: "Ъ", - 798: "Φ", - 799: "¼½¾⅓⅔⅛⅜⅝⅞", - 802: "шŵ", - 823: "фщ", - 832: "Μ", - 833: "¸М", - 836: "Ψ", - 857: "æ", - 885: "Ы", - 900: ( - "ˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆" - "⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│" - "┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆" - "╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈" - "➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰" - "㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲" - "㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<" - "=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwx" - "yz{|}~¢£¬ ̄¥₩ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはば" - "ぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジス" - "ズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵ" - "ヶ・ー" - ), - 917: "Ш", - 923: "Ж", - 938: "œЩ", - 967: "Æ", - 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", - 987: "Œ", - 990: "Ŵ", - 1000: "\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851", - 1010: "Ю", - }, - "KoPubWorld바탕체 Light": { - 160: "·", - 167: "⁄", - 223: "ι", - 260: "𐤟", - 280: "²³¹º⁴₁₂₃₄", - 282: "ĵ", - 288: "ĺļł", - 289: "․", - 290: "\u00a0", - 294: "ˮ", - 312: "¡´\uf09e\uf0a0", - 323: "ǐỉị", - 324: "ìíîïĩīĭįı", - 328: "ª", - 335: "‖", - 346: "ⁿ", - 350: "ţŧ", - 352: "ÌÍÎÏĨĪĬĮİ", - 354: "ľ", - 358: "Ĵſ", - 361: "ŀ", - 365: "г", - 396: "τ", - 400: "•‣", - 416: "¶ŕŗř", - 432: "śŝşš", - 433: "\u00ad", - 438: "к", - 440: "«»ζ", - 444: "ť", - 447: "εξ", - 450: "§ː˛′″∂、。【】〔〕", - 451: "з", - 458: "т\uf0a7", - 468: "¦¿", - 476: "źżž", - 485: "「」■", - 500: "усхγκλν・\U000f0800\U000f0854\U000f0855", - 510: "э", - 516: "ýÿŷỷ", - 521: "ьч", - 525: "χ", - 527: "‐", - 529: "¯", - 531: "в", - 532: "ŚŜŞŠ", - 533: "¤", - 536: "¢çćĉċč", - 542: "яГп", - 547: "υẹẻẽếềểễệ", - 548: "èéêëēĕėęěĝğġģ", - 550: "Γ", - 552: "ĹĻĽĿŁн", - 555: "£", - 556: "еёаорδηθο", - 558: "àáâãäåāăąǎạảấầẩẫậắằẳặ", - 559: "ий", - 562: "ĥħ", - 564: "ķ", - 569: "ρ", - 570: "−", - 573: "ðбц", - 576: "βμ", - 578: "α", - 583: "лдК", - 584: "ĸ", - 589: "ʹ", - 590: "ÈÉÊËĒĔĖĘĚ", - 592: "đ", - 600: "◦", - 601: "ß", - 603: "ǔǚǜụủ", - 604: "Зµùúûüũūŭůűų", - 606: "ij", - 610: "ΖΤ", - 611: "Т", - 612: "Þñòóôõöøńņňŋōŏőǒọỏốồổỗộ", - 616: "σ", - 618: "Σ", - 625: "ъ¬‒", - 632: "þ", - 635: "У", - 638: "ŹŻŽ", - 647: "φơớờởỡợ", - 649: "ʼn", - 650: "Ξ", - 652: "ŢŤŦ", - 656: "БЬЛưứừửữự", - 667: "ЁЕРВАЧХΑΒΔΕΚΛΡΥΧ", - 668: "ÀÁÂÃÄÅĀĂĄ", - 669: "ж", - 672: "ďŔŖŘ", - 677: "Д", - 688: "м", - 690: "π", - 706: "¥ÝŶŸ", - 708: "ÇĆĈĊČ", - 710: "IJ", - 712: "ψ", - 717: "Ŋ", - 719: "ЭыИЙП", - 722: "ЯСН", - 723: "ΗΝΠ", - 740: "ÙÚÛÜŨŪŬŮŰŲЦ", - 746: "Ķ", - 747: "Ω", - 750: "ю", - 760: "Ф", - 768: "ĜĞĠĢ", - 770: "ÐĎĐĤĦ", - 772: "ŵ", - 778: "ÑŃŅŇОΘΟ", - 780: "ω", - 787: "\uf0fc", - 792: "Ъ", - 798: "Φ", - 802: "ш", - 812: "ÒÓÔÕÖØŌŎŐ", - 823: "фщ", - 832: "Μ", - 833: "¸М", - 836: "Ψ", - 860: "æ", - 868: "œ", - 885: "Ы", - 900: ( - "¨©®¼½¾ˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵" - "∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠ" - "ⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺" - "┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼" - "❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤" - "㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦" - "㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0" - "123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkl" - "mnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - 915: "Œ", - 917: "Ш", - 923: "Ж", - 938: "Щ", - 954: "Ŵ", - 967: "Æ", - 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", - 1000: "\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851", - 1010: "Ю", - 1023: ( - "ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼ" - "ぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅ" - "テデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ・ー" - ), - }, - "KoPubWorld바탕체 Medium": { - 160: "·", - 167: "⁄", - 223: "ι", - 260: "𐤟", - 280: "²³¹º⁴₁₂₃₄", - 282: "ĵ", - 288: "ĺļł", - 289: "․", - 290: "\u00a0", - 294: "ˮ", - 312: "¡´\uf09e\uf0a0", - 323: "ǐỉị", - 324: "ìíîïĩīĭįı", - 328: "ª", - 335: "‖", - 346: "ⁿ", - 350: "ţŧ", - 352: "ÌÍÎÏĨĪĬĮİ", - 354: "ľ", - 358: "Ĵſ", - 361: "ŀ", - 365: "г", - 396: "τ", - 400: "•‣", - 416: "¶ŕŗř", - 432: "śŝşš", - 433: "\u00ad", - 438: "к", - 440: "«»ζ", - 444: "ť", - 447: "εξ", - 450: "§ː˛′″∂、。【】〔〕", - 451: "з", - 458: "т\uf0a7", - 468: "¦¿", - 476: "źżž", - 485: "「」■", - 500: "усхγκλν・\U000f0800\U000f0854\U000f0855", - 510: "э", - 516: "ýÿŷỷ", - 521: "ьч", - 525: "χ", - 527: "‐", - 529: "¯", - 531: "в", - 532: "ŚŜŞŠ", - 533: "¤", - 536: "¢çćĉċč", - 542: "яГп", - 547: "υẹẻẽếềểễệ", - 548: "èéêëēĕėęěĝğġģ", - 550: "Γ", - 552: "ĹĻĽĿŁн", - 555: "£", - 556: "еёаорδηθο", - 558: "àáâãäåāăąǎạảấầẩẫậắằẳặ", - 559: "ий", - 562: "ĥħ", - 564: "ķ", - 569: "ρ", - 570: "−", - 573: "ðбц", - 576: "βμ", - 578: "α", - 583: "лдК", - 584: "ĸ", - 589: "ʹ", - 590: "ÈÉÊËĒĔĖĘĚ", - 592: "đ", - 600: "◦", - 601: "ß", - 603: "ǔǚǜụủ", - 604: "Зµùúûüũūŭůűų", - 606: "ij", - 610: "ΖΤ", - 611: "Т", - 612: "Þñòóôõöøńņňŋōŏőǒọỏốồổỗộ", - 616: "σ", - 618: "Σ", - 625: "ъ¬‒", - 632: "þ", - 635: "У", - 638: "ŹŻŽ", - 647: "φơớờởỡợ", - 649: "ʼn", - 650: "Ξ", - 652: "ŢŤŦ", - 656: "БЬЛưứừửữự", - 667: "ЁЕРВАЧХΑΒΔΕΚΛΡΥΧ", - 668: "ÀÁÂÃÄÅĀĂĄ", - 669: "ж", - 672: "ďŔŖŘ", - 677: "Д", - 688: "м", - 690: "π", - 706: "¥ÝŶŸ", - 708: "ÇĆĈĊČ", - 710: "IJ", - 712: "ψ", - 717: "Ŋ", - 719: "ЭыИЙП", - 722: "ЯСН", - 723: "ΗΝΠ", - 740: "ÙÚÛÜŨŪŬŮŰŲЦ", - 746: "Ķ", - 747: "Ω", - 750: "ю", - 760: "Ф", - 768: "ĜĞĠĢ", - 770: "ÐĎĐĤĦ", - 772: "ŵ", - 778: "ÑŃŅŇОΘΟ", - 780: "ω", - 787: "\uf0fc", - 792: "Ъ", - 798: "Φ", - 802: "ш", - 812: "ÒÓÔÕÖØŌŎŐ", - 823: "фщ", - 832: "Μ", - 833: "¸М", - 836: "Ψ", - 860: "æ", - 868: "œ", - 885: "Ы", - 900: ( - "¨©®¼½¾ˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵" - "∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠ" - "ⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺" - "┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼" - "❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤" - "㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦" - "㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0" - "123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkl" - "mnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - 915: "Œ", - 917: "Ш", - 923: "Ж", - 938: "Щ", - 954: "Ŵ", - 967: "Æ", - 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", - 1000: "\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851", - 1010: "Ю", - 1023: ( - "ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼ" - "ぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅ" - "テデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ・ー" - ), - }, - "KoPubWorld바탕체 Bold": { - 160: "·", - 167: "⁄", - 223: "ι", - 260: "𐤟", - 280: "²³¹º⁴₁₂₃₄", - 282: "ĵ", - 288: "ĺļł", - 289: "․", - 290: "\u00a0", - 294: "ˮ", - 312: "¡´\uf09e\uf0a0", - 323: "ǐỉị", - 324: "ìíîïĩīĭįı", - 328: "ª", - 335: "‖", - 346: "ⁿ", - 350: "ţŧ", - 352: "ÌÍÎÏĨĪĬĮİ", - 354: "ľ", - 358: "Ĵſ", - 361: "ŀ", - 365: "г", - 396: "τ", - 400: "•‣", - 416: "¶ŕŗř", - 432: "śŝşš", - 433: "\u00ad", - 438: "к", - 440: "«»ζ", - 444: "ť", - 447: "εξ", - 450: "§ː˛′″∂、。【】〔〕", - 451: "з", - 458: "т\uf0a7", - 468: "¦¿", - 476: "źżž", - 485: "「」■", - 500: "усхγκλν・\U000f0800\U000f0854\U000f0855", - 510: "э", - 516: "ýÿŷỷ", - 521: "ьч", - 525: "χ", - 527: "‐", - 529: "¯", - 531: "в", - 532: "ŚŜŞŠ", - 533: "¤", - 536: "¢çćĉċč", - 542: "яГп", - 547: "υẹẻẽếềểễệ", - 548: "èéêëēĕėęěĝğġģ", - 550: "Γ", - 552: "ĹĻĽĿŁн", - 555: "£", - 556: "еёаорδηθο", - 558: "àáâãäåāăąǎạảấầẩẫậắằẳặ", - 559: "ий", - 562: "ĥħ", - 564: "ķ", - 569: "ρ", - 570: "−", - 573: "ðбц", - 576: "βμ", - 578: "α", - 583: "лдК", - 584: "ĸ", - 589: "ʹ", - 590: "ÈÉÊËĒĔĖĘĚ", - 592: "đ", - 600: "◦", - 601: "ß", - 603: "ǔǚǜụủ", - 604: "Зµùúûüũūŭůűų", - 606: "ij", - 610: "ΖΤ", - 611: "Т", - 612: "Þñòóôõöøńņňŋōŏőǒọỏốồổỗộ", - 616: "σ", - 618: "Σ", - 625: "ъ¬‒", - 632: "þ", - 635: "У", - 638: "ŹŻŽ", - 647: "φơớờởỡợ", - 649: "ʼn", - 650: "Ξ", - 652: "ŢŤŦ", - 656: "БЬЛưứừửữự", - 667: "ЁЕРВАЧХΑΒΔΕΚΛΡΥΧ", - 668: "ÀÁÂÃÄÅĀĂĄ", - 669: "ж", - 672: "ďŔŖŘ", - 677: "Д", - 688: "м", - 690: "π", - 706: "¥ÝŶŸ", - 708: "ÇĆĈĊČ", - 710: "IJ", - 712: "ψ", - 717: "Ŋ", - 719: "ЭыИЙП", - 722: "ЯСН", - 723: "ΗΝΠ", - 740: "ÙÚÛÜŨŪŬŮŰŲЦ", - 746: "Ķ", - 747: "Ω", - 750: "ю", - 760: "Ф", - 768: "ĜĞĠĢ", - 770: "ÐĎĐĤĦ", - 772: "ŵ", - 778: "ÑŃŅŇОΘΟ", - 780: "ω", - 787: "\uf0fc", - 792: "Ъ", - 798: "Φ", - 802: "ш", - 812: "ÒÓÔÕÖØŌŎŐ", - 823: "фщ", - 832: "Μ", - 833: "¸М", - 836: "Ψ", - 860: "æ", - 868: "œ", - 885: "Ы", - 900: ( - "¨©®¼½¾ˇ˘˙˚˝Ι―†‡‥‧€℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵" - "∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⋯⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠ" - "ⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺" - "┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭❌❶❷❸❹❺❻❼" - "❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓\u3000〃〓㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤" - "㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦" - "㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0" - "123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkl" - "mnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - 915: "Œ", - 917: "Ш", - 923: "Ж", - 938: "Щ", - 954: "Ŵ", - 967: "Æ", - 970: "∘∙⋅ⅪⅫ⇨⇩∎⋁╺▢▪▸►◯☑✔❍➜➭⦁⫽〇〜", - 1000: "\U000f003b\U000f02eb\U000f02ef\U000f0850\U000f0851", - 1010: "Ю", - 1023: ( - "ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼ" - "ぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅ" - "テデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ・ー" - ), - }, - "HY견명조": { - 165: "\u0387", - 512: ( - "\u00a0¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöù" - "úûüýÿ" - ), - 1024: ( - "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘΙ" - "ΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТУ" - "ФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄℉ℓ№" - "℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟" - "⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓" - "└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥" - "▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓" - "㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘" - "㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"" - "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^" - "_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - }, - "HY동녘M": { - 165: "\u0387", - 512: ( - "\u00a0¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöù" - "úûüýÿ" - ), - 1024: ( - "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝ΑΒΓΔΕΖΗΘΙ" - "ΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТУ" - "ФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё―†‡‥′″⁴ⁿ₁₂₃₄℉ℓ№" - "℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥⌒⒜⒝⒞⒟" - "⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓" - "└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▣▤▥" - "▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭\u3000、。〃【】〓〔〕㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓" - "㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘" - "㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"" - "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^" - "_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - }, - "HCI Poppy": { - 1: "¡\u302a\u302b", - 161: "˙", - 165: "\u0387", - 172: "ː", - 218: "⁏", - 232: "⁚⁝⁞", - 256: "¦", - 263: "˛", - 270: "˚", - 272: "ĺļľł", - 276: "ìíîïĩīĭįı", - 294: "Ι", - 296: "․‧", - 300: "‚‛", - 304: "ª", - 308: "ĵ", - 321: "¹", - 328: "⁴ⁿ₁₂₃₄", - 338: "ι", - 343: "‖′‵", - 346: "ÌÍÎÏĨĪĬĮİ", - 358: "¸", - 370: "ţťŧ", - 378: "‣", - 384: "º", - 386: "´˘", - 390: "¨", - 392: "²³", - 395: "ˇ", - 400: "„‟", - 402: "ŀ", - 406: "‹›", - 409: "•", - 418: "ŕŗř", - 427: "⁎", - 432: "¼½¾", - 445: "˝", - 448: "Ĵ", - 449: "‡", - 458: "τ‼", - 466: "śŝşš", - 467: "⁃", - 474: "źżž", - 475: "⁖", - 483: "⁅⁆", - 485: "″‶", - 488: "⚬", - 491: "¶", - 492: "‽", - 494: "çðćĉċč", - 497: ( - "〿。「」、ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑→" - "↓■○" - ), - 498: "§⁑", - 502: "èéêëēĕėęě", - 506: "¯", - 512: ( - "¢»¿【】〔〕〖〗〘〙〚〛・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモ" - "ヤユヨラリルレロワン゙゚ᅠ" - ), - 514: "«", - 522: "àáâãäåāăą", - 523: "₫", - 529: "₰", - 530: "её", - 532: "£òóôõöøōŏő", - 534: "⁙", - 536: "µ", - 537: "δ", - 538: "ĸ‸", - 540: "ij", - 541: "‐‑", - 544: "⁊", - 546: "ζξ⚘", - 547: "сэ", - 549: "ν", - 550: "β", - 551: "з", - 553: "х", - 554: "у", - 555: "μ", - 556: "ďđ", - 562: "ь", - 564: "⚨⚲", - 565: "ρ", - 566: "ß", - 568: "ĝğġģε⁒", - 570: "ķ", - 571: "†", - 573: "а", - 574: "¤ùúûüĥħũūŭůűųŷ", - 578: "ñńņňʼnŋ", - 580: "ýþÿκ", - 584: "¥οо₤", - 585: "б", - 586: "гт", - 587: "γ", - 590: "ÞΡ⚚", - 593: "‗", - 601: "Β", - 604: "η", - 605: "υ", - 606: "В", - 607: "θ", - 608: "‾", - 609: "₦", - 612: "ŹŻŽк", - 613: "в", - 614: "φ", - 615: "₠₪", - 616: "З", - 621: "Р₲", - 623: "Ζря‴‷₵", - 624: "ΕЁБЕ", - 627: "Γ", - 628: "₴", - 632: "χий", - 636: "ŚŜŞŠ", - 637: "Г", - 639: "⁈", - 640: "‒", - 645: "ч", - 647: "₣", - 649: "ц⁉", - 650: "⁄", - 652: "₱", - 655: "‥", - 657: "ΚЯ⁘⁛", - 660: "ĹĻĽĿŁ", - 662: "ΤТ⁋⁌⁍", - 665: "Ь", - 666: "₭", - 668: "⁗", - 670: "₮", - 671: "н", - 672: "€", - 673: "σ", - 674: "С", - 675: "⚭", - 676: "α", - 677: "ΞЭ", - 681: "лп₥", - 682: "ψ⁁₡₢", - 688: "æК", - 694: "ÈÉÊËĒĔĖĘĚ", - 697: "⁕", - 705: "Ç", - 706: "ĆĈĊČ", - 711: "⚥⚦", - 712: "Δм", - 713: "ΘΟО", - 714: "Π", - 716: "ŔŖŘ", - 717: "Ч", - 720: "ΥΧХ", - 721: "ΑА", - 724: "λ", - 726: "Ŋъ", - 727: "д", - 731: "πω", - 733: "ΗΝН", - 736: "ИЙ", - 737: "⚐⚑", - 738: "Ω", - 740: "œ", - 752: "ПЦ", - 753: "ΛЛ", - 760: "ĜĞĠĢ", - 762: "Д", - 764: "Ψ", - 765: "ΦФ", - 766: "ÐÒÓÔÕÖØĎĐŌŎŐ", - 768: "У", - 773: "Σ", - 780: "ŶŸ", - 787: "₳", - 788: "ÙÚÛÜÝŢŤŦŨŪŬŮŰŲ‿⁀", - 792: "IJ", - 796: "ÑŃŅŇ", - 798: "Ķ", - 800: "ж", - 802: "ĤĦ", - 804: "©", - 806: "®", - 808: "Ъ", - 813: "₩", - 814: "ÀÁÂÃÄÅĀĂĄю", - 815: "⁔", - 818: "⁐", - 819: "⚢", - 822: "⁓", - 825: "ы", - 829: "₨", - 841: "ΜМ", - 842: "ŵ", - 845: "шщ", - 853: "⁇", - 864: "⚩", - 882: "◸◹◺◿", - 886: "ШЩ", - 895: "Ы⚣⚤", - 896: "―", - 920: "ф⚊⚋⚌⚍⚎⚏", - 931: "⁂", - 950: "Œ", - 951: "Ж", - 954: "⚮", - 956: "Æ", - 971: "Ю", - 979: "‱", - 980: "₧", - 993: ( - "₯℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∊∋∌∍∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡∢∣∤∥" - "∦∧∨∩∪∫∬∭∮∯∰∱∲∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟≠≡" - "≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝" - "⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙" - "⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰" - "⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤" - "┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱▴▵▶▷" - "▸▹►▻▼▽▾▿◀◁◂◃◄◅◈◉◊◌◍◎◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷" - "☀☁☂☃☄☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☙☚☛☝☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂" - "♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽⚀" - "⚁⚂⚃⚄⚅⚆⚇⚈⚉✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷" - "✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❙❚❛❜❝❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻" - "❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻" - "➼➽➾、。〃〄〇〜〝〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘" - "㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝" - "㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'" - "()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abc" - "defghijklmnopqrstuvwxyz{|}~⦅⦆¢£¬ ̄¦¥₩" - ), - 1022: "¬", - 1024: "ſ⁜✀々〆〒〓〞〟", - 1036: "☜☞", - 1058: "Ŵ", - 1116: "⚯", - 1406: "◻◼◽◾☔☕☘♾♿⚒⚓⚔⚕⚖⚗⚙⚛⚜⚠⚡⚧⚪⚫⚰⚱", - }, - "HCI Hollyhock": { - 1: "¡\u302a\u302b", - 161: "˙", - 165: "\u0387", - 172: "ː", - 200: "ıľ", - 202: "ī", - 204: "į", - 206: "ĵ", - 210: "Ī", - 218: "ìíîïĺļł⁏", - 226: "ĭ", - 232: "Į⁚⁝⁞", - 238: "ÌÍÎÏ", - 242: "¦", - 244: "¹", - 246: "ĩ", - 260: "Ĭİ", - 262: "ţťŧ", - 263: "˛", - 270: "˚", - 276: "´Ĩ", - 286: "ŀ", - 294: "Ι", - 296: "․‧", - 300: "‚‛", - 318: "ŕŗř", - 328: "⁴ⁿ₁₂₃₄", - 338: "¸ι", - 343: "‖′‵", - 358: "¨", - 370: "º", - 372: "²³", - 378: "‣", - 380: "ª", - 384: "„‟", - 386: "˘", - 394: "¼½¾ij", - 395: "ˇ", - 406: "‹›", - 409: "•", - 427: "⁎", - 445: "˝", - 449: "‡", - 458: "τ‼", - 467: "⁃", - 475: "⁖", - 478: "ŷ", - 480: "ýþÿ", - 482: "ð", - 483: "⁅⁆", - 485: "″‶", - 488: "⚬", - 491: "ķ", - 492: "śŝşš‽", - 494: "¢çćĉċč", - 496: "źżž", - 497: ( - "〿。「」、ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑→" - "↓■○" - ), - 498: "»⁑", - 500: "«", - 508: "Ĵ", - 510: "ĸ", - 512: ( - "【】〔〕〖〗〘〙〚〛・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨ" - "ラリルレロワン゙゚ᅠ" - ), - 522: "¯", - 523: "₫", - 528: "¿", - 529: "₰", - 530: "её", - 534: "⁙", - 536: "Þ", - 537: "δ", - 538: "‸", - 541: "‐‑", - 542: "ñĝğġģĥńņňʼnŋ", - 544: "èéêëùúûüďđēĕėęěũūŭůűų⁊", - 546: "àáâãäåāăąζξ⚘", - 547: "сэ", - 548: "ô", - 549: "ν", - 550: "õβ", - 551: "з", - 552: "òóöøōŏő", - 553: "х", - 554: "у", - 555: "μ", - 562: "ĹĻĽĿŁь", - 564: "⚨⚲", - 565: "ρ", - 568: "ε⁒", - 571: "†", - 572: "ħ", - 573: "а", - 574: "¥µ", - 577: "¶", - 580: "κ", - 584: "οо₤", - 585: "б", - 586: "гт", - 587: "γ", - 590: "Ρ⚚", - 593: "‗", - 600: "ßŢŤŦŹŻŽ", - 601: "Β", - 604: "η", - 605: "υ", - 606: "¤В", - 607: "θ", - 608: "‾", - 609: "₦", - 612: "к", - 613: "в", - 614: "φ", - 615: "₠₪", - 616: "З", - 621: "Р₲", - 623: "Ζря‴‷₵", - 624: "£ΕЁБЕ", - 627: "Γ", - 628: "₴", - 632: "χий", - 634: "ÝŊŶŸ", - 637: "Г", - 639: "⁈", - 640: "Ķ‒", - 645: "ч", - 647: "₣", - 648: "ÀÁÂÃÄÅĀĂĄ", - 649: "ц⁉", - 650: "Ş⁄", - 652: "ŚŜŠ₱", - 655: "‥", - 657: "ΚЯ⁘⁛", - 658: "§", - 662: "ΤТ⁋⁌⁍", - 664: "ÈÉÊËĒĔĖĘĚ", - 665: "Ь", - 666: "₭", - 668: "⁗", - 670: "₮", - 671: "н", - 672: "€", - 673: "σ", - 674: "С", - 675: "⚭", - 676: "α", - 677: "ΞЭ", - 681: "лп₥", - 682: "ψ⁁₡₢", - 688: "К", - 697: "⁕", - 698: "IJ", - 702: "ĎĐ", - 705: "ÙÚÛÜŨŪŬŮŲ", - 706: "ĤĦŰ", - 708: "ÑŃŅŇŔŖŘ", - 710: "Ð", - 711: "⚥⚦", - 712: "Δм", - 713: "ΘΟО", - 714: "ŵΠ", - 716: "ÇĆĈĊČ", - 717: "Ч", - 720: "ΥΧХ", - 721: "ΑА", - 724: "λ", - 726: "ъ", - 727: "д", - 731: "πω", - 733: "ΗΝН", - 736: "ИЙ", - 737: "⚐⚑", - 738: "Ω", - 752: "ПЦ", - 753: "ΛЛ", - 762: "Д", - 764: "Ψ", - 765: "ΦФ", - 766: "ÒÓÔÕÖŌŎŐ", - 768: "У", - 770: "ĜĞĠĢ", - 773: "Σ", - 782: "©®", - 787: "₳", - 788: "‿⁀", - 800: "ж", - 806: "Ø", - 808: "Ъ", - 813: "₩", - 814: "ю", - 815: "⁔", - 818: "⁐", - 819: "⚢", - 822: "⁓", - 825: "ы", - 829: "₨", - 841: "ΜМ", - 845: "шщ", - 848: "æ", - 853: "⁇", - 864: "⚩", - 882: "◸◹◺◿", - 886: "ШЩ", - 892: "œ", - 895: "Ы⚣⚤", - 896: "―", - 920: "ф⚊⚋⚌⚍⚎⚏", - 926: "Ŵ", - 931: "⁂", - 946: "Œ", - 951: "Ж", - 954: "⚮", - 958: "¬", - 971: "Ю", - 972: "Æ", - 979: "‱", - 980: "₧", - 993: ( - "₯℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∊∋∌∍∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡∢∣∤∥" - "∦∧∨∩∪∫∬∭∮∯∰∱∲∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟≠≡" - "≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝" - "⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙" - "⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰" - "⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤" - "┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱▴▵▶▷" - "▸▹►▻▼▽▾▿◀◁◂◃◄◅◈◉◊◌◍◎◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷" - "☀☁☂☃☄☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☙☚☛☝☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂" - "♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽⚀" - "⚁⚂⚃⚄⚅⚆⚇⚈⚉✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷" - "✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❙❚❛❜❝❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻" - "❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻" - "➼➽➾、。〃〄〇〜〝〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘" - "㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝" - "㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'" - "()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abc" - "defghijklmnopqrstuvwxyz{|}~⦅⦆¢£¬ ̄¦¥₩" - ), - 1024: "ſ⁜✀々〆〒〓〞〟", - 1036: "☜☞", - 1116: "⚯", - 1406: "◻◼◽◾☔☕☘♾♿⚒⚓⚔⚕⚖⚗⚙⚛⚜⚠⚡⚧⚪⚫⚰⚱", - }, - "한양중고딕": { - 1: "\u302a\u302b", - 195: "ıľ", - 198: "ī", - 200: "į", - 201: "ĵ", - 205: "Ī", - 212: "ìíîïĺļł", - 213: "⁏", - 220: "ĭ", - 226: "Į", - 227: "⁚⁝⁞", - 233: "ÌÍÎÏ", - 237: "¦", - 239: "¹", - 240: "ĩ", - 253: "Ĭİ", - 255: "ţťŧ", - 270: "´Ĩ", - 279: "ŀ", - 292: "‚‛", - 310: "ŕŗř", - 312: "˙", - 313: "·˚˛\uf09e\uf0a0", - 330: "¸", - 350: "¨", - 361: "º", - 363: "²", - 364: "³", - 371: "ª", - 375: "ˇ˘Ι„‟", - 384: "¼½", - 385: "¾ij\uf0fa", - 398: "ι", - 417: "⁎", - 438: "˝ζξ", - 457: "с", - 458: "\uf027\uf073\uf09f\uf0a7", - 463: "⁖", - 464: "з", - 466: "ŷ", - 468: "ÿ", - 469: "ýþ", - 470: "ð", - 477: "⚬", - 478: "ķ", - 480: "śŝşš", - 483: "¢çćĉċč\uf0f9", - 485: ( - "źżžε〿ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑→" - "↓○" - ), - 486: "υ⁑", - 487: "»", - 488: "«", - 497: "Ĵ", - 498: "ĸ", - 500: ( - "ао‧▮▯◤◥❙❚〖〗〘〙。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマ" - "ミムメモヤユヨラリルレロワン゙゚ᅠ\uf07f" - ), - 506: "э", - 509: "¯", - 511: "₫", - 515: "¿", - 517: "₰", - 520: "⁙", - 521: "р", - 522: "ρ", - 524: "Þ", - 526: "τ", - 529: "ñĝğġģĥńņňʼnŋ", - 531: "ùúûüďđũūŭůűų⁊\uf07d\uf07e", - 532: "èéêëēĕėęě", - 533: "⚘", - 534: "àáâãäåāăą", - 535: "ô", - 537: "З", - 538: "õ", - 539: "óöøōŏő", - 540: "ò", - 542: "δμοσеё", - 544: "α", - 547: "ν", - 548: "я", - 549: "ĹĻĽĿŁ₤\uf047\uf048", - 551: "⚨⚲", - 554: "\uf035", - 555: "⁒", - 556: "г", - 559: "ħ", - 560: "¥", - 561: "µ", - 562: "¶γ", - 563: "κх", - 565: "π", - 574: "б", - 576: "⚚", - 577: "у", - 578: "\uf077", - 580: "ь", - 585: "ßŹŻŽ", - 586: "ŢŤŦ", - 587: "\uf041", - 592: "¤", - 593: "ч", - 594: "в", - 595: "₦", - 601: "₠₪", - 603: "Ξ\uf036", - 605: "к", - 606: "₲", - 608: "₵", - 609: "£Ρ", - 610: "Γ", - 612: "Р", - 613: "₴", - 616: "Ь", - 617: "т", - 619: "ÝŊŶŸ", - 623: "η", - 624: "⁈", - 625: "ĶΖλωГ₣", - 626: "χ", - 632: "ÀÁÂÃÄÅĀĂĄ", - 634: "⁉", - 635: "Ş", - 636: "ŚŜŠ\uf0fb", - 637: "₱", - 640: "и", - 641: "⁘⁛", - 643: "§", - 645: "н", - 646: "⁋⁌⁍", - 649: "ÈÉÊËĒĔĖĘĚ", - 650: "Ч₭", - 651: "\uf053", - 652: "⁗", - 654: "Ββ₮", - 658: "Δ₧", - 659: "⚭", - 660: "\uf04e", - 661: "φ", - 662: "п", - 665: "₥", - 666: "₡₢", - 667: "ΕΥЁБВЕСЭЯ", - 670: "д", - 674: "\uf043\uf044", - 680: "⁕", - 681: "IJ", - 684: "ΧХ", - 686: "ĎĐц", - 688: "ÙÚÛÜŨŪŬŮŲъ", - 689: "ĤĦ", - 690: "Űψф", - 692: "ÑŃŅŇŔŖŘУ", - 693: "Ð\uf058", - 694: "⚥⚦", - 697: "ŵ", - 699: "ÇĆĈĊČ", - 700: "Πл\uf032\uf033", - 708: "ΘΟθО", - 711: "Т", - 716: "Τ", - 717: "Ω", - 720: "⚐⚑", - 723: "\uf057", - 736: "ΦЛФ", - 741: "Ψ", - 747: "\uf055\uf056\uf06c\uf06e\uf074", - 749: "ÒÓÔÕÖŌŎŐ", - 750: "ΑΗΚΛΝАИЙН►◄", - 751: "ĜĞĠĢ", - 762: "ж", - 764: "©®", - 769: "₳", - 770: "м", - 774: "♦", - 776: "\uf0e3\uf0e4\uf0e5\uf0e6", - 780: "П\uf069", - 781: "Σ", - 783: "\uf0f5\uf0f6\uf0f7\uf0f8", - 787: "Ø\uf0fc", - 793: "\uf042", - 794: "Д\uf059\uf0d7\uf0d8", - 795: "Ъ", - 796: "⁔", - 798: "ю", - 799: "⁐⚢", - 801: "Ц", - 802: "⁓", - 810: "₨", - 811: "\uf0f1\uf0f2\uf0f4", - 813: "К\uf054", - 829: "æ", - 833: "⁇", - 843: "\uf04a\uf04b\uf04c", - 844: "⚩", - 849: "\uf04f", - 861: "◸◹◺◿", - 872: "œ", - 873: "\uf0eb\uf0ec\uf0ed\uf0ee", - 874: "⚣⚤", - 875: "шы", - 880: "\uf052", - 885: "\uf05a", - 887: "\uf051", - 890: "щ", - 891: "\uf03b\uf03e\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0", - 893: "\uf029\uf034\uf03c\uf03d\uf049\uf05b\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0fd\uf0fe", - 894: "\uf025", - 896: "\uf05c", - 898: "⚊⚋⚌⚍⚎⚏", - 900: "Ы", - 904: "Ŵ", - 911: "\uf03f\uf040", - 912: "ΜМ", - 924: "Œ", - 929: "\uf066", - 932: "⚮", - 933: "\uf063", - 936: "¬", - 940: "\uf03a\uf062", - 943: "\uf045\uf046", - 947: "\uf038\uf064", - 950: "Æ", - 953: "\uf06d\uf0a6", - 963: "\uf060", - 970: ( - "₯∊∍≛⋍⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿▢▭▰▻◅◌◍◖◗◚◛◠◡◢◣◧◨◩◪◫◬◭◮◰◱◲◳◴◵◶◷☀☉☊☋☌☍☐☓☖☗" - "☙☚☛☠☡☣☤☥☦☧☩☪☫☬☭☸☹☾☿♁♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♢♰♱♲♳♴♵♶♷♸♹" - "♺♻♼♽⚀⚁⚂⚃⚄⚅⚆⚇⚈⚉✁✃✄✆✇✈✌✍✎✏✐✑✒✓✕✖✘✙✚✛✜✞✟✠✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸" - "✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❛❜❝❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❿➀➁➂➃➄➅➆➇" - "➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➝➞➟➠➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻➼➽➾〝〠〡〢〣〤〥〦〧〨〩" - "〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾⦅⦆¦" - ), - 980: "\uf0df\uf0e0", - 987: "\uf075", - 1000: ( - "¡ſːЖШЩЮй‐‑‒―‖‗†‡•‣․‥‱′″‴‵‶‷‸‹›‼‽‾‿⁀⁁⁂⁃⁄⁅⁆⁜⁴ⁿ₁₂₃₄₩€℉ℓ№℡™ΩÅ⅓⅔⅛" - "⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∋∌∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡∢∣∤∥∦∧∨∩∪∫∬∭∮∯∰∱∲" - "∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≜≝≞≟≠≡≢≣≤≥≦≧≨≩≪≫≬≭≮≯" - "≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫" - "⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨" - "⋩⋪⋫⋬⋭⋮⋯⋰⋱⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧ" - "ⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁" - "╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▪▫▬▱▴▵▶▷▸▹▼▽▾▿◀◁◂◃◈◉◊◎◐◑◒◓◔◕◘◙◜◝◞◟◦◯☁☂☃☄☇☈" - "☎☏☑☒☜☝☞☟☢☨☮☯☰☱☲☳☴☵☶☷☺☻☼☽♀♂♠♡♣♤♥♧♨♩♪♫♬♭♮♯✀✂✉✔✗✝✡❶❷❸❹❺❻❼❽❾➜➡、。" - "〃〄々〆〇【】〒〓〔〕〚〛〜〞〟㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮" - "㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰" - "㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:" - ";<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuv" - "wxyz{|}~¢£¬ ̄¥₩■\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4" - ), - 1025: "\uf065", - 1031: "\uf021", - 1036: "\uf0ff", - 1047: "\uf0c7\uf0c8\uf0c9\uf0ca", - 1051: "\uf06a", - 1054: "\uf05f", - 1060: "\uf078\uf079\uf0f3", - 1065: "\uf068", - 1067: "\uf0e7\uf0e8", - 1073: "\uf037", - 1078: "\uf039", - 1083: "\uf028", - 1089: "⚯\uf050", - 1091: "\uf061", - 1096: "\uf030\uf067", - 1111: "\uf04d", - 1133: "\uf02a\uf02b", - 1145: "\uf022", - 1156: "\uf05e", - 1171: "\uf02c\uf02d", - 1216: "\uf026", - 1253: "\uf0d5\uf0d6", - 1271: "\uf06b", - 1300: "\uf023", - 1373: "◻◼◽◾☔☕☘♾♿⚒⚓⚔⚕⚖⚗⚙⚛⚜⚠⚡⚧⚪⚫⚰⚱", - }, - "한양신명조": { - 1: "\u302a\u302b", - 213: "⁏", - 227: "⁚⁝⁞", - 250: "¦", - 265: "ĺļľł", - 269: "ìíîïĩīĭįı", - 292: "‚‛", - 297: "ª", - 301: "ĵ", - 312: "˙", - 313: "·¹˚˛\uf09e\uf0a0", - 337: "ÌÍÎÏĨĪĬĮİ", - 350: "¸", - 361: "ţťŧ", - 375: "ºˇ˘Ι", - 376: "´", - 380: "¨", - 383: "²³", - 385: "\uf0fa", - 390: "„‟", - 393: "ŀ", - 398: "ι", - 409: "ŕŗř", - 417: "⁎", - 421: "¼½¾", - 438: "Ĵ˝ζξ", - 455: "śŝşš", - 457: "с", - 458: "\uf027\uf073\uf09f\uf0a7", - 463: "źżž⁖", - 464: "з", - 477: "⚬", - 479: "¶", - 482: "çðćĉċč", - 483: "\uf0f9", - 485: "ε〿ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑→↓○", - 486: "§υ⁑", - 490: "èéêëēĕėęě", - 494: "¯", - 500: ( - "¢»¿ао‧▮▯◤◥❙❚〖〗〘〙。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフ" - "ヘホマミムメモヤユヨラリルレロワン゙゚ᅠ\uf07f" - ), - 501: "«", - 506: "э", - 509: "àáâãäåāăą", - 511: "₫", - 517: "₰", - 519: "òóôõöøōŏő", - 520: "£⁙", - 521: "р", - 522: "ρ", - 523: "µ", - 525: "ĸ", - 526: "τ", - 528: "ij", - 531: "⁊\uf07d\uf07e", - 533: "⚘", - 537: "З", - 542: "δμοσеё", - 543: "ďđ", - 544: "α", - 547: "ν", - 548: "я", - 549: "₤\uf047\uf048", - 551: "⚨⚲", - 553: "ß", - 554: "ĝğġģ\uf035", - 555: "⁒", - 556: "г", - 557: "ķ", - 560: "ùúûüĥħũūŭůűų", - 561: "¤ŷ", - 562: "γ", - 563: "κх", - 564: "ñńņňʼnŋ", - 565: "π", - 566: "ýþÿ", - 571: "¥", - 574: "б", - 576: "Þ⚚", - 577: "у", - 578: "\uf077", - 580: "ь", - 587: "\uf041", - 593: "ч", - 594: "в", - 595: "₦", - 597: "ŹŻŽ", - 601: "₠₪", - 603: "Ξ\uf036", - 605: "к", - 606: "₲", - 608: "₵", - 609: "Ρ", - 610: "Γ", - 612: "Р", - 613: "₴", - 616: "Ь", - 617: "т", - 622: "ŚŜŞŠ", - 623: "η", - 624: "⁈", - 625: "ΖλωГ₣", - 626: "χ", - 634: "⁉", - 636: "\uf0fb", - 637: "₱", - 640: "и", - 641: "⁘⁛", - 645: "ĹĻĽĿŁн", - 646: "⁋⁌⁍", - 650: "Ч₭", - 651: "\uf053", - 652: "⁗", - 654: "Ββ₮", - 658: "Δ₧", - 659: "⚭", - 660: "\uf04e", - 661: "φ", - 662: "п", - 665: "₥", - 666: "₡₢", - 667: "ΕΥЁБВЕСЭЯ", - 670: "д", - 672: "æ", - 674: "\uf043\uf044", - 677: "ÈÉÊËĒĔĖĘĚ", - 680: "⁕", - 684: "ΧХ", - 686: "ц", - 687: "Ç", - 688: "ъ", - 690: "ĆĈĊČψф", - 692: "У", - 693: "\uf058", - 694: "⚥⚦", - 700: "ŔŖŘΠл\uf032\uf033", - 708: "ΘΟθО", - 709: "Ŋ", - 711: "Т", - 716: "Τ", - 717: "Ω", - 720: "⚐⚑", - 723: "œ\uf057", - 736: "ΦЛФ", - 741: "Ψ", - 742: "ĜĞĠĢ", - 747: "\uf055\uf056\uf06c\uf06e\uf074", - 748: "ÒÓÔÕÖØŌŎŐ", - 749: "ÐĎĐ", - 750: "ΑΗΚΛΝАИЙН►◄", - 762: "ŶŸж", - 769: "₳", - 770: "ÙÚÛÜÝŢŤŦŨŪŬŮŰŲм", - 774: "IJ♦", - 776: "\uf0e3\uf0e4\uf0e5\uf0e6", - 777: "ÑŃŅŇ", - 780: "ĶП\uf069", - 781: "Σ", - 783: "\uf0f5\uf0f6\uf0f7\uf0f8", - 784: "ĤĦ", - 785: "©", - 787: "\uf0fc", - 788: "®", - 793: "\uf042", - 794: "ÀÁÂÃÄÅĀĂĄД\uf059\uf0d7\uf0d8", - 795: "Ъ", - 796: "⁔", - 798: "ю", - 799: "⁐⚢", - 801: "Ц", - 802: "⁓", - 810: "₨", - 811: "\uf0f1\uf0f2\uf0f4", - 813: "К\uf054", - 823: "ŵ", - 833: "⁇", - 843: "\uf04a\uf04b\uf04c", - 844: "⚩", - 849: "\uf04f", - 861: "◸◹◺◿", - 873: "\uf0eb\uf0ec\uf0ed\uf0ee", - 874: "⚣⚤", - 875: "шы", - 880: "\uf052", - 885: "\uf05a", - 887: "\uf051", - 890: "щ", - 891: "\uf03b\uf03e\uf05d\uf06f\uf070\uf071\uf072\uf076\uf07a\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0e1\uf0e2\uf0e9\uf0ea\uf0ef\uf0f0", - 893: "\uf029\uf034\uf03c\uf03d\uf049\uf05b\uf07b\uf07c\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf0fd\uf0fe", - 894: "\uf025", - 896: "\uf05c", - 898: "⚊⚋⚌⚍⚎⚏", - 900: "Ы", - 911: "\uf03f\uf040", - 912: "ΜМ", - 927: "Œ", - 929: "\uf066", - 932: "⚮", - 933: "\uf063", - 934: "Æ", - 940: "\uf03a\uf062", - 943: "\uf045\uf046", - 947: "\uf038\uf064", - 953: "\uf06d\uf0a6", - 963: "\uf060", - 970: ( - "₯∊∍≛⋍⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿▢▭▰▻◅◌◍◖◗◚◛◠◡◢◣◧◨◩◪◫◬◭◮◰◱◲◳◴◵◶◷☀☉☊☋☌☍☐☓☖☗" - "☙☚☛☠☡☣☤☥☦☧☩☪☫☬☭☸☹☾☿♁♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♢♰♱♲♳♴♵♶♷♸♹" - "♺♻♼♽⚀⚁⚂⚃⚄⚅⚆⚇⚈⚉✁✃✄✆✇✈✌✍✎✏✐✑✒✓✕✖✘✙✚✛✜✞✟✠✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸" - "✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❛❜❝❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❿➀➁➂➃➄➅➆➇" - "➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➝➞➟➠➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻➼➽➾〝〠〡〢〣〤〥〦〧〨〩" - "〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾⦅⦆¦" - ), - 980: "\uf0df\uf0e0", - 987: "\uf075", - 999: "¬", - 1000: ( - "¡ſːЖШЩЮй‐‑‒―‖‗†‡•‣․‥‱′″‴‵‶‷‸‹›‼‽‾‿⁀⁁⁂⁃⁄⁅⁆⁜⁴ⁿ₁₂₃₄₩€℉ℓ№℡™ΩÅ⅓⅔⅛" - "⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∋∌∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡∢∣∤∥∦∧∨∩∪∫∬∭∮∯∰∱∲" - "∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≜≝≞≟≠≡≢≣≤≥≦≧≨≩≪≫≬≭≮≯" - "≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫" - "⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨" - "⋩⋪⋫⋬⋭⋮⋯⋰⋱⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧ" - "ⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁" - "╂╃╄╅╆╇╈╉╊╋▒▣▤▥▦▧▨▩▪▫▬▱▴▵▶▷▸▹▼▽▾▿◀◁◂◃◈◉◊◎◐◑◒◓◔◕◘◙◜◝◞◟◦◯☁☂☃☄☇☈" - "☎☏☑☒☜☝☞☟☢☨☮☯☰☱☲☳☴☵☶☷☺☻☼☽♀♂♠♡♣♤♥♧♨♩♪♫♬♭♮♯✀✂✉✔✗✝✡❶❷❸❹❺❻❼❽❾➜➡、。" - "〃〄々〆〇【】〒〓〔〕〚〛〜〞〟㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮" - "㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰" - "㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:" - ";<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuv" - "wxyz{|}~¢£¬ ̄¥₩■\uf020\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4" - ), - 1025: "\uf065", - 1031: "\uf021", - 1034: "Ŵ", - 1036: "\uf0ff", - 1047: "\uf0c7\uf0c8\uf0c9\uf0ca", - 1051: "\uf06a", - 1054: "\uf05f", - 1060: "\uf078\uf079\uf0f3", - 1065: "\uf068", - 1067: "\uf0e7\uf0e8", - 1073: "\uf037", - 1078: "\uf039", - 1083: "\uf028", - 1089: "⚯\uf050", - 1091: "\uf061", - 1096: "\uf030\uf067", - 1111: "\uf04d", - 1133: "\uf02a\uf02b", - 1145: "\uf022", - 1156: "\uf05e", - 1171: "\uf02c\uf02d", - 1216: "\uf026", - 1253: "\uf0d5\uf0d6", - 1271: "\uf06b", - 1300: "\uf023", - 1373: "◻◼◽◾☔☕☘♾♿⚒⚓⚔⚕⚖⚗⚙⚛⚜⚠⚡⚧⚪⚫⚰⚱", - }, - "한양견고딕": { - 3: "\u302a\u302b", - 644: "˙", - 660: "\u0387", - 689: "ː", - 799: "ıľ", - 813: "ī", - 820: "į", - 824: "ĵ", - 840: "Ī", - 869: "ìíîïĺļł", - 873: "⁏", - 902: "ĭ", - 925: "Į", - 930: "⁚⁝⁞", - 955: "ÌÍÎÏ", - 971: "¦", - 979: "¹", - 983: "ĩ", - 1037: "Ĭİ", - 1045: "ţťŧ", - 1053: "˛", - 1082: "˚", - 1107: "´Ĩ", - 1143: "ŀ", - 1176: "Ι", - 1184: "․‧", - 1196: "‚‛", - 1271: "ŕŗř", - 1311: "⁴ⁿ₁₂₃₄", - 1353: "¸ι", - 1373: "‖′‵", - 1435: "¨", - 1479: "º", - 1487: "²", - 1491: "³", - 1512: "‣", - 1520: "ª", - 1536: "„‟", - 1545: "˘", - 1573: "¼½", - 1577: "¾ij", - 1581: "ˇ", - 1622: "‹›", - 1635: "•", - 1708: "⁎", - 1782: "˝", - 1796: "‡", - 1831: "τ‼", - 1868: "⁃", - 1901: "⁖", - 1908: "ŷ", - 1917: "ÿ", - 1921: "ýþ", - 1927: "ð", - 1934: "⁅⁆", - 1941: "″‶", - 1954: "⚬", - 1959: "ķ", - 1967: "śŝşš‽", - 1979: "¢çćĉċč", - 1987: ( - "źżž〿。「」、ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│" - "←↑→↓■○" - ), - 1992: "⁑", - 1995: "»", - 1999: "«", - 2036: "Ĵ", - 2041: "ĸ", - 2048: ( - "【】〔〕〖〗〘〙〚〛・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨ" - "ラリルレロワン゙゚ᅠ" - ), - 2053: "¡", - 2085: "¯", - 2094: "₫", - 2110: "¿", - 2118: "₰", - 2121: "её", - 2134: "⁙", - 2147: "Þδ", - 2151: "‸", - 2163: "‐‑", - 2167: "ñĝğġģĥńņňʼnŋ", - 2175: "ùúûüďđũūŭůűų⁊", - 2180: "èéêëēĕėęě", - 2184: "ζξ⚘", - 2189: "àáâãäåāăąсэ", - 2192: "ô", - 2196: "ν", - 2200: "β", - 2205: "õз", - 2208: "óöøōŏő", - 2212: "òх", - 2216: "у", - 2219: "μ", - 2249: "ĹĻĽĿŁь", - 2257: "⚨⚲", - 2261: "ρ", - 2274: "ε⁒", - 2285: "†", - 2290: "ħ", - 2294: "¥а", - 2298: "µ", - 2301: "¶", - 2320: "κ", - 2336: "οо₤", - 2339: "б", - 2343: "гт", - 2347: "γ", - 2360: "Ρ⚚", - 2372: "‗", - 2397: "ßŹŻŽ", - 2400: "ŢŤŦ", - 2405: "Β", - 2416: "η", - 2421: "υ", - 2425: "¤В", - 2429: "θ", - 2432: "‾", - 2438: "₦", - 2449: "к", - 2454: "в", - 2458: "φ", - 2462: "₠₪", - 2465: "З", - 2484: "Р₲", - 2491: "Ζря‴‷₵", - 2495: "£ΕЁБЕ", - 2507: "Γ", - 2511: "₴", - 2528: "χий", - 2536: "ÝŊŶŸ", - 2549: "Г", - 2556: "⁈", - 2560: "Ķ‒", - 2580: "ч", - 2589: "ÀÁÂÃÄÅĀĂĄ₣", - 2596: "ц⁉", - 2601: "Ş⁄", - 2606: "ŚŜŠ", - 2610: "₱", - 2622: "‥", - 2629: "ΚЯ⁘⁛", - 2634: "§", - 2648: "ΤТ⁋⁌⁍", - 2659: "ÈÉÊËĒĔĖĘĚЬ", - 2664: "₭", - 2671: "⁗", - 2680: "₮", - 2683: "н", - 2687: "€", - 2692: "σ", - 2697: "С", - 2700: "⚭", - 2704: "α", - 2708: "ΞЭ", - 2724: "лп₥", - 2729: "ψ⁁₡₢", - 2753: "К", - 2790: "IJ⁕", - 2809: "ĎĐ", - 2818: "ÙÚÛÜŨŪŬŮŲ", - 2823: "ĤĦ", - 2828: "Ű", - 2835: "ÑŃŅŇŔŖŘ", - 2839: "Ð", - 2844: "⚥⚦", - 2847: "Δм", - 2851: "ΘΟО", - 2855: "ŵΠ", - 2864: "ÇĆĈĊČ", - 2868: "Ч", - 2880: "ΥΧХ", - 2884: "ΑА", - 2896: "λ", - 2905: "ъ", - 2908: "д", - 2924: "πω", - 2933: "ΗΝН", - 2945: "ИЙ", - 2950: "⚐⚑", - 2954: "Ω", - 3008: "ПЦ", - 3011: "ΛЛ", - 3048: "Д", - 3057: "Ψ", - 3060: "ΦФ", - 3068: "ÒÓÔÕÖŌŎŐ", - 3073: "У", - 3077: "ĜĞĠĢ", - 3093: "Σ", - 3130: "©®", - 3150: "₳", - 3153: "‿⁀", - 3199: "ж", - 3224: "Ø", - 3232: "Ъ", - 3252: "₩", - 3257: "ю", - 3261: "⁔", - 3273: "⁐", - 3277: "⚢", - 3290: "⁓", - 3301: "ы", - 3317: "₨", - 3363: "ΜМ", - 3380: "шщ", - 3396: "æ", - 3412: "⁇", - 3457: "⚩", - 3527: "◸◹◺◿", - 3543: "ШЩ", - 3572: "œ", - 3581: "Ы⚣⚤", - 3584: "―", - 3680: "ф⚊⚋⚌⚍⚎⚏", - 3703: "Ŵ", - 3724: "⁂", - 3785: "Œ", - 3806: "Ж", - 3818: "⚮", - 3834: "¬", - 3883: "Ю", - 3893: "Æ", - 3916: "‱", - 3920: "₧", - 3973: ( - "₯℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∁∂∃∄∅∆∇∈∉∊∋∌∍∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡∢∣∤∥" - "∦∧∨∩∪∫∬∭∮∯∰∱∲∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟≠≡" - "≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝" - "⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙" - "⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰" - "⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤" - "┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋▒▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱▴▵▶▷" - "▸▹►▻▼▽▾▿◀◁◂◃◄◅◈◉◊◌◍◎◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷" - "☀☁☂☃☄☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☙☚☛☝☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂" - "♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽⚀" - "⚁⚂⚃⚄⚅⚆⚇⚈⚉✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷" - "✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❙❚❛❜❝❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻" - "❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻" - "➼➽➾、。〃〄〇〜〝〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘" - "㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝" - "㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'" - "()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abc" - "defghijklmnopqrstuvwxyz{|}~⦅⦆¢£¬ ̄¦¥₩" - ), - 4096: "ſ⁜✀々〆〒〓〞〟", - 4146: "☜☞", - 4464: "⚯", - 5624: "◻◼◽◾☔☕☘♾♿⚒⚓⚔⚕⚖⚗⚙⚛⚜⚠⚡⚧⚪⚫⚰⚱", - }, - "휴먼옛체": { - 1: "\u302a\u302b", - 164: "\u0387", - 228: "ι", - 256: "¦", - 276: "‚‛", - 284: "Ι", - 296: "․‧⁚", - 298: "ìíîïįĵĺļ⁏⁝⁞", - 344: "‖‵", - 360: "ĩīĭ", - 374: "г", - 378: "‣", - 380: "„‟", - 384: "¯ÌÍÎÏĨĪĬĮİţſ", - 394: "ľ", - 404: "τ", - 406: "‹›", - 408: "•", - 426: "ŕŗř", - 448: "к", - 452: "ζ", - 456: "ε", - 458: "ξ‼", - 466: "⁃", - 470: "Ĵзт", - 482: "źżž", - 484: "⁅⁆", - 486: "‶", - 492: "‽", - 496: ( - "ť〿。「」、ᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ│←↑" - "→↓■○" - ), - 498: "⁎⁑", - 512: ( - "¢£«»àáâãäåāăąćĉċčśŝşšγκλνсух〖〗〘〙〚〛・ヲァィゥェォャュョッーアイウエオカキクケコサシスセ" - "ソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚ᅠ" - ), - 522: "э", - 524: "₫", - 530: "₰", - 532: "ç", - 534: "чь", - 538: "χ‸", - 540: "‐‑", - 544: "в⁊", - 550: "⁖", - 554: "µèéêëñòóôõöùúûüēĕėęěĝğġģĥķńņňōŏőũūŭůűųГпя", - 560: "υ", - 564: "Γ", - 566: "н", - 568: "⁒", - 570: "δηθοаеорё", - 572: "ий⁕", - 582: "ρ", - 584: "₤", - 586: "бц⁗", - 590: "βμ", - 592: "α‗", - 596: "К", - 598: "ýÿŷдл", - 608: "‾", - 610: "₦", - 616: "₠₪", - 619: "З⁙", - 620: "₲", - 622: "‴‷₵", - 626: "ΖΤТ", - 628: "₴", - 632: "σ", - 634: "Σ", - 638: "⁈⁘", - 640: "ĹĻĽŚŜŞŠŹŻŽъ‒", - 648: "₣", - 650: "У⁄⁉", - 652: "₱", - 662: "⁋⁌⁍", - 664: "φ", - 666: "Ξ₭", - 670: "₮", - 672: "БЛЬ€", - 680: "₥", - 682: "¥ÈÉÊËÝĆĈĊČĒĔĖĘĚŔŖŘŶŸЧ⁁₡₢", - 684: "ΑΒΔΕΚΛΡΥΧЁАВЕРХ", - 686: "ж", - 690: "Ç", - 694: "ďД", - 700: "⁛", - 705: "м⁓", - 706: "π", - 726: "ÒÓÔÕÖĎĐĜĞĠĢŌŎŐ", - 730: "ψ", - 736: "ИЙПЭы", - 740: "ΗΝΠНСЯ", - 758: "Ц", - 766: "Ω", - 768: "ÀÁÂÃÄÅÑÙÚÛÜĀĂĄĤĶŃŅŇŢŤŨŪŬŮŰŲю", - 778: "Ф", - 788: "‿⁀⁔⁜₳", - 796: "ΘΟО", - 800: "ω", - 802: "©®", - 804: "¬", - 810: "ŵЪ", - 814: "₩", - 818: "Φ⁐", - 822: "ш", - 830: "₨", - 842: "фщ", - 854: "ΜМ", - 856: "Ψ", - 900: "⁇", - 906: "Ы", - 930: "⁂", - 938: "Ш", - 946: "Ж", - 960: "Щ", - 978: "‱", - 980: "₧", - 982: "Ŵ", - 994: ( - "₯∁∄∅∆∉∊∌∍∎∐−∓∔∕∖∗∘∙∛∜∟∡∢∣∤∦∭∯∰∱∲∳∶∷∸∹∺∻∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≓" - "≔≕≖≗≘≙≚≛≜≝≞≟≢≣≦≧≨≩≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊄⊅⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊚" - "⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗" - "⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿▢▪▫▬▭▮▯▰▱▴▵▸▹►▻▾▿◂◃◄" - "◅◉◊◌◍◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷◸◹◺◻◼◽◾◿☀☁☂☃☄☇☈☉☊" - "☋☌☍☐☑☒☓☔☕☖☗☘☙☚☛☝☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♁♃♄♅♆♇♈♉♊♋♌" - "♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♢♦♫♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚇⚈⚉⚊⚋⚌⚍⚎⚏⚐⚑⚒⚓" - "⚔⚕⚖⚗⚘⚙⚚⚛⚜⚠⚡⚢⚣⚤⚥⚦⚧⚨⚩⚪⚫⚬⚭⚮⚯⚰⚱⚲✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣" - "✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❘❙❚❛❜❝❞❡❢❣❤❥❦❧❨" - "❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧" - "➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻➼➽➾〄〇〜〝〠〡〢〣〤〥〦〧〨〩〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾⦅⦆¦" - ), - 1024: ( - "¡¤§¨ª²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧˇː˘˙˚˛˝―†‡‥′″⁴ⁿ₁₂" - "₃₄℉ℓ№℡™ΩÅ⅓⅔⅛⅜⅝⅞↔↕↖↗↘↙⇒⇔∀∂∃∇∈∋∏∑√∝∞∠∥∧∨∩∪∫∬∮∴∵∼∽≒≠≡≤≥≪≫⊂⊃⊆⊇⊙⊥" - "⌒⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ─━│┃┌┍┎" - "┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊" - "╋▒▣▤▥▦▧▨▩▶▷▼▽◀◁◈◎◐◑☎☏☜☞♀♂♠♡♣♤♥♧♨♩♪♬♭✀、。〃々〆【】〒〓〔〕〞〟㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉" - "㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉿㎀㎁㎂㎃㎄㎈㎉㎊㎋㎌㎍㎎" - "㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊" - "㏏㏐㏓㏖㏘㏛㏜㏝!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRST" - "UVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¬ ̄¥₩" - ), - 1034: "Ю", - }, - "Times New Roman": { - 342: "⁄∕", - 410: "¦", - 448: "′‵", - 512: "\u00a0‧∙", - 551: "ίι", - 561: "∫", - 565: "ª", - 569: "ìíîïĩīĭįıĵĺļłţŧſ", - 575: "‖", - 614: "²³¹⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", - 635: "º", - 682: "¡¨\u00ad´¸ÌÍÎÏĨĪĬĮİŕŗřΙΪ‐‑‚‛․‹›‾", - 704: "ŀ", - 717: "•‣", - 797: "Ĵśŝşš", - 811: "ς", - 823: "τ", - 832: "ľ", - 848: "ζ", - 853: "″‴", - 860: "έε", - 875: "ť", - 905: "γ", - 909: "¿àáâãäåçèéêëāăąćĉċčēĕėęěźżžχ„‟", - 913: "ξ", - 926: "ν", - 928: "¶", - 965: "δ", - 981: "θ", - 993: "λ", - 1012: "◊", - 1013: "ŋ", - 1014: "ΰυ", - 1022: "ρ", - 1024: "¢£¤¥§«¯»ßðñòóôõöøùúûüýþÿđĝğġģĥħķĸńņňōŏőũūŭůűųŷο‒‗†‡€", - 1032: "κ", - 1034: "π", - 1042: "β", - 1071: "ήη", - 1073: "άα", - 1098: "μ", - 1104: "σ", - 1124: "√≈≠≤≥", - 1131: "ij", - 1139: "ÞŚŜŞŠΡfifl", - 1155: "¬−≡", - 1173: "‼", - 1180: "µ", - 1182: "φ", - 1184: "Γ", - 1192: "Σ", - 1229: "℮", - 1237: "ʼn", - 1251: "ÈÉÊËĒĔĖĘĚĹĻĽĿŁŢŤŦŹŻŽΕΖΤ", - 1282: "ψ", - 1317: "ΔΞ", - 1324: "ď", - 1348: "ω", - 1364: "‥", - 1366: "ÇæĆĈĊČŔŖŘΒ", - 1437: "Ŋ", - 1451: "IJ", - 1460: "∞", - 1479: "ÀÁÂÃÄÅÐÑÒÓÔÕÖØÙÚÛÜÝĀĂĄĎĐĜĞĠĢĤĦĶŃŅŇŌŎŐœŨŪŬŮŰŲŵŶŸΑΗΘΚΝΟΠΥΧΫ", - 1485: "Λ", - 1497: "Φ", - 1511: "Ψ", - 1522: "Ω", - 1536: "¼½¾⅓⅔⅛", - 1556: "©®", - 1821: "ÆŒΜ", - 1870: "℉", - 1933: "Ŵ₩", - 1954: "№", - 2007: "™", - 2048: "―↔", - 2713: "‱", - }, - "Arial": { - 342: "⁄∕", - 384: "′", - 455: "įĵĺļłſίι‚‛", - 532: "¦", - 561: "∫", - 569: "\u00a0ÌÍÎÏìíîïĨĩĪīĬĭĮİıţŧΙΪ∙", - 592: "․‧", - 597: "ľ", - 655: "₀₁₂₃₄₅₆₇₈₉", - 682: "¡¨\u00ad²³´¸¹ŕŗř„‟‹›‾⁰⁴⁵⁶⁷⁸⁹", - 684: "ŀ", - 686: "‵", - 717: "•", - 725: "″‴", - 748: "º", - 756: "‣", - 758: "ª", - 768: "ť", - 809: "τ", - 846: "‖", - 903: "ζ", - 909: "ij", - 913: "έε", - 917: "ξ", - 987: "ς", - 1012: "◊", - 1024: "çýÿćĉċčĴķĸśŝşšŷźżžγκλν‼fifl", - 1075: "χ", - 1081: "‐‑", - 1100: "¶", - 1120: "ΰυ", - 1124: "√≈≠≤≥", - 1128: "Γ", - 1131: "¯‗", - 1139: ( - "¢£¤¥§«»àáâãäåèéêëðñòóôõöùúûüþāăąđēĕėęěĝğġģĥħĹĻĽĿŁńņňŋōŏőũūŭů" - "űųήηθο‒†‡€" - ), - 1140: "δ", - 1165: "ρ", - 1178: "β", - 1180: "µμ", - 1184: "άα", - 1195: "≡", - 1196: "¬−", - 1229: "℮", - 1237: "ʼn", - 1251: "¿ßøŢŤŦŹŻŽΖΤ", - 1259: "ď", - 1264: "σ", - 1266: "Σ", - 1311: "‥", - 1328: "φ", - 1331: "Ξ", - 1366: "ÀÁÂÃÄÅÈÉÊËÝÞĀĂĄĒĔĖĘĚĶŚŜŞŠŶŸΑΒΕΚΡΥΧΫ", - 1368: "ΔΛ", - 1413: "π", - 1460: "ψ∞", - 1479: "ÇÐÑÙÚÛÜĆĈĊČĎĐĤĦŃŅŇŔŖŘŨŪŬŮŰŲŵΗΝΠ", - 1481: "Ŋ", - 1505: "IJ", - 1509: "©®", - 1531: "Ω", - 1593: "ÒÓÔÕÖØĜĞĠĢŌŎŐΘΟ", - 1599: "ω", - 1634: "Φ", - 1706: "Μ", - 1708: "¼½¾⅓⅔⅛", - 1711: "Ψ", - 1821: "æ", - 1933: "œŴ₩", - 1958: "‱", - 1987: "℉", - 2048: "ÆŒ―™↔", - 2197: "№", - }, - "Cambria": { - 234: "∕", - 420: "‚․", - 451: "\u00a0", - 453: "‛", - 506: "∙", - 529: "′", - 545: "ĵ", - 556: "ĺļ", - 569: "ìíîïĩīĭįı", - 572: "ſ", - 582: "ίι", - 583: "¨¯´¸", - 585: "¡", - 592: "‧", - 620: "‹›", - 628: "Ĵ", - 632: "ł", - 648: "¦", - 664: "ÌÍÎÏĨĪĬĮİΙΪ", - 680: "\u00ad‐‑", - 686: "‵", - 693: "ţ", - 723: "ŧ", - 738: "„", - 741: "‾", - 756: "‣", - 759: "‗", - 769: "‟", - 770: "ŀ", - 788: "ľ", - 819: "ζ", - 829: "ξ", - 834: "²³¹⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", - 847: "ŕŗř", - 854: "ª", - 865: "¿", - 871: "∫", - 876: "º", - 880: "śŝşš", - 881: "″", - 883: "ς", - 903: "¢çćĉċč", - 908: "•", - 909: "έε", - 923: "ť", - 931: "źżž", - 979: "τ", - 987: "ν", - 995: "χ", - 999: "«»èéêëēĕėęěλ", - 1000: "àáâãäåāăą", - 1012: "ĝğġģ", - 1016: "ŚŜŞŠ", - 1024: "§", - 1032: "ýÿŷ", - 1038: "γ", - 1055: "‼", - 1058: "†‡", - 1074: "ķ", - 1075: "δ", - 1079: "κ", - 1082: "£", - 1083: "‖", - 1086: "ð", - 1087: "òóôõöøĸōŏőο", - 1090: "ρ", - 1098: "Γ", - 1099: "ĹĻĽ", - 1101: "ŹŻŽΖ", - 1104: "◊", - 1105: "Ł", - 1108: "ΰυ", - 1112: "ήη", - 1114: "¤µij‒", - 1118: "μ", - 1120: "θ", - 1121: "þ", - 1122: "Σ", - 1128: "ŋ", - 1130: "ĥħ", - 1131: "ùúûüũūŭůűų", - 1134: "¬⁄−≈≠≤≥", - 1136: "đ", - 1137: "β", - 1143: "ñńņň", - 1152: "ÇĆĈĊČ", - 1163: "Ρ", - 1168: "ÝŶŸ", - 1170: "Χ", - 1171: "Ξσ", - 1175: "Þfl", - 1176: "άα", - 1178: "ÈÉÊËĒĔĖĘĚΕ", - 1189: "fi", - 1204: "¶", - 1214: "ŢŤŦΤ", - 1220: "Δ", - 1233: "π", - 1240: "ßΛ", - 1243: "‴", - 1244: "ΥΫ", - 1248: "¥", - 1251: "ĜĞĠĢ", - 1252: "Β", - 1272: "ŔŖŘ", - 1274: "Ŀ", - 1276: "ÀÁÂÃÄÅĀĂĄΑ", - 1287: "€", - 1289: "ĶΚ", - 1292: "IJ", - 1311: "‥", - 1327: "ÙÚÛÜŨŪŬŮŰŲ", - 1338: "ÒÓÔÕÖØŌŎŐΘΟ", - 1345: "√", - 1355: "Ď", - 1361: "ÐĐ", - 1381: "Π", - 1388: "ď", - 1391: "Ω™", - 1394: "ÑŃŅŇŊΝ", - 1406: "ĤΗ", - 1413: "ʼn", - 1416: "Ħ", - 1458: "φ", - 1473: "ψ", - 1530: "≡", - 1536: "―", - 1538: "ω", - 1541: "æ", - 1586: "ŵ", - 1603: "Ψ", - 1608: "Φ", - 1670: "Μ", - 1676: "œ", - 1742: "©®∞", - 1751: "℮", - 1772: "¼¾", - 1774: "Æ", - 1799: "℉", - 1800: "₩", - 1822: "½", - 1886: "↔", - 1887: "Ŵ", - 1901: "⅓⅔⅛", - 1902: "Œ", - 1958: "‱", - 2127: "№", - }, - "Constantia": { - 321: "⁄∕", - 454: "‚", - 514: "\u00a0", - 524: "¡∙", - 541: "ίι", - 543: "ĵ", - 552: "‛", - 575: "ĺļł", - 579: "ſ", - 580: "ìíîïĩīĭįı", - 592: "․‧", - 611: "ª", - 628: "‹›", - 640: "Ĵ", - 642: "•", - 678: "ºΪ", - 686: "‖′‵", - 692: "Į", - 694: "ľ", - 696: "ÌÍÎÏĨĪĬİΙ", - 706: "ŀ", - 721: "ŧ", - 723: "ţť", - 736: "\u00ad‐", - 738: "²³¹⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", - 742: "¦", - 756: "‣", - 758: "‟", - 784: "„", - 785: "ŕŗř", - 795: "∫", - 829: "śŝşš", - 840: "¨¯´¸", - 844: "®", - 846: "ζ", - 880: "¿", - 883: "ξ", - 897: "έε", - 907: "τ", - 915: "‼", - 929: "¢", - 944: "γ", - 945: "çćĉċč", - 953: "ς", - 965: "ν", - 971: "″", - 981: "èéêëēĕėęě", - 983: "àáâãäåāăąźżž", - 986: "ýÿŷ", - 991: "£", - 1016: "χ", - 1037: "ΰυ", - 1040: "ĝğġģ", - 1044: "ŚŜŞŠ", - 1048: "«»", - 1050: "δ", - 1056: "€", - 1073: "◊", - 1076: "¥", - 1081: "‑", - 1083: "θ", - 1095: "ķ", - 1100: "ĸ", - 1101: "ο", - 1102: "λ", - 1104: "ρ", - 1106: "§", - 1107: "òóôõöøōŏőκ", - 1122: "ð", - 1123: "ij", - 1124: "ήη", - 1126: "Γ", - 1130: "¤¬−≈≠≤≥", - 1131: "µ", - 1132: "†", - 1138: "ĹĻĽĿŁ", - 1140: "σ", - 1141: "þ", - 1147: "μ", - 1148: "β", - 1156: "ŋ", - 1158: "άα", - 1162: "đ", - 1166: "ùúûüũūŭůűų", - 1168: "π", - 1172: "¶", - 1182: "ŹŻŽΖ", - 1186: "‗", - 1187: "ĥħ", - 1189: "ÈÉÊËĒĔĖĘĚΕ", - 1191: "Ρ", - 1192: "ñńņň", - 1196: "fi", - 1198: "Þ", - 1201: "fl", - 1215: "ÝŶŸΥΫ", - 1217: "‾", - 1223: "Β", - 1229: "√", - 1232: "‡", - 1245: "‴", - 1247: "Σ", - 1250: "ß", - 1256: "ŢŤŦΤ", - 1279: "Ξ", - 1280: "‒", - 1281: "ď", - 1293: "ŔŖŘ", - 1311: "‥", - 1334: "ÇĆĈĊČ", - 1336: "IJ", - 1343: "Δ", - 1346: "Χ", - 1350: "ĶΚ", - 1375: "Λ", - 1381: "ÀÁÂÃÄÅĀĂĄΑψ", - 1411: "φ", - 1417: "ʼn", - 1435: "ĜĞĠĢ", - 1437: "™", - 1444: "ω", - 1481: "Φ", - 1499: "ŵ", - 1511: "æ", - 1523: "ÙÚÛÜŨŪŬŮŰŲ", - 1534: "ÑŃŅŇŊΝ", - 1538: "ÐĎĐ", - 1579: "Π", - 1620: "ĤĦΗ", - 1626: "Ω₩", - 1631: "©", - 1646: "Θ", - 1647: "ÒÓÔÕÖØŌŎŐΟ", - 1687: "¼½¾", - 1692: "œ", - 1707: "Ψ", - 1783: "∞", - 1839: "Æ", - 1850: "℮", - 1854: "Μ", - 1956: "№", - 1958: "‱", - 1987: "℉⅓⅔⅛↔≡", - 2022: "Œ", - 2088: "Ŵ", - 2103: "―", - }, - "Calibri": { - 452: "′", - 463: "\u00a0", - 470: "ìíîïĩīĭįıĺļ", - 490: "ĵ", - 497: "ſ", - 504: "¹₁", - 507: "ł", - 511: "‚‛", - 516: "ÌÍÎÏĨĪĬĮİΙΪ", - 517: "․∙", - 540: "ľ", - 562: "ίι", - 592: "‧", - 598: "´", - 627: "\u00ad‐", - 629: "¸", - 653: "Ĵ", - 657: "⁷₇", - 667: "¡", - 678: "⁵₅", - 685: "³₃", - 686: "ţ‵", - 688: "²₂", - 689: "⁄∕", - 694: "‹›", - 700: "ŧ", - 708: "ť", - 712: "ζ", - 714: "ŕŗř", - 731: "⁴₄", - 735: "⁶⁹₆₉", - 737: "⁸₈", - 749: "∫", - 756: "‣", - 765: "ŀ", - 770: "ξ", - 793: "τ", - 801: "śŝşš⁰₀", - 804: "¨", - 807: "¯", - 809: "źżž‖", - 820: "″", - 824: "ª", - 841: "ς", - 851: "Γ", - 856: "‟", - 857: "„", - 861: "ĹĻ", - 865: "º", - 866: "çćĉċčĽ", - 873: "χ", - 880: "Ł", - 914: "γ", - 919: "ν", - 927: "ýÿŷ", - 931: "ķĸκ", - 933: "έε", - 939: "Σ", - 941: "ŚŜŞŠ", - 948: "λ", - 949: "¿", - 959: "ŹŻŽΖ", - 960: "ij", - 964: "ĝğġģ", - 981: "àáâãäåāăą", - 998: "ÝŢŤŦŶŸΤΥΫ", - 1000: "ÈÉÊËĒĔĖĘĚΕ", - 1007: "Ξ", - 1019: "èéêëēĕėęě", - 1020: "¢¤¦§¬‗†‡•‾−√≈≠≡≤≥", - 1038: "£¥®‒€", - 1042: "ρ", - 1046: "◊", - 1049: "«»", - 1058: "ÞΡ", - 1063: "Χ", - 1064: "ĶΚ", - 1072: "δ", - 1076: "ðñùúûüþĥńņňŋũūŭůűų", - 1080: "ßòóôõöōŏőο", - 1081: "‑", - 1084: "øfifl", - 1088: "β", - 1089: "θσ", - 1091: "ħ", - 1092: "ÇĆĈĊČ", - 1100: "ήη", - 1109: "ΰυ", - 1112: "ŔŖŘ", - 1114: "Β", - 1118: "Ŀ", - 1126: "µμ", - 1130: "đ", - 1132: "π", - 1142: "‼", - 1156: "Δ", - 1162: "άα", - 1164: "ď", - 1170: "IJ", - 1173: "Λ", - 1185: "ÀÁÂÃÄÅĀĂĄΑ", - 1186: "ʼn", - 1188: "‴", - 1200: "¶", - 1260: "Ď", - 1276: "ĤΗΠ", - 1279: "ÐĐ", - 1287: "Ŋ", - 1292: "ĜĞĠĢ", - 1303: "¼", - 1311: "‥", - 1314: "ÙÚÛÜŨŪŬŮŰŲ", - 1322: "ÑŃŅŇΝ", - 1334: "φ", - 1344: "Ħ", - 1356: "ÒÓÔÕÖŌŎŐΘΟ", - 1359: "Ø", - 1360: "Ω", - 1363: "⅛", - 1375: "½", - 1383: "¾", - 1385: "⅓", - 1426: "ω", - 1444: "™", - 1449: "ψ", - 1464: "ŵ", - 1481: "⅔", - 1513: "℮", - 1536: "Ψ", - 1555: "Φ", - 1563: "Æ", - 1583: "æ", - 1709: "©", - 1740: "œ", - 1747: "∞", - 1751: "Μ", - 1775: "Œ", - 1822: "Ŵ₩", - 1854: "―", - 1958: "‱", - 1987: "℉", - 2099: "№", - 2638: "↔", - }, - "Georgia": { - 166: "⁄∕", - 400: "‛", - 464: "‚", - 494: "\u00a0", - 572: "∙", - 586: "ĺļł", - 592: "․‧", - 598: "ĵ", - 600: "ìíîïĩīĭįı", - 605: "ίι", - 613: "ſ", - 658: "′", - 678: "¡", - 686: "‖‵", - 707: "ţťŧ", - 756: "‣", - 758: "‟", - 766: "\u00ad", - 768: "¦", - 771: "ľ", - 798: "ÌÍÎÏĨĪĬĮİΙΪ", - 804: "•", - 827: "ζ", - 839: "ŕŗř", - 840: "„", - 850: "‹›", - 861: "ŀ", - 885: "śŝşš", - 903: "ξ", - 909: "źżž", - 913: "ς", - 923: "τ", - 930: "çćĉċč", - 959: "έε", - 967: "†‡", - 980: "¿", - 990: "èéêëēĕėęě", - 999: "λ", - 1008: "ýÿŷ", - 1023: "∫", - 1024: "§¨ª²³´¶¸¹º⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", - 1027: "ν", - 1032: "àáâãäåāăą", - 1037: "χ", - 1043: "ĝğġģ", - 1052: "γ", - 1059: "″", - 1060: "Ĵ", - 1081: "‐‑", - 1089: "ð", - 1097: "ķ", - 1098: "κ", - 1104: "òóôõöøōŏőδο", - 1108: "ΰυ", - 1115: "ĸ", - 1123: "ß", - 1137: "¢", - 1139: "θ", - 1142: "ρ", - 1145: "þ", - 1149: "ŚŜŞŠ", - 1150: "◊", - 1158: "β", - 1160: "µ", - 1169: "ήη", - 1170: "¤", - 1172: "ij", - 1173: "σ", - 1176: "đ", - 1178: "ùúûüũūŭůűų‼", - 1185: "ŋ", - 1186: "μ", - 1190: "«»", - 1192: "ĥħ", - 1193: "fi", - 1195: "Γ", - 1208: "fl", - 1210: "ñńņň", - 1224: "άα", - 1231: "π", - 1232: "ŹŻŽΖ", - 1236: "ĹĻĽĿŁΣ", - 1245: "‴", - 1249: "Ρ", - 1258: "Þ", - 1259: "¥", - 1260: "ÝŶŸΥΫ", - 1261: "℮", - 1267: "ŢŤŦΤ", - 1274: "£", - 1280: "‒", - 1311: "‥", - 1315: "ÇĆĈĊČ€", - 1317: "¬¯‗‾−≈≠≤≥", - 1320: "ʼn", - 1338: "ÈÉÊËĒĔĖĘĚΕ", - 1339: "Β", - 1353: "Δ", - 1362: "ď", - 1370: "√", - 1374: "ÀÁÂÃÄÅĀĂĄΑ", - 1380: "Λ", - 1420: "Ξ", - 1422: "ĶΚ", - 1425: "φ", - 1437: "ŔŖŘ", - 1455: "Χ", - 1464: "ω", - 1468: "∞", - 1485: "ĜĞĠĢ", - 1496: "ψ", - 1509: "æ", - 1510: "ŵ", - 1524: "ÒÓÔÕÖØŌŎŐΘΟ", - 1534: "ÐĎĐ", - 1549: "ÙÚÛÜŨŪŬŮŰŲ", - 1570: "Φ", - 1571: "ÑŃŅŇŊΝ", - 1595: "Ω", - 1626: "₩", - 1655: "Π", - 1669: "ĤĦΗ", - 1672: "œ", - 1755: "―", - 1791: "Ψ", - 1818: "IJ", - 1899: "Μ", - 1929: "©®", - 1930: "™", - 1958: "‱", - 1987: "℉⅓⅔↔≡", - 1988: "Æ", - 1998: "Ŵ", - 2044: "Œ", - 2150: "¼½¾⅛", - 2500: "№", - }, - "Verdana": { - 550: "‚‛", - 562: "ìíîïĩīĭįıĺļίι", - 582: "ł", - 592: "․‧", - 606: "ľ", - 615: "ſ", - 686: "‖‵", - 705: "ĵ", - 720: "\u00a0", - 740: "′⁄∕", - 745: "∙", - 756: "‣", - 806: "¡", - 807: "ţťŧ", - 862: "ÌÍÎÏĨĪĬĮİΙΪ", - 874: "ŕŗř", - 930: "¦\u00ad‹›", - 931: "Ĵ", - 937: "ζ", - 939: "ŀ", - 940: "„‟", - 1016: "τ", - 1030: "ξ", - 1040: "ς", - 1050: "έε", - 1067: "çćĉċčśŝşš", - 1076: "źżž", - 1081: "‐‑", - 1110: "²³¹⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", - 1117: "ªº¿•", - 1140: "ĹĻĽĿ", - 1141: "″‴", - 1150: "Ł", - 1160: "Γ", - 1208: "χ", - 1212: "ýÿķĸŷγκλν", - 1220: "èéêëēĕėęě", - 1230: "àáâãäåāăą", - 1235: "Ρ", - 1240: "Þ", - 1243: "òóôõöøōŏőο", - 1245: "δ", - 1253: "ð", - 1257: "ij", - 1260: "ÝŶŸΥΫ", - 1262: "ŢŤŦΤ", - 1270: "ßβ", - 1276: "þđĝğġģάα", - 1278: "θ", - 1279: "‼", - 1280: "ρfi", - 1282: "fl", - 1291: "ųσ", - 1293: "ΰυ", - 1295: "ÈÉÊËĒĔĖĘĚΕ", - 1296: "ñùúûüĥħńņňŋũūŭůűήη", - 1302: "¢£¤¥§¨¯´¶¸‒‗†‡‾€∫", - 1305: "π", - 1310: "μ", - 1311: "‥", - 1314: "µ", - 1320: "«»", - 1326: "ď", - 1329: "Ξ", - 1377: "Σ", - 1400: "ÀÁÂÃÄÅĀĂĄŚŜŞŠΑ", - 1403: "ŹŻŽΖΧ", - 1404: "ΒΛ", - 1419: "ĶΚ", - 1424: "ŔŖŘ", - 1430: "ÇĆĈĊČ", - 1440: "Δ", - 1470: "℮", - 1496: "ʼn", - 1499: "ÙÚÛÜŨŪŬŮŰŲ", - 1532: "ÑŃŅŇŊΝ", - 1539: "ĤĦΗΠ", - 1578: "Ď", - 1588: "ÐĐĜĞĠĢ", - 1612: "ÒÓÔÕÖØŌŎŐΘΟ", - 1618: "φ", - 1666: "ω", - 1676: "¬ŵΩ−√≈≠≡≤≥◊", - 1677: "Φ", - 1683: "ψ", - 1726: "Μ", - 1783: "IJΨ", - 1956: "æ", - 1958: "‱", - 1987: "℉⅓⅔↔", - 2000: "™", - 2010: "œ", - 2016: "Æ", - 2025: "Ŵ₩", - 2048: "©®¼½¾―⅛∞", - 2191: "Œ", - 2400: "№", - }, - "Tahoma": { - 317: "∕", - 432: "‚‛", - 468: "ìíîïĩīĭįıĺļίι", - 520: "ſ", - 558: "․", - 562: "ł", - 577: "ĵ", - 602: "′‵", - 620: "‧∙", - 640: "\u00a0", - 680: "¡", - 685: "ţ", - 695: "ŧ", - 738: "ŕŗř", - 739: "ľ", - 744: "\u00ad‐‑", - 764: "ÌÍÎÏĨĪĬĮİΙΪ", - 783: "¦‖", - 784: "‹›", - 801: "ζ", - 814: "„", - 822: "‟", - 853: "Ĵ", - 881: "ς", - 886: "⁄", - 887: "ξ", - 910: "źżž", - 912: "ŀ", - 914: "śŝşš", - 931: "•‣", - 932: "έε", - 945: "çćĉċč", - 956: "τ", - 959: "ť", - 970: "¿", - 972: "″‴", - 1010: "ª²³¹º⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", - 1018: "χ", - 1019: "ĹĻĽĿ", - 1020: "ýÿķĸŷγκλν", - 1039: "Γ", - 1056: "ij", - 1060: "Ł", - 1075: "àáâãäåāăą", - 1078: "èéêëēĕėęě", - 1086: "fl", - 1092: "fi", - 1112: "òóôõöøōŏőδο", - 1116: "‥", - 1118: "¢£¤¥§¨¯´¶¸ð‒‗†‡‾€∫", - 1123: "ß", - 1129: "Ρ", - 1130: "ρ", - 1132: "þĝğġģ", - 1136: "άαθ", - 1137: "β", - 1139: "Σ", - 1140: "ΰυ", - 1141: "ŚŜŞŠ", - 1142: "ñùúûüĥńņňŋũūŭůűųήη", - 1144: "‼", - 1145: "ŹŻŽΖ", - 1149: "ÈÉÊËĒĔĖĘĚΕ", - 1154: "π", - 1158: "Þ", - 1160: "Ξ", - 1163: "µμ", - 1174: "«»đ", - 1180: "ÝŶŸΥΫ", - 1184: "ħ", - 1189: "Χ", - 1191: "σ", - 1196: "ŢŤŦΤ", - 1204: "ĶΚ", - 1207: "Β", - 1222: "Λ", - 1228: "ÀÁÂÃÄÅĀĂĄΑ", - 1230: "ÇĆĈĊČ", - 1268: "Δ", - 1271: "ŔŖŘ", - 1296: "℮", - 1343: "ÙÚÛÜŨŪŬŮŰŲ", - 1367: "ÑĜĞĠĢŃŅŇŊΝ", - 1383: "ĤΗΠ", - 1389: "Ď", - 1407: "ď", - 1418: "ʼn", - 1430: "ÐĐ", - 1438: "Ω", - 1446: "φ", - 1449: "ÒÓÔÕÖØŌŎŐΘΟ", - 1463: "ψ", - 1465: "Ħ", - 1484: "ω", - 1490: "¬−√≈≠≡≤≥◊", - 1497: "IJ", - 1520: "ŵ", - 1533: "Φ", - 1578: "Μ", - 1625: "Ψ", - 1794: "™", - 1802: "æ", - 1847: "Ŵ₩", - 1861: "œ", - 1862: "―∞", - 1870: "Æ", - 1902: "©®", - 1926: "℉", - 2000: "Œ", - 2048: "¼½¾⅓⅛↔", - 2172: "⅔", - 2336: "№", - 3692: "‱", - }, - "Segoe UI": { - 354: "⁄∕", - 420: "¸", - 444: "∙", - 469: "‚‛′", - 490: "¦", - 494: "ſ", - 496: "ìíîïĩīĭįıĵĺļ", - 545: "ÌÍÎÏĨĪĬĮİΙΪ", - 546: "ίι", - 561: "\u00a0ł", - 578: "´", - 582: "¡", - 592: "․‧", - 629: "ľ", - 645: "ŀ", - 647: "‹›", - 686: "‵", - 694: "ţŧ", - 712: "ŕŗř", - 719: "¹⁴₁₄", - 731: "Ĵ", - 750: "²³⁰⁵⁶⁷⁸⁹₀₂₃₅₆₇₈₉", - 756: "‣", - 768: "†‡", - 772: "„‟″", - 803: "ª", - 819: "\u00ad‐‑", - 832: "•", - 848: "¨", - 850: "¯‗‾", - 869: "śŝşš", - 882: "º", - 897: "έε", - 901: "ť", - 905: "ζ", - 911: "ξ", - 918: "§¿", - 926: "źżž", - 938: "¶", - 940: "‖", - 943: "ς", - 946: "çćĉċč", - 964: "ĹĻĽĿŁ", - 966: "Γ", - 983: "‼", - 991: "ýÿŷ", - 998: "τ", - 1014: "ij", - 1018: "ķĸ", - 1020: "λ", - 1036: "«»ÈÉÊËĒĔĖĘĚΕ", - 1042: "àáâãäåāăą", - 1044: "Ξ", - 1053: "‴", - 1057: "Σ", - 1063: "γ", - 1071: "èéêëēĕėęě", - 1073: "ŢŤŦΤκ", - 1077: "ν", - 1088: "ŚŜŞŠ", - 1102: "χ", - 1104: "¢£¥‒€", - 1105: "∫", - 1114: "ß", - 1122: "β", - 1132: "ÝŶŸΥΫΰυ", - 1136: "fifl", - 1138: "¤", - 1145: "ð", - 1147: "ÞΡ", - 1159: "ñùúûüĥħńņňŋũūŭůűų", - 1168: "ŹŻŽΖ", - 1174: "Β", - 1177: "σ", - 1178: "ήη", - 1182: "µμ", - 1188: "ĶΚ", - 1195: "◊", - 1196: "δ", - 1200: "òóôõöøōŏőορ", - 1201: "θ", - 1204: "þ", - 1206: "đĝğġģ", - 1208: "Χ", - 1225: "ŔŖŘ", - 1229: "℮", - 1241: "ʼn", - 1258: "άα", - 1268: "ÇĆĈĊČ", - 1276: "IJ", - 1284: "π", - 1288: "Λ", - 1311: "‥", - 1320: "Δ", - 1321: "ÀÁÂÃÄÅĀĂĄΑ", - 1331: "√", - 1381: "ď", - 1401: "¬−≡", - 1403: "≈≠≤≥", - 1405: "ĜĞĠĢ", - 1407: "ÙÚÛÜŨŪŬŮŰŲ", - 1432: "φ", - 1436: "ÐĎĐ", - 1454: "ĤĦΗ", - 1460: "Π", - 1480: "ŵ", - 1524: "₩", - 1532: "ÑŃŅŇŊΝ", - 1536: "ψ", - 1544: "ÒÓÔÕÖØŌŎŐΘΟΦ", - 1546: "Ω", - 1583: "™", - 1589: "Ψ", - 1655: "ω", - 1673: "∞", - 1704: "æ", - 1762: "Æ", - 1765: "↔", - 1823: "©®", - 1839: "Μ", - 1856: "¼", - 1888: "⅓⅔⅛", - 1900: "œ", - 1906: "½Œ", - 1913: "Ŵ", - 1950: "¾", - 1958: "‱", - 1987: "℉", - 2048: "―", - 2298: "№", - }, - "Consolas": { - 592: "‧", - 686: "‵", - 756: "‣", - 1081: "‑", - 1126: ( - "\u00a0¡¢£¤¥¦§¨©ª«¬\u00ad®¯²³´µ¶¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞß" - "àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜ" - "ĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘ" - "řŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦ" - "ΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψω‐‒―‖‗‚‛„‟†‡•․′″‴‹›‼‾⁄⁰⁴⁵⁶" - "⁷⁸⁹₀₁₂₃₄₅₆₇₈₉₩€№™℮⅓⅔⅛↔−∕∙√∞∫≈≠≡≤≥◊fifl" - ), - 1311: "‥", - 1958: "‱", - 1987: "℉", - }, - "Courier New": { - 592: "․‧", - 655: "⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", - 686: "‖‵", - 756: "‣", - 1081: "‐‑", - 1229: ( - "\u00a0¡¢£¤¥¦§¨©ª«¬\u00ad®¯²³´µ¶¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞß" - "àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜ" - "ĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘ" - "řŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦ" - "ΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψω‒―‗‚‛„‟†‡•′″‴‹›‼‾⁄₩€№™℮⅓⅔" - "⅛↔−∕∙√∞∫≈≠≡≤≥◊fifl" - ), - 1311: "‥", - 1958: "‱", - 1987: "℉", - }, - "#신명조": { - 250: "¦", - 265: "ĺļľł", - 269: "ìíîïĩīĭįı", - 292: "‚‛", - 297: "ª", - 301: "ĵ", - 313: "¹", - 320: "⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉", - 337: "ÌÍÎÏĨĪĬĮİ", - 350: "¸", - 361: "ţťŧ", - 375: "\u00adºΙΪ", - 376: "´", - 380: "¨", - 383: "²³", - 390: "„‟", - 393: "ŀ", - 398: "ίι", - 409: "ŕŗř", - 421: "¼½¾", - 438: "Ĵζξ", - 455: "śŝşš", - 463: "źżž", - 479: "¶", - 482: "çðćĉċč", - 485: "έε", - 486: "§ΰυ", - 490: "èéêëēĕėęě", - 494: "¯", - 500: "¢»¿ς‧", - 501: "«", - 509: "àáâãäåāăą", - 519: "òóôõöøōŏő", - 520: "£", - 522: "ρ", - 523: "µ", - 525: "ĸ", - 526: "τ", - 528: "ij", - 542: "δμοσ", - 543: "ďđ", - 544: "άα", - 547: "ν", - 553: "ß", - 554: "ĝğġģ", - 557: "ķ", - 560: "ùúûüĥħũūŭůűų", - 561: "¤ŷ", - 562: "γ", - 563: "κ", - 564: "ñńņňʼnŋ", - 565: "π", - 566: "ýþÿ", - 571: "¥", - 576: "Þ", - 597: "ŹŻŽ", - 603: "Ξ", - 609: "Ρ", - 610: "Γ", - 622: "ŚŜŞŠ", - 623: "ήη", - 625: "Ζλω", - 626: "χ", - 645: "ĹĻĽĿŁ", - 654: "Ββ", - 658: "Δ", - 661: "φ", - 667: "ΕΥΫ", - 672: "æ", - 677: "ÈÉÊËĒĔĖĘĚ", - 684: "Χ", - 687: "Ç", - 690: "ĆĈĊČψ", - 700: "ŔŖŘΠ", - 708: "ΘΟθ", - 709: "Ŋ", - 716: "Τ", - 717: "Ω", - 723: "œ", - 736: "Φ", - 741: "Ψ", - 742: "ĜĞĠĢ", - 748: "ÒÓÔÕÖØŌŎŐ", - 749: "ÐĎĐ", - 750: "ΑΗΚΛΝ", - 762: "ŶŸ", - 770: "ÙÚÛÜÝŢŤŦŨŪŬŮŰŲ", - 774: "IJ", - 777: "ÑŃŅŇ", - 780: "Ķ", - 781: "Σ", - 784: "ĤĦ", - 785: "©", - 788: "®", - 794: "ÀÁÂÃÄÅĀĂĄ", - 823: "ŵ", - 912: "Μ", - 927: "Œ", - 934: "Æ", - 999: "¬", - 1000: "¡ſ‐‑‒―‖‗†‡•‣․‥‱′″‴‵‹›‼‾⁄⁴₁₂₃₄₩€℉№™℮⅓⅔⅛↔−∕∙√∞∫≈≠≡≤≥◊", - 1034: "Ŵ", - }, - "양재백두체B": { - 222: "ι", - 250: "¦", - 270: "‚‛", - 278: "Ι", - 287: "Ϊ", - 289: "․‧", - 291: "ìíîïįĵĺļ", - 320: "⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉", - 335: "‖‵", - 338: "ί", - 352: "ĩīĭ", - 369: "‣", - 370: "„‟", - 375: "¯ÌÍÎÏĨĪĬĮİţſ", - 384: "ľ", - 395: "τ", - 396: "‹›", - 399: "•", - 416: "ŕŗř", - 441: "ζ", - 446: "ε", - 447: "‼", - 448: "ξ", - 458: "Ĵ", - 470: "źżž", - 484: "ť", - 500: "¢£«»àáâãäåāăąćĉċčśŝşšγκλν", - 501: "ς", - 520: "ç", - 525: "χ", - 528: "‐‑", - 541: "µèéêëñòóôõöùúûüēĕėęěĝğġģĥķńņňōŏőũūŭůűų", - 547: "υ", - 551: "Γ", - 556: "ηθο", - 557: "δ", - 563: "έ", - 569: "ρ", - 575: "β", - 576: "μ", - 578: "α", - 579: "‗", - 583: "ýÿŷ", - 590: "ή", - 591: "ΰ", - 594: "‾", - 608: "‴", - 611: "ΖΤ", - 617: "σ", - 618: "Σ", - 625: "ĹĻĽŚŜŞŠŹŻŽ‒", - 635: "⁄", - 648: "φ", - 650: "Ξ", - 656: "€", - 666: "¥ÈÉÊËÝĆĈĊČĒĔĖĘĚŔŖŘŶŸ", - 667: "ΑΒΕΚΡΥΧ", - 668: "ΔΛά", - 674: "Ç", - 677: "ď", - 690: "π", - 703: "Ϋ", - 708: "ÒÓÔÕÖĎĐĜĞĠĢŌŎŐ", - 713: "ψ", - 722: "ΗΝΠ", - 748: "Ω", - 750: "ÀÁÂÃÄÅÑÙÚÛÜĀĂĄĤĶŃŅŇŢŤŨŪŬŮŰŲ", - 778: "ΘΟ", - 781: "ω", - 783: "©®", - 785: "¬", - 791: "ŵ", - 794: "₩", - 798: "Φ", - 833: "Μ", - 835: "Ψ", - 956: "‱", - 958: "Ŵ", - 970: "℮−∕∙≈◊", - 976: "↔≡", - 1000: ( - "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧ―†‡‥′″⁴₁₂₃₄℉№™⅓⅔" - "⅛√∞∫≠≤≥" - ), - }, - "양재참숯체B": { - 250: "¦", - 270: "‚‛", - 287: "ΙΪ", - 289: "․‧", - 291: "ìíîïįıĵĺļł", - 320: "⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", - 330: "ι", - 333: "´¸", - 335: "‖′‵", - 338: "ί", - 352: "ĩīĭ", - 359: "²³", - 368: "ŀ", - 369: "‣", - 370: "„‟", - 375: "\u00ad¯¹ÌÍÎÏĨĪĬĮİţŧſ", - 384: "ľ", - 396: "‹›", - 399: "•", - 416: "¡ŕŗř", - 438: "‡", - 447: "τ‼", - 458: "Ĵ", - 469: "ªº", - 470: "źżž", - 474: "″", - 484: "ť", - 500: "¢£¤§¨«»¿àáâãäåāăąćĉċčśŝşš", - 501: "ς", - 520: "ç", - 524: "δ", - 525: "ij", - 528: "‐‑", - 533: "ζξ", - 536: "ν", - 537: "β", - 541: "µèéêëðñòóôõöøùúûüþēĕėęěĝğġģĥħķĸńņňŋōŏőũūŭůűų", - 542: "μ", - 549: "đ", - 552: "ρ", - 555: "ε", - 558: "†", - 562: "¼½¾", - 563: "έ", - 566: "κ", - 570: "ο", - 573: "γ", - 576: "Ρ", - 579: "‗", - 583: "ýÿŷ", - 587: "Β", - 590: "ήη", - 591: "ΰυ", - 593: "θ", - 594: "‾", - 600: "φ", - 608: "Ζ‴", - 609: "Ε", - 612: "Γ", - 617: "χ", - 625: "¶ßĹĻĽŁŚŜŞŠŹŻŽ‒", - 635: "⁄", - 640: "‥", - 642: "Κ", - 646: "Τ", - 656: "€", - 657: "σ", - 660: "α", - 661: "Ξ", - 666: "¥ÈÉÊËÝÞĆĈĊČĒĔĖĘĚŔŖŘŶŸψ", - 667: "ʼn", - 668: "ά", - 674: "Ç", - 677: "ď", - 695: "Δ", - 696: "ΘΟ", - 697: "Π", - 703: "ΥΧΫ", - 704: "Α", - 707: "λ", - 708: "ÐÒÓÔÕÖØĎĐĜĞĠĢŌŎŐ", - 714: "πω", - 716: "ΗΝ", - 721: "Ω", - 735: "ĿΛ", - 741: "IJ", - 746: "Ψ", - 747: "Φ", - 750: "ÀÁÂÃÄÅÑÙÚÛÜĀĂĄĤĦĶŃŅŇŊŢŤŦŨŪŬŮŰŲ", - 755: "Σ", - 783: "©®", - 785: "¬", - 791: "ŵ", - 794: "₩", - 821: "Μ", - 829: "œ", - 845: "æ", - 875: "―", - 918: "Œ", - 956: "‱", - 958: "Ŵ", - 970: "℉№™℮⅓⅔⅛↔−∕∙√∞∫≈≠≡≤≥◊", - 1000: "Æ", - }, - "한컴 솔잎 M": { - 222: "ι", - 238: "¦", - 252: "′", - 270: "‚‛", - 278: "Ι", - 287: "´Ϊ", - 289: "․‧", - 320: "⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉", - 335: "‖‵", - 337: "¸", - 338: "ί", - 360: "²³¹₁₂₃", - 366: "ĺļľŀł", - 369: "‣", - 370: "ìíîïĩīĭįı„‟", - 375: "ĵ", - 378: "§⁴₄", - 395: "τ", - 396: "‹›", - 399: "•", - 405: "″", - 425: "ÌÍÎÏĨĪĬĮİ", - 436: "ţŧ", - 441: "ζ", - 446: "ε", - 447: "‼", - 448: "ξ", - 464: "ſ", - 474: "ª", - 476: "º", - 500: "γκλν", - 501: "ς", - 508: "‥", - 511: "\u00ad", - 522: "ť", - 525: "χ", - 528: "‐‑", - 542: "¨", - 547: "υ", - 551: "Γ", - 552: "Ĵ", - 556: "ηθο", - 557: "δ", - 563: "έ", - 569: "ρ", - 574: "źżž", - 575: "ŕŗřśŝşšβ", - 576: "μ", - 578: "α", - 579: "‗", - 585: "¶", - 590: "çćĉċčή", - 591: "ΰ", - 594: "‾", - 608: "‴", - 610: "èéêëēĕėęě", - 611: "ΖΤ", - 617: "σ", - 618: "Σ", - 625: "‒", - 635: "⁄", - 640: "ýÿŷ", - 648: "φ", - 650: "àáâãäåāăąΞ", - 660: "òóôõöøĝğġģōŏő", - 667: "ΑΒΕΚΡΥΧ", - 668: "¢ΔΛά", - 672: "ð", - 677: "¯", - 685: "µùúûüđũūŭůűų", - 686: "ij", - 690: "π", - 694: "¬", - 699: "ŹŻŽ", - 700: "ŚŜŞŠ", - 702: "þ", - 703: "Ϋ", - 710: "ñĥħńņňŋ", - 713: "ψ", - 718: "«»", - 722: "ΗΝΠ", - 723: "Þ", - 731: "ķĸ", - 739: "ĹĻĽĿŁ", - 748: "ÝŶŸΩ", - 757: "ŢŤŦ", - 765: "ÈÉÊËĒĔĖĘĚ", - 770: "ÇĆĈĊČ", - 778: "ΘΟ", - 781: "ω", - 790: "ŔŖŘ", - 791: "ÀÁÂÃÄÅĀĂĄ", - 794: "₩", - 798: "Φ", - 801: "ß", - 805: "ď", - 820: "ĤĦ", - 823: "ÑŃŅŇŊ", - 833: "Μ", - 835: "Ψ", - 840: "ÒÓÔÕÖØĎĐŌŎŐ", - 841: "Ð", - 843: "ĜĞĠĢ", - 850: "ÙÚÛÜŨŪŬŮŰŲ", - 856: "Ķ", - 864: "ʼn", - 870: "ŵ", - 900: "¡£¤¥©®¼½¾¿―†‡€℉№™⅓⅔⅛↔√∞∫≠≡≤≥", - 918: "IJ", - 956: "‱", - 970: "℮−∕∙≈◊", - 976: "Ŵ", - 978: "æ", - 985: "œ", - 1073: "Œ", - 1107: "Æ", - }, - "한컴 솔잎 B": { - 222: "ι", - 238: "¦", - 252: "′", - 270: "‚‛", - 278: "Ι", - 287: "´Ϊ", - 288: "¸", - 289: "․‧", - 320: "⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉", - 335: "‖‵", - 338: "ί", - 360: "²³¹₁₂₃", - 369: "‣", - 370: "„‟", - 378: "§⁴₄", - 380: "ĺļ", - 383: "ìíîïĩīĭįı", - 386: "ĵ", - 395: "τ", - 396: "‹›", - 399: "•", - 405: "″", - 441: "ζ", - 445: "ÌÍÎÏĨĪĬĮİ", - 446: "ε", - 447: "‼", - 448: "ξ", - 450: "ţŧ", - 472: "ŀ", - 474: "ª", - 476: "ºľ", - 481: "ł", - 494: "ſ", - 500: "γκλν", - 501: "ς", - 506: "‥", - 511: "\u00ad", - 525: "χ", - 526: "¨", - 528: "‐‑", - 534: "ť", - 547: "υ", - 551: "Γ", - 552: "Ĵ", - 556: "ηθο", - 557: "δ", - 563: "έ", - 569: "ρ", - 574: "źżž", - 575: "ŕŗřśŝşšβ", - 576: "μ", - 578: "α", - 579: "‗", - 585: "¶", - 590: "çćĉċčή", - 591: "ΰ", - 594: "‾", - 608: "‴", - 610: "èéêëēĕėęě", - 611: "ΖΤ", - 617: "σ", - 618: "Σ", - 625: "‒", - 635: "⁄", - 648: "φ", - 650: "àáâãäåýÿāăąŷΞ", - 660: "òóôõöøĝğġģōŏő", - 667: "ΑΒΕΚΡΥΧ", - 668: "¢ΔΛά", - 672: "ð", - 677: "¯", - 685: "µùúûüđũūŭůűų", - 690: "π", - 694: "¬", - 699: "ŹŻŽ", - 700: "ŚŜŞŠ", - 702: "þ", - 703: "Ϋ", - 704: "ij", - 710: "ñĥħńņňŋ", - 713: "ψ", - 718: "«»", - 722: "ΗΝΠ", - 723: "Þ", - 731: "ķĸ", - 739: "ĹĻĽĿŁ", - 748: "Ω", - 757: "ŢŤŦ", - 758: "ÝŶŸ", - 765: "ÈÉÊËĒĔĖĘĚ", - 770: "ÇĆĈĊČ", - 778: "ΘΟ", - 781: "©ω", - 790: "ŔŖŘ", - 791: "ÀÁÂÃÄÅĀĂĄ", - 794: "₩", - 796: "ď", - 798: "Φ", - 801: "ß", - 820: "ĤĦ", - 823: "ÑŃŅŇŊ", - 833: "Μ", - 835: "Ψ", - 840: "ÐÒÓÔÕÖØĎĐŌŎŐ", - 843: "ĜĞĠĢ", - 850: "ÙÚÛÜŨŪŬŮŰŲ", - 856: "Ķ", - 866: "ʼn", - 870: "ŵ", - 900: "¡£¤¥®¼½¾¿―†‡€℉№™⅓⅔⅛↔√∞∫≠≡≤≥", - 918: "IJ", - 956: "‱", - 963: "æ", - 970: "℮−∕∙≈◊", - 976: "Ŵ", - 985: "œ", - 1078: "Œ", - 1107: "Æ", - }, - "한컴 윤고딕 740": { - 222: "ι", - 240: "․", - 250: "ĺļ", - 252: "ìíı", - 259: "‚", - 267: "ÌÍİ", - 276: "Įį", - 278: "Ι", - 287: "Ϊ", - 288: "´′", - 289: "‧", - 296: "‛", - 338: "ί", - 345: "ſ", - 357: "ŕŗ", - 365: "ţŧ", - 369: "‣", - 370: "ĵ", - 373: "¸", - 379: "ř", - 380: "‵", - 395: "τ", - 400: "§²³¹⁴₁₂₃₄", - 408: "¦", - 420: "ł", - 440: "„″", - 441: "ζ", - 446: "ε", - 448: "ξ‹›", - 450: "‟", - 460: "⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉", - 462: "śŝşš", - 465: "ª", - 470: "º", - 473: "ľ", - 474: "ĨĩĬĭ", - 475: "ŀ", - 480: "ť", - 482: "ς", - 484: "îï", - 487: "ÎÏ", - 500: "γκλν", - 523: "Ĵ", - 525: "χ", - 528: "‑", - 536: "ijźżž", - 538: "çćĉċč", - 544: "¨", - 546: "ĸ", - 547: "υ", - 548: "ķ", - 551: "Γ", - 556: "ηθο", - 557: "δ", - 562: "ýÿŷ", - 563: "έ", - 564: "àáâãäåāăą", - 569: "ρ", - 575: "β", - 576: "μ", - 577: "Īī", - 578: "α", - 579: "ĹĻĽĿ‗", - 580: "èéêëēĕėęě", - 589: "ŚŜŞŠ", - 590: "ή", - 591: "ΰ", - 592: "ð", - 594: "‾", - 599: "ŢŤŦ", - 611: "ΖΤ", - 612: "‥", - 616: "ß", - 617: "ŹŻŽσ", - 618: "Σ", - 621: "ÝÞŶŸ", - 622: "µ", - 624: "ñĥńņňŋ", - 625: "‒", - 626: "ÈÉÊËòóôõöøĒĔĖĘĚōŏő", - 630: "\u00ad¯‐", - 631: "ĝğġģ", - 635: "⁄", - 641: "ùúûüũūŭůűų", - 646: "þ", - 648: "φ", - 650: "Ξ", - 667: "ΑΒΕΚΡΥΧ", - 668: "ΔΛά", - 669: "Ł", - 672: "Ķ", - 681: "ŔŖŘ", - 690: "π", - 703: "ÇĆĈĊČΫ", - 713: "ψ", - 722: "ΗΝΠ", - 726: "ÀÁÂÃÄÅĀĂĄ", - 728: "đħ", - 729: "ÙÚÛÜŨŪŬŮŰŲ", - 730: "¬", - 731: "Ď", - 732: "ÑŃŅŇŊ", - 734: "Đ", - 735: "Ĥ", - 739: "IJ", - 748: "Ω", - 751: "ĜĞĠĢ", - 774: "ď", - 778: "ΘΟ", - 779: "ʼn", - 780: "ŵ", - 781: "ω", - 794: "Ħ", - 798: "Φ", - 802: "ÒÓÔÕÖØŌŎŐ", - 833: "Μ", - 835: "Ψ", - 839: "Ð", - 886: "©®", - 915: "Ŵ", - 920: "¡¢£¤¥«¶»¼½¾¿Æ―‖†‡•‴‼₩€℉№™⅓⅔⅛↔√∞∫≈≠≡≤≥◊", - 948: "æœ", - 956: "‱", - 970: "℮−∕∙", - 982: "Œ", - }, - "HY동녘B": { - 228: "ι", - 276: "‚‛", - 285: "Ι", - 294: "Ϊ", - 296: "․‧", - 298: "įĵĺļ", - 328: "⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉", - 343: "‖‵", - 346: "ί", - 360: "ĩīĭ", - 378: "‣", - 379: "„‟", - 384: "ĨĪĬĮİţſ", - 393: "ľ", - 405: "τ", - 406: "‹›", - 409: "•", - 426: "ŕŗř", - 452: "ζ", - 457: "ε", - 458: "‼", - 459: "ξ", - 469: "Ĵ", - 481: "źżž", - 496: "ť", - 512: ( - "¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöùú" - "ûüýÿāăąćĉċčśŝşšγκλν" - ), - 513: "ς", - 538: "χ", - 541: "‐‑", - 554: "ēĕėęěĝğġģĥķńņňōŏőũūŭůűų", - 560: "υ", - 564: "Γ", - 570: "δηθο", - 577: "έ", - 583: "ρ", - 588: "fi", - 589: "β", - 590: "μ", - 592: "α", - 593: "‗", - 597: "ŷ", - 603: "fl", - 604: "ή", - 605: "ΰ", - 608: "‾", - 623: "‴", - 626: "ΖΤ", - 632: "σ", - 633: "Σ", - 640: "ĹĻĽŚŜŞŠŹŻŽ‒", - 650: "⁄", - 664: "φ", - 666: "Ξ", - 672: "€", - 682: "ĆĈĊČĒĔĖĘĚŔŖŘŶŸ", - 683: "ΑΒΕΚΡΥΧ", - 684: "ΔΛά", - 693: "ď", - 707: "π", - 720: "Ϋ", - 725: "ĎĐĜĞĠĢŌŎŐ", - 730: "ψ", - 740: "ΗΝΠ", - 766: "Ω", - 768: "ĀĂĄĤĶŃŅŇŢŤŨŪŬŮŰŲ", - 797: "ΘΟ", - 800: "ω", - 810: "ŵ", - 813: "₩", - 817: "Φ", - 853: "Μ", - 856: "Ψ", - 979: "‱", - 981: "Ŵ", - 993: "℮−∕∙≈◊", - 1024: ( - "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧ―†‡‥′″⁴₁₂₃₄℉№™⅓⅔" - "⅛↔√∞∫≠≡≤≥" - ), - }, - "HY수평선B": { - 228: "ι", - 276: "‚‛", - 285: "Ι", - 294: "Ϊ", - 296: "․‧", - 298: "įĵĺļ", - 328: "⁰⁵⁶⁷⁸⁹₀₅₆₇₈₉", - 343: "‖‵", - 346: "ί", - 360: "ĩīĭ", - 378: "‣", - 379: "„‟", - 384: "ĨĪĬĮİţſ", - 393: "ľ", - 405: "τ", - 406: "‹›", - 409: "•", - 426: "ŕŗř", - 452: "ζ", - 457: "ε", - 458: "‼", - 459: "ξ", - 469: "Ĵ", - 481: "źżž", - 496: "ť", - 512: ( - "¢£¥¦©«¬®¯µ»ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöùú" - "ûüýÿāăąćĉċčśŝşšγκλν" - ), - 513: "ς", - 538: "χ", - 541: "‐‑", - 554: "ēĕėęěĝğġģĥķńņňōŏőũūŭůűų", - 560: "υ", - 564: "Γ", - 570: "δηθο", - 577: "έ", - 583: "ρ", - 588: "fi", - 589: "β", - 590: "μ", - 592: "α", - 593: "‗", - 597: "ŷ", - 603: "fl", - 604: "ή", - 605: "ΰ", - 608: "‾", - 623: "‴", - 626: "ΖΤ", - 632: "σ", - 633: "Σ", - 640: "ĹĻĽŚŜŞŠŹŻŽ‒", - 650: "⁄", - 664: "φ", - 666: "Ξ", - 672: "€", - 682: "ĆĈĊČĒĔĖĘĚŔŖŘŶŸ", - 683: "ΑΒΕΚΡΥΧ", - 684: "ΔΛά", - 693: "ď", - 707: "π", - 720: "Ϋ", - 725: "ĎĐĜĞĠĢŌŎŐ", - 730: "ψ", - 740: "ΗΝΠ", - 766: "Ω", - 768: "ĀĂĄĤĶŃŅŇŢŤŨŪŬŮŰŲ", - 797: "ΘΟ", - 800: "ω", - 810: "ŵ", - 813: "₩", - 817: "Φ", - 853: "Μ", - 856: "Ψ", - 979: "‱", - 981: "Ŵ", - 993: "℮−∕∙≈◊", - 1024: ( - "¡¤§¨ª\u00ad²³´¶¸¹º¼½¾¿ÆÐØÞßæðøþđĦħıIJijĸĿŀŁłʼnŊŋŒœŦŧ―†‡‥′″⁴₁₂₃₄℉№™⅓⅔" - "⅛↔√∞∫≠≡≤≥" - ), - }, - "MD이솝체": { - 256: "¦", - 276: "‚‛", - 294: "ΙΪ", - 296: "․‧", - 298: "ìíîïįıĵĺļł", - 328: "⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", - 338: "ι", - 341: "´¸", - 343: "‖′‵", - 346: "ί", - 360: "ĩīĭ", - 368: "²³", - 377: "ŀ", - 378: "‣", - 379: "„‟", - 384: "¯¹ÌÍÎÏĨĪĬĮİţŧſ", - 393: "ľ", - 406: "‹›", - 409: "•", - 426: "¡ŕŗř", - 449: "‡", - 458: "τ‼", - 469: "Ĵ", - 480: "ªº", - 481: "źżž", - 485: "″", - 496: "ť", - 512: "¢£¤§¨«»¿àáâãäåāăąćĉċčśŝşš", - 513: "ς", - 532: "ç", - 537: "δ", - 538: "ij", - 541: "‐‑", - 546: "ζξ", - 549: "ν", - 550: "β", - 554: "µèéêëðñòóôõöøùúûüþēĕėęěĝğġģĥħķĸńņňŋōŏőũūŭůűų", - 555: "μ", - 562: "đ", - 565: "ρ", - 568: "ε", - 571: "†", - 575: "¼½¾", - 577: "έ", - 580: "κ", - 584: "ο", - 587: "γ", - 588: "fi", - 590: "Ρ", - 593: "‗", - 597: "ýÿŷ", - 601: "Β", - 603: "fl", - 604: "ήη", - 605: "ΰυ", - 607: "θ", - 608: "‾", - 614: "φ", - 623: "Ζ‴", - 624: "Ε", - 627: "Γ", - 632: "χ", - 640: "¶ßĹĻĽŁŚŜŞŠŹŻŽ‒", - 650: "⁄", - 655: "‥", - 657: "Κ", - 662: "Τ", - 672: "€", - 673: "σ", - 676: "α", - 677: "Ξ", - 682: "¥ÈÉÊËÝÞĆĈĊČĒĔĖĘĚŔŖŘŶŸψ", - 683: "ʼn", - 684: "ά", - 690: "Ç", - 693: "ď", - 712: "Δ", - 713: "ΘΟ", - 714: "Π", - 720: "ΥΧΫ", - 721: "Α", - 724: "λ", - 725: "ÐÒÓÔÕÖØĎĐĜĞĠĢŌŎŐ", - 731: "πω", - 733: "ΗΝ", - 738: "Ω", - 753: "ĿΛ", - 759: "IJ", - 764: "Ψ", - 765: "Φ", - 768: "ÀÁÂÃÄÅÑÙÚÛÜĀĂĄĤĦĶŃŅŇŊŢŤŦŨŪŬŮŰŲ", - 773: "Σ", - 802: "©®", - 804: "¬", - 810: "ŵ", - 813: "₩", - 841: "Μ", - 849: "œ", - 865: "æ", - 896: "―", - 940: "Œ", - 979: "‱", - 981: "Ŵ", - 993: "℉№™℮⅓⅔⅛↔−∕∙√∞∫≈≠≡≤≥◊", - 1024: "\u00adÆ", - }, - "태 헤드라인D": { - 256: "¦", - 276: "‚‛", - 294: "ΙΪ", - 296: "․‧", - 298: "ìíîïįıĵĺļł", - 328: "⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", - 338: "ι", - 341: "´¸", - 343: "‖′‵", - 346: "ί", - 360: "ĩīĭ", - 368: "²³", - 377: "ŀ", - 378: "‣", - 379: "„‟", - 384: "\u00ad¯¹ÌÍÎÏĨĪĬĮİţŧſ", - 393: "ľ", - 406: "‹›", - 409: "•", - 426: "¡ŕŗř", - 449: "‡", - 458: "τ‼", - 469: "Ĵ", - 480: "ªº", - 481: "źżž", - 485: "″", - 496: "ť", - 512: "¢£¤§¨«»¿àáâãäåāăąćĉċčśŝşš", - 513: "ς", - 532: "ç", - 537: "δ", - 538: "ij", - 541: "‐‑", - 546: "ζξ", - 549: "ν", - 550: "β", - 554: "µèéêëðñòóôõöøùúûüþēĕėęěĝğġģĥħķĸńņňŋōŏőũūŭůűų", - 555: "μ", - 562: "đ", - 565: "ρ", - 568: "ε", - 571: "†", - 575: "¼½¾", - 577: "έ", - 580: "κ", - 584: "ο", - 587: "γ", - 588: "fi", - 590: "Ρ", - 593: "‗", - 597: "ýÿŷ", - 601: "Β", - 603: "fl", - 604: "ήη", - 605: "ΰυ", - 607: "θ", - 608: "‾", - 614: "φ", - 623: "Ζ‴", - 624: "Ε", - 627: "Γ", - 632: "χ", - 640: "¶ßĹĻĽŁŚŜŞŠŹŻŽ‒", - 650: "⁄", - 655: "‥", - 657: "Κ", - 662: "Τ", - 672: "€", - 673: "σ", - 676: "α", - 677: "Ξ", - 682: "¥ÈÉÊËÝÞĆĈĊČĒĔĖĘĚŔŖŘŶŸψ", - 683: "ʼn", - 684: "ά", - 690: "Ç", - 693: "ď", - 712: "Δ", - 713: "ΘΟ", - 714: "Π", - 720: "ΥΧΫ", - 721: "Α", - 724: "λ", - 725: "ÐÒÓÔÕÖØĎĐĜĞĠĢŌŎŐ", - 731: "πω", - 733: "ΗΝ", - 738: "Ω", - 753: "ĿΛ", - 759: "IJ", - 764: "Ψ", - 765: "Φ", - 768: "ÀÁÂÃÄÅÑÙÚÛÜĀĂĄĤĦĶŃŅŇŊŢŤŦŨŪŬŮŰŲ", - 773: "Σ", - 802: "©®", - 804: "¬", - 810: "ŵ", - 813: "₩", - 841: "Μ", - 849: "œ", - 865: "æ", - 896: "―", - 940: "Œ", - 979: "‱", - 981: "Ŵ", - 993: "℉№™℮⅓⅔⅛↔−∕∙√∞∫≈≠≡≤≥◊", - 1024: "Æ", - }, -} +ADVANCES: dict[str, dict[int, str]] = _by_key(_TABLES["ADVANCES"]) -#: Advances Hancom Office 2024 lays italic glyphs out at, on the desktop, in the faces it draws italic in faces of -#: their own (in each face's units per em), where they differ from the regular ones: measured, not read from a -#: font file. The Windows Latin faces it draws italic in their installed italic faces. Italic glyphs in the other -#: faces Hancom slants in place, at their regular advances. -ITALIC_ADVANCES: dict[str, dict[int, str]] = { - "HCI Poppy": { - 284: "fijl", - 302: "/", - 340: "It", - 398: "ers", - 416: "c", - 454: "akoz", - 474: "bq", - 510: "\"?dghpvxy", - 568: "LSnu", - 624: "PT", - 684: "CK", - 740: "AGXw", - 796: "DHNOQm", - 910: "%", - 966: "MW", - }, - "한양중고딕": { - 191: "il", - 192: "j", - 221: "‘’", - 232: "|", - 235: "'`", - 240: ".;", - 241: ",I", - 242: ":", - 248: "[]", - 250: "ft", - 258: "/", - 275: ")", - 277: "\\", - 282: "(", - 300: "}", - 304: "r{", - 362: "*", - 368: "“”„‟", - 412: "\"", - 439: "^", - 457: "y", - 461: "Jx", - 464: "k", - 470: "v", - 471: "s", - 474: "c", - 475: "z", - 490: "0123456789_~", - 515: "+=?", - 518: "b", - 520: "$ghn", - 522: "dqu", - 523: "e", - 525: "#ap", - 529: "Lo", - 574: "Z", - 583: "F", - 608: "Y", - 615: "X", - 618: "B", - 620: "K", - 621: "AV", - 625: "PS", - 631: "&", - 637: "E", - 675: "U", - 676: "H", - 679: "NR", - 680: "D", - 684: "w", - 686: "C", - 735: "O", - 737: "G", - 740: "Q", - 788: "M", - 794: "m", - 851: "%", - 887: "W", - 980: "@", - }, - "한양신명조": { - 140: "\\", - 224: ".", - 241: "f", - 290: ",l", - 305: "j", - 310: "i", - 317: "'", - 322: "`", - 340: ":", - 348: "t", - 375: ";", - 383: "^", - 413: "(", - 417: ")", - 433: "I}", - 434: "{", - 441: "„‟", - 445: "r", - 472: "s", - 474: "c", - 482: "]", - 495: "#", - 499: "[", - 500: "*|", - 502: "a", - 508: "hx", - 513: "\"/", - 519: "y", - 524: "v", - 530: "e", - 534: "o", - 535: "z", - 539: "b", - 542: "k", - 544: "n", - 560: "u", - 564: "q", - 568: "p", - 573: "-=d", - 574: "+", - 583: "J", - 585: "?", - 618: "S", - 619: "g", - 655: "L", - 658: "$", - 708: "Z", - 716: "Y", - 720: "Tw", - 724: "", - 743: "V", - 746: "F", - 752: "E", - 754: "P", - 759: "R", - 763: "G", - 766: "B", - 769: "A", - 794: "O", - 798: "Q", - 807: "X", - 826: "D", - 840: "K", - 853: "U", - 864: "N", - 869: "%", - 881: "H", - 973: "&", - 999: "@", - 1024: "W", - 1050: "M", - }, - "한양견고딕": { - 1079: "'", - 1099: "`", - 2150: "-", - 2154: "+=", - 2874: ">", - 2966: "<", - }, - "Times New Roman": { - 438: "'", - 512: "·", - 563: "|¦", - 569: "fίι", - 570: "ŧ", - 661: "ŀ", - 682: ":;", - 733: "τ", - 745: "ľť", - 763: "․", - 797: "[]rz¡ŕŗřźżž", - 807: "έγε", - 819: "{}", - 829: "ζ", - 831: "ς", - 860: "\"‴", - 864: "^", - 877: "ξ", - 887: "λ", - 901: "χ", - 909: "JkvxyýÿĴķĸŷνⅴⅹ", - 940: "ΰυ", - 952: "δ", - 983: "κρ", - 987: "ŋ", - 1006: "θ", - 1010: "σ", - 1016: "ήη", - 1020: "β", - 1024: "?Sa¿àáâãäåā㹌ŜŞŠfifl", - 1025: "ij", - 1026: "π", - 1028: "μ", - 1071: "¶", - 1075: "άα", - 1133: "φ", - 1139: "LTYZÝĹĻĽĿŁŢŤŦŶŸŹŻŽΖΤΥΫ“”„‟", - 1165: "Γ", - 1182: "ʼn", - 1202: "Δ", - 1217: "Σ", - 1237: "Λ", - 1246: "ď", - 1251: "ABFPRVXÀÁÂÃÄÅÞĀĂĄŔŖŘΑΒΡΧⅤⅩ", - 1272: "ψ", - 1292: "‥", - 1300: "Ⅱ", - 1309: "Ξ", - 1366: "KNwÑĶŃŅŇœŵΚΝ", - 1382: "+<=>¬×−≡", - 1426: "Ŋ", - 1440: "Ψ", - 1446: "ω", - 1474: "ⅳ", - 1479: "m", - 1481: "Ω", - 1483: "ⅺ", - 1484: "ⅵ", - 1485: "ⅸ", - 1536: "IJ", - 1559: "Φ", - 1706: "MWŴΜ₩", - 1821: "—…", - 1844: "℉", - 1884: "@", - 1885: "Ⅳ", - 1908: "Ⅵ", - 1918: "Ⅲ", - 1931: "№", - 1933: "Œ", - 1942: "Ⅸ", - 1952: "Ⅺ", - 1988: "ⅻ", - 1989: "ⅶ", - 2009: "℃", - 2494: "ⅷ", - 2526: "Ⅶ", - 2570: "Ⅻ", - 2630: "Ⅷ", - 2745: "‱", - }, - "Arial": { - 455: "ĩīĭ", - 576: "ľ", - 725: "ť", - 766: "τ", - 819: "ŀ", - 900: "έε", - 915: "ξ", - 949: "ζ", - 996: "ς", - 1008: "λ", - 1111: "θ", - 1118: "χ", - 1122: "μ", - 1126: "ΰυ", - 1137: "ήη", - 1138: "δ", - 1168: "Γάα", - 1170: "β", - 1173: "ρ", - 1196: "≡", - 1228: "Σ", - 1235: "σ", - 1259: "ʼn", - 1280: "ď", - 1328: "Ξ", - 1336: "φ", - 1366: "Λ", - 1372: "π", - 1374: "Δ", - 1484: "Π", - 1490: "ψ", - 1502: "IJ", - 1558: "Ω", - 1595: "ω", - 1701: "Ψ", - 1714: "Φ", - 2218: "№", - }, - "Cambria": { - 221: "⁄", - 408: ",.‚․", - 437: "‘’‛", - 480: "'", - 494: "·", - 499: "′", - 530: ":;", - 546: "lĺļ", - 554: "`¨¯´¸", - 555: "iìíîïĩīĭįı", - 562: "ſ", - 574: "¡", - 578: "∙", - 588: "ίι", - 593: "‹›", - 599: "f", - 604: "ł", - 613: "JĴ", - 646: "|¦", - 653: "-\u00ad‐‑", - 656: "IÌÍÎÏĨĪĬĮİΙΪ", - 694: "[]", - 707: "tţ", - 719: "„", - 735: "ŧ", - 741: "ŀ", - 751: "“”", - 761: "()", - 767: "‟", - 768: "{}", - 773: "ľ", - 782: "sśŝşš", - 797: "\"", - 808: "²³¹⁰⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", - 811: "ª", - 832: "º", - 834: "?r¿ŕŗř", - 850: "*", - 854: "ζ", - 861: "ς″", - 877: "ξ", - 883: "ť", - 887: "cçćĉċčέε", - 896: "¢", - 920: "x", - 921: "zźżž", - 936: "eèéêëēĕėęě", - 942: "vyýÿŷ", - 954: "/\\", - 958: "χ", - 960: "«»", - 961: "λ", - 973: "§", - 977: "ν", - 979: "γ", - 980: "τ", - 986: "SŚŜŞŠ", - 1000: "$", - 1010: "κ", - 1011: "†‡", - 1018: "kķ", - 1024: "δ", - 1025: "£", - 1028: "ĸ", - 1038: "oòóôõöøōŏőο", - 1042: "ð", - 1049: "ZŹŻŽΖ", - 1053: "‼", - 1067: "bþ", - 1068: "q", - 1070: "gĝğġģ", - 1071: "LĹĻĽ", - 1073: "dđΓΰυ", - 1077: "aàáâãäåā㹣Σρ", - 1079: "Fpβ", - 1081: "‖", - 1082: "+0123456789<=>^~¬±×÷−∕≈≠≤≥", - 1086: "hĥħ", - 1089: "ŋ", - 1094: "ήη", - 1096: "nuñùúûüńņňũūŭůűų", - 1100: "ij", - 1105: "CÇĆĈĊČ", - 1110: "μ", - 1112: "Ξθ", - 1116: "XΧ", - 1122: "YÝŶŸ", - 1128: "µ", - 1134: "¤", - 1135: "σ", - 1137: "PΡ", - 1143: "άα", - 1145: "ΥΫfl", - 1147: "Þ", - 1154: "fi", - 1160: "ß", - 1164: "EÈÉÊËĒĔĖĘĚΕ", - 1166: "¶", - 1171: "Δ", - 1175: "TŢŤŦΤ", - 1178: "V", - 1194: "π", - 1198: "GĜĞĠĢ", - 1205: "AÀÁÂÃÄÅĀĂĄΑΛ", - 1209: "RŔŖŘ", - 1221: "BΒ", - 1223: "‴", - 1227: "¥", - 1235: "KĶΚ", - 1238: "€", - 1241: "Ŀ", - 1269: "IJ", - 1273: "OQÒÓÔÕÖØŌŎŐΟ", - 1274: "Θ", - 1295: "UÙÚÛÜŨŪŬŮŰŲ", - 1305: "ď", - 1324: "DĎ™", - 1325: "Ω", - 1330: "ÐĐ", - 1350: "&Π", - 1361: "ʼn", - 1370: "HĤΗ", - 1374: "NÑŃŅŇŊΝ", - 1379: "Ħ", - 1386: "ψ", - 1389: "φ", - 1452: "æ", - 1472: "…", - 1481: "Φ", - 1489: "ω", - 1490: "wŵ", - 1509: "Ψ", - 1568: "√", - 1581: "œ", - 1622: "MΜ", - 1636: "m", - 1709: "Æ", - 1736: "℮", - 1739: "⅔", - 1743: "⅓", - 1757: "%¼¾", - 1769: "₩", - 1806: "½", - 1822: "■□", - 1836: "WŒŴ", - 1868: "⅛", - 1872: "▲", - 2048: "℃℉△◆◇●", - 2052: "№", - 2502: "‰", - }, - "Constantia": { - 386: "'", - 416: "‘’", - 445: "‚", - 483: " \u00a0", - 499: "·∙", - 520: "ίι", - 537: "jĵ", - 542: "ſ", - 552: "lĺļł", - 557: "iìíîïĩīĭįı", - 614: "‹›", - 616: "f", - 630: "1", - 638: "JĴ", - 652: "ª", - 653: "º", - 662: "ŀ", - 678: "Į", - 682: "∕", - 690: "ľ", - 692: "IÌÍÎÏĨĪĬİΙΪ", - 693: "-\u00ad‐", - 706: "\"", - 736: "“”", - 738: "tţť", - 751: "(", - 758: "ŧ", - 775: "„", - 792: "rŕŗř", - 797: "ζ", - 805: "/\\", - 818: "έε", - 825: "ξ", - 853: "ς", - 865: "sśŝşš", - 866: "τ", - 911: "γ", - 916: "eèéêëēĕėęě", - 921: "ν", - 936: "cvçćĉċč", - 942: "2", - 952: "5", - 961: "χ", - 983: "yýÿŷ", - 996: "zźżž", - 1009: "ΰυ", - 1010: "δ", - 1014: "«»", - 1016: "x", - 1025: "κ", - 1026: "θ", - 1028: "ο", - 1041: "gĝğġģ", - 1042: "λ", - 1043: "SŚŜŞŠ", - 1044: "q", - 1045: "ρ", - 1048: "kķ", - 1052: "aàáâãäåþāăą", - 1053: "b", - 1058: "ĸήη", - 1062: "4dđ", - 1069: "p", - 1072: "oòóôõöøōŏő", - 1079: "ð", - 1082: "F", - 1094: "ij", - 1101: "µ", - 1103: "Γμ", - 1108: "9", - 1111: "β", - 1114: "σ", - 1116: "ŋ", - 1117: "LĹĻĽĿŁ", - 1121: "π", - 1124: "άα", - 1127: "hĥħ", - 1136: "fi", - 1139: "uùúûüũūŭůűų", - 1142: "nñńņň", - 1155: "fl", - 1162: "ZŹŻŽΖ", - 1166: "EÈÉÊËĒĔĖĘĚΕ", - 1176: "PΡ", - 1181: "Þ", - 1200: "ď", - 1203: "BΒ", - 1209: "ß", - 1212: "YÝŶŸΥΫ", - 1232: "TŢŤŦΤ", - 1242: "Σ", - 1260: "Ξ", - 1277: "RŔŖŘ", - 1312: "ʼn", - 1316: "Δ", - 1318: "XΧ", - 1320: "CÇĆĈĊČ", - 1330: "IJφ", - 1344: "KĶΚ", - 1347: "Λ", - 1353: "AÀÁÂÃÄÅĀĂĄΑ", - 1365: "Vψ", - 1386: "ω", - 1387: "GĜĞĠĢ", - 1424: "wŵ", - 1437: "…", - 1473: "Φ", - 1487: "NÑŃŅŇŊ", - 1491: "æΝ", - 1496: "UÙÚÛÜŨŪŬŮŰŲ", - 1501: "&", - 1537: "DÐĎĐ", - 1560: "Π", - 1595: "OÒÓÔÕÖØŌŎŐΘΟ", - 1596: "Q", - 1597: "HĤĦΗ", - 1611: "œ", - 1637: "Ω", - 1687: "%", - 1691: "Ψ", - 1709: "m", - 1827: "MΜ", - 1840: "Æ", - 1854: "№", - 1976: "Œ", - 2055: "WŴ", - 2425: "‰", - }, - "Calibri": { - 702: "rŕŗř", - 787: "\\", - 794: "/", - 797: "sśŝşš", - 852: "cçćĉċč", - 882: "ª", - 913: "vγ", - 916: "yýÿŷ", - 926: "SŚŜŞŠ", - 978: "eèéêëēĕėęě", - 1038: "‖", - 1051: "oòóôõöōŏőο", - 1053: "abdghnpquàáâãäåñùúûüþāăąĝğġģĥńņňŋũūŭůűų", - 1066: "ħ", - 1070: "CÇĆĈĊČ", - 1076: "ήη", - 1081: "β", - 1102: "µμ", - 1128: "đ", - 1136: "ď", - 1144: "θ", - 1157: "άα", - 1165: "ʼn", - 1284: "Ŋ", - 1320: "NÑŃŅŇΝ", - 1339: "φ", - 1340: "OÒÓÔÕÖŌŎŐΟ", - 1344: "Θ", - 1347: "Ø", - 1360: "Q", - 1413: "…", - 1545: "æ", - 1556: "Φ", - 1620: "m", - 1668: "œ", - 1823: "WŴ₩", - 2093: "№", - }, - "Georgia": { - 294: "⁄∕", - 400: "‘’‚", - 575: "ίι", - 584: "lĺļł", - 596: "jĵ", - 603: "ſ", - 609: "iìíîïĩīĭįı", - 673: "f", - 711: "tţťŧ", - 786: ":;", - 790: "“”„", - 798: "ľ", - 822: "ζ", - 862: "ŀ", - 883: "sśŝşš", - 898: "ξ", - 903: "ς", - 920: "τ", - 929: "cçćĉċč", - 945: "rŕŗř", - 949: "έε", - 966: "eèéêëēĕėęě", - 1017: "7", - 1026: "x", - 1042: "γ", - 1081: "kķ", - 1100: "oòóôõöøōŏőο", - 1102: "vΰυ", - 1103: "δ", - 1110: "ß", - 1119: "ð", - 1129: "θ", - 1132: "þ", - 1134: "b", - 1137: "q", - 1138: "ĸκ", - 1146: "yýÿŷ", - 1152: "hĥħρ", - 1160: "β", - 1161: "µ", - 1166: "σ", - 1173: "agàáâãäåāăąĝğġģ", - 1178: "dđ", - 1179: "μ‼", - 1180: "ij", - 1184: "pŋήη", - 1195: "fi", - 1208: "nñńņň", - 1221: "¯‾", - 1225: "άα", - 1234: "fl", - 1236: "π", - 1288: "ʼn", - 1369: "Δ", - 1406: "ď", - 1450: "φ", - 1486: "ω", - 1496: "OQÒÔÕŌŎŐΘΟ", - 1507: "ψ", - 1565: "æ", - 1684: "wŵ", - 1690: "œ", - 1798: "IJ", - 1801: "m", - 2514: "‰", - }, - "Verdana": { - 562: "ł", - 1105: "⁰⁶⁹₀₆₉", - 1140: "Ł", - 1202: "kķĸ", - 1210: "vyýÿŷγν", - 1273: "gĝğġģ", - 1278: "ρ", - 1291: "ΰυ", - 1296: "ų", - 1308: "μ", - 1398: "AVÀÁÂÃÄÅĀĂĄΑ", - 1487: "Δ", - 1568: "DÐĎĐ", - 1669: "Φ", - 1955: "æ", - 1993: "m", - 2008: "œ", - 2026: "Æ", - 2028: "WŴ₩", - 3110: "‰", - }, - "Segoe UI": { - 270: "⁄∕", - 432: "‘’‚‛", - 446: ",.:;·", - 463: "'", - 492: "j|¦ĵ", - 530: "ilìíîïĩīĭįıĺļ", - 563: " \u00a0ł", - 600: "ſ", - 604: "fľ", - 623: "()[]{}", - 653: "¡", - 662: "tţŧ", - 709: "JĴ", - 715: "`¨¯´¸", - 727: "rŕŗř", - 745: "ť", - 750: "¹⁴", - 766: "\"“”„‟", - 770: "†‡", - 788: "₃", - 791: "\\", - 793: "₂", - 795: "₁", - 809: "sśŝşš", - 811: "/", - 829: "•", - 856: "*", - 881: "?¿", - 893: "cªçćĉċč", - 915: "º", - 932: "xς", - 936: "έε", - 937: "‖", - 940: "ξ", - 948: "LĹĻŁ", - 965: "ĽĿ", - 967: "Γ", - 969: "v", - 997: "eèéêëēĕėęě", - 1001: "Fτ", - 1004: "kķĸ", - 1018: "SŚŜŞŠ", - 1022: "EÈÉÊËĒĔĖĘĚΕ", - 1025: "ij", - 1037: "ν", - 1046: "κ", - 1053: "«»", - 1054: "‴", - 1069: "ð", - 1077: "TŢŤΤ", - 1096: "oòóôõöøōŏőο", - 1104: "∫", - 1106: "ß", - 1110: "abdgpqàáâãäåþāăąđĝğġģ", - 1116: "χ", - 1134: "fifl", - 1135: "YÝŶŸΥΫ", - 1139: "¤", - 1141: "hĥħ", - 1143: "uùúûüũūŭůűų", - 1147: "ρ", - 1149: "β", - 1151: "nñńņňŋ", - 1167: "ZŹŻŽΖ", - 1171: "θσ", - 1175: "µήημ", - 1178: "PÞΡ", - 1192: "RŔŖŘ", - 1194: "◊", - 1197: "ⅺ", - 1202: "ΰυ", - 1210: "XΧ", - 1221: "ď", - 1228: "KĶΚ", - 1230: "π", - 1268: "IJ", - 1282: "άα", - 1286: "V", - 1294: "AÀÁÂÃÄÅĀĂĄΑ", - 1309: "CÇĆĈĊČ", - 1343: "Λ", - 1360: "Δ", - 1403: "+<=>^~¬±×÷−≡", - 1409: "GĜĞĠĢ", - 1411: "UÙÚÛÜŨŪŬŮŰŲ", - 1449: "Π", - 1450: "HĤĦΗ", - 1458: "DÐĎĐⅻ", - 1475: "wŵ", - 1494: "φ", - 1507: "…", - 1538: "NÑŃŅŇŊΝ", - 1573: "ψ", - 1576: "&", - 1578: "Ω", - 1647: "ω", - 1655: "Ψ", - 1675: "MΜ", - 1686: "%", - 1692: "æ", - 1743: "œ", - 1751: "Æ", - 1757: "m", - 1862: "©", - 1876: "¼⅓⅔⅛", - 1892: "Œ", - 1903: "WŴ", - 1939: "½", - 1966: "@", - 1968: "¾", - 2359: "№", - 2482: "‰", - }, - "#신명조": { - 441: "„‟", - }, - "양재백두체B": { - 374: "τ", - 439: "ε", - 447: "ξ", - 463: "ζ", - 492: "λ", - 542: "θ", - 546: "χ", - 548: "μ", - 550: "υ", - 555: "η", - 556: "δ", - 570: "Γα", - 571: "β", - 573: "ρ", - 600: "Σ", - 603: "σ", - 648: "Ξ", - 652: "φ", - 667: "Λ", - 670: "π", - 671: "Δ", - 725: "Π", - 728: "ψ", - 761: "Ω", - 779: "ω", - 831: "Ψ", - 837: "Φ", - }, - "한컴 소망 M": { - 374: "τ", - 439: "ε", - 447: "ξ", - 463: "ζ", - 492: "λ", - 542: "θ", - 546: "χ", - 548: "μ", - 550: "υ", - 555: "η", - 556: "δ", - 570: "Γα", - 571: "β", - 573: "ρ", - 600: "Σ", - 603: "σ", - 648: "Ξ", - 652: "φ", - 667: "Λ", - 670: "π", - 671: "Δ", - 725: "Π", - 728: "ψ", - 761: "Ω", - 779: "ω", - 831: "Ψ", - 837: "Φ", - }, - "한컴 소망 B": { - 374: "τ", - 439: "ε", - 447: "ξ", - 463: "ζ", - 492: "λ", - 542: "θ", - 546: "χ", - 548: "μ", - 550: "υ", - 555: "η", - 556: "δ", - 570: "Γα", - 571: "β", - 573: "ρ", - 600: "Σ", - 603: "σ", - 648: "Ξ", - 652: "φ", - 667: "Λ", - 670: "π", - 671: "Δ", - 725: "Π", - 728: "ψ", - 761: "Ω", - 779: "ω", - 831: "Ψ", - 837: "Φ", - }, - "한컴 솔잎 M": { - 374: "τ", - 439: "ε", - 447: "ξ", - 463: "ζ", - 492: "λ", - 542: "θ", - 546: "χ", - 548: "μ", - 550: "υ", - 555: "η", - 556: "δ", - 570: "Γα", - 571: "β", - 573: "ρ", - 600: "Σ", - 603: "σ", - 648: "Ξ", - 652: "φ", - 667: "Λ", - 670: "π", - 671: "Δ", - 725: "Π", - 728: "ψ", - 761: "Ω", - 779: "ω", - 831: "Ψ", - 837: "Φ", - }, - "한컴 솔잎 B": { - 374: "τ", - 439: "ε", - 447: "ξ", - 463: "ζ", - 492: "λ", - 542: "θ", - 546: "χ", - 548: "μ", - 550: "υ", - 555: "η", - 556: "δ", - 570: "Γα", - 571: "β", - 573: "ρ", - 600: "Σ", - 603: "σ", - 648: "Ξ", - 652: "φ", - 667: "Λ", - 670: "π", - 671: "Δ", - 725: "Π", - 728: "ψ", - 761: "Ω", - 779: "ω", - 831: "Ψ", - 837: "Φ", - }, - "한컴 윤고딕 740": { - 374: "τ", - 439: "ε", - 447: "ξ", - 463: "ζ", - 486: "ς", - 492: "λ", - 542: "θ", - 546: "χ", - 548: "μ", - 550: "υ", - 555: "η", - 556: "δ", - 570: "Γα", - 571: "β", - 573: "ρ", - 600: "Σ", - 603: "σ", - 648: "Ξ", - 652: "φ", - 667: "Λ", - 670: "π", - 671: "Δ", - 725: "Π", - 728: "ψ", - 761: "Ω", - 779: "ω", - 831: "Ψ", - 837: "Φ", - }, - "HY동녘B": { - 383: "τ", - 450: "ε", - 458: "ξ", - 475: "ζ", - 504: "λ", - 556: "θ", - 559: "χ", - 561: "μ", - 563: "υ", - 569: "δη", - 584: "Γα", - 585: "β", - 587: "ρ", - 614: "Σ", - 618: "σ", - 664: "Ξ", - 668: "φ", - 683: "Λ", - 686: "π", - 687: "Δ", - 742: "Π", - 745: "ψ", - 779: "Ω", - 798: "ω", - 851: "Ψ", - 857: "Φ", - }, - "HY수평선B": { - 383: "τ", - 450: "ε", - 458: "ξ", - 475: "ζ", - 504: "λ", - 556: "θ", - 559: "χ", - 561: "μ", - 563: "υ", - 569: "δη", - 584: "Γα", - 585: "β", - 587: "ρ", - 614: "Σ", - 618: "σ", - 664: "Ξ", - 668: "φ", - 683: "Λ", - 686: "π", - 687: "Δ", - 742: "Π", - 745: "ψ", - 779: "Ω", - 798: "ω", - 851: "Ψ", - 857: "Φ", - }, - "HY태백B": { - 383: "τ", - 450: "ε", - 458: "ξ", - 475: "ζ", - 504: "λ", - 556: "θ", - 559: "χ", - 561: "μ", - 563: "υ", - 569: "δη", - 584: "Γα", - 585: "β", - 587: "ρ", - 614: "Σ", - 618: "σ", - 664: "Ξ", - 668: "φ", - 683: "Λ", - 686: "π", - 687: "Δ", - 742: "Π", - 745: "ψ", - 779: "Ω", - 798: "ω", - 851: "Ψ", - 857: "Φ", - }, -} +#: Advances Hancom Office 2024 lays italic glyphs out at in the faces it draws italic in faces of their own +#: (in each face's units per em), where they differ from the regular ones. +ITALIC_ADVANCES: dict[str, dict[int, str]] = _by_key(_TABLES["ITALIC_ADVANCES"]) #: Advances Hancom Office 2024 lays bold italic glyphs out at where they differ from the italic ones and a bold -#: italic glyph is not widened as a bold one is (see ``measure._BOLD_WIDER_FACES``): measured on the desktop. -BOLD_ITALIC_ADVANCES: dict[str, dict[int, str]] = { - "HCI Poppy": { - 444: "·", - 470: "°", - 682: "×", - 684: "±", - 690: "÷", - }, -} +#: italic glyph is not widened as a bold one is (see ``measure._BOLD_WIDER_FACES``). +BOLD_ITALIC_ADVANCES: dict[str, dict[int, str]] = _by_key(_TABLES["BOLD_ITALIC_ADVANCES"]) + +del _TABLES diff --git a/src/hwpx/layout/_page_measure.py b/src/hwpx/layout/_page_measure.py new file mode 100644 index 00000000..42ceca38 --- /dev/null +++ b/src/hwpx/layout/_page_measure.py @@ -0,0 +1,3009 @@ +# SPDX-License-Identifier: Apache-2.0 +"""What the page estimate measures: the lower half of :mod:`hwpx.layout.pages`. + +:mod:`hwpx.layout.pages` describes what the estimate follows. It is one model in two files, because a single +file passed the 256 KiB a plugin directory reads of one file: this module holds the constants, the paragraph +and table model (:class:`_Measure`, the rows and lines of cells, the objects' extents) and the rows of a +flowing table; :mod:`~hwpx.layout.pages` holds the paragraphs' flow over pages and columns, and the public +names. Nothing here refers to :mod:`~hwpx.layout.pages`, which imports every name defined here, so +``hwpx.layout.pages._Measure`` and the like are these objects. +""" + +from __future__ import annotations + +import copy +import math +from collections.abc import Collection +from dataclasses import dataclass, field, replace +from typing import Any + +from ..form_fit.measure import ( + _DEFAULT_TAB_STOP, + _GLYPH_SPACE, + _TYPED_NO_BREAK_SPACE, + char_advance, + font_line_height, + hancom_line_starts, + in_char_units, + indented_widths, + margins_doubled, + paragraph_label, + text_style_from_refs, +) +from ..oxml._document_primitives import _remove_stale_paragraph_layout_cache +from ..oxml.namespaces import HH, HP +from ..oxml.paragraph_heading import paragraph_heading +from ..oxml.section import _remove_short_paragraph_layout_cache +from ..oxml.header_part import HwpxOxmlHeader +from ..oxml.table_sizes import cell_margins_of, grid_widths_of + +#: Objects in a run, placed by their ``hp:pos``. +_OBJECTS = frozenset({ + "tbl", "pic", "rect", "ellipse", "line", "arc", "polygon", "curve", "connectLine", "textart", + "container", "ole", "equation", "video", "chart", "checkBtn", "radioBtn", "btn", "button", + "comboBox", "edit", "listBox", "scrollBar", +}) +#: How an object in front of or behind the text wraps it: it takes no room from the text. +_FLOATING = frozenset({"IN_FRONT_OF_TEXT", "BEHIND_TEXT"}) +#: Run content that takes its place in the text like a character: composed characters and ruby text. +_MARKS = frozenset({"compose", "dutmal"}) +#: A flowing table's rows use the body only down to this far above its foot: a row, or a cell line of +#: a row split between its lines, ending lower goes on to the next page, and a row whose declared +#: height leaves room under its text (CELL) is cut there. What is left of such a row goes on to the +#: next page unless it is _SPARE_DROPPED or less, which is dropped (the row ends at the page's foot). +#: Both in HWPUNIT, as Hancom lays such rows out whatever the cells' margins, vertical alignment and +#: character size. A table set not to be adjusted (hp:tbl@noAdjust) uses _SPARE_CUT_FIXED instead. +_SPARE_CUT = 101 +_SPARE_CUT_FIXED = 2 +_SPARE_DROPPED = 1282 +#: The narrowest line FormFit breaks at, in HWPUNIT. +_MIN_LINE_WIDTH = 1440 +#: How tall Hancom makes a table's row that only cells merged over rows cover at least, unless the table is set +#: not to adjust its cells (``hp:tbl@noAdjust``): it starts the merged cells' heights from that. +_MERGED_ROW_LEAST = 100 +#: the room a cell that never breaks its text into lines (``hp:subList@lineWrap`` SQUEEZE or KEEP) gives a line +_NO_WRAP = 1 << 40 +#: The narrowest side of a square-wrapped object text goes to (1/5 inch): Hancom leaves a narrower one empty. +_MIN_SIDE = 1440 + + +class _Unsupported(Exception): + """Something the estimate does not follow.""" + + +# -- the paragraph model ------------------------------------------------------------------------ + + +def _local(element: Any) -> str: + tag = element.tag + return tag.rsplit("}", 1)[-1] if isinstance(tag, str) else "" + + +def _child(element: Any, name: str) -> Any: + return next((child for child in element if _local(child) == name), None) + + +def _char_unit_height(header: Any) -> int: + """The character size of the first paragraph style (바탕글), which margins in ``unit="CHAR"`` count in.""" + + style = next((el for el in header.iter(f"{HH}style") if el.get("id") == "0"), None) + ref = style.get("charPrIDRef") if style is not None else None + shape = next((el for el in header.iter(f"{HH}charPr") if el.get("id") == ref), None) if ref is not None else None + return int(shape.get("height", 1000)) if shape is not None else 1000 + + +@dataclass(frozen=True) +class _Shape: + """What the estimate reads from a paragraph shape (``hh:paraPr``).""" + + kind: str + value: int + prev: int + next: int + left: int + right: int + indent: int + flags: dict[str, str] + font_line: bool = False # its lines as tall as the font makes them (fontLineHeight) + snap: bool = True # its lines on the section's line grid (snapToGrid) + + +def _para_shape(header: Any, para_pr_id: str, doubled: bool = False) -> _Shape: + """The paragraph shape *para_pr_id*. With *doubled* (a document an older Hancom saved, see + :func:`~hwpx.form_fit.measure.margins_doubled`), margins and a line spacing in HWPUNIT outside + ``hp:switch`` hold twice the values Hancom lays out with, as ``hp:default`` does.""" + + shape = next((el for el in header.iter(f"{HH}paraPr") if el.get("id") == para_pr_id), None) + if shape is None: + raise _Unsupported(f"paragraph shape {para_pr_id} is missing") + # The hp:case holding margin and lineSpacing: outline levels 8-10 put hh:heading in an earlier switch. + case = next((c for c in shape.iter(f"{HP}case") if _child(c, "lineSpacing") is not None), None) + holder = case if case is not None else shape + spacing = _child(holder, "lineSpacing") + margin = _child(holder, "margin") + half = 2 if doubled and case is None else 1 + + def value(name: str) -> int: + element = _child(margin, name) if margin is not None else None + if element is None: + return 0 + if element.get("unit") == "CHAR": # two-hundredths of 바탕글's character size + return in_char_units(int(element.get("value", 0)), _char_unit_height(header)) // half + return int(element.get("value", 0)) // half + + breaks = shape.find(f"{HH}breakSetting") + kind, amount = ("PERCENT", 160) + if spacing is not None: + kind, amount = spacing.get("type", "PERCENT"), int(spacing.get("value", 160)) + if kind != "PERCENT" and spacing.get("unit") == "CHAR": # as a margin in that unit + amount = in_char_units(amount, _char_unit_height(header)) + elif kind != "PERCENT": + amount //= half + return _Shape(kind, amount, value("prev"), value("next"), value("left"), value("right"), value("intent"), + dict(breaks.attrib) if breaks is not None else {}, shape.get("fontLineHeight") in ("1", "true"), + shape.get("snapToGrid", "1") not in ("0", "false")) + + +def _pitch(kind: str, value: int, size: int) -> int: + """The distance from one line's top to the next line's top in a paragraph.""" + + if kind == "FIXED": + return value + if kind == "BETWEEN_LINES": + return size + value + if kind == "AT_LEAST": + return max(size, value) + # PERCENT: the spacing over the size is counted in 1/1800 inch from the em (height // 4), rounded. + extra = (size // 4) * (value - 100) / 100 + units = int(abs(extra) + 0.5) + return size + 4 * (units if extra >= 0 else -units) + + +def _object_pitch(shape: _Shape, obj: Any, tall: int, size: int) -> int: + """The distance from the top of a line *tall* tall holding only *obj*, an object set as a character, to the + next line's top in a paragraph of *shape* whose characters are *size*: a percentage spacing is the + characters' unless the object is set to affect the line spacing (``hp:pos@affectLSpacing``), when it is the + line's, as any other spacing is -- a fixed one keeps the next line that far down even below a taller object, + an at-least one at the line's height when that is more.""" + + if shape.kind == "PERCENT" and obj.find(f"{HP}pos").get("affectLSpacing") != "1": + return tall + _pitch(shape.kind, shape.value, size) - size + return _pitch(shape.kind, shape.value, tall) + + +def _on(flags: dict[str, str], name: str) -> bool: + return flags.get(name) in ("1", "true") + + +def _t_text(text_element: Any) -> str: + """The text of one ``hp:t``, with ``hp:lineBreak`` as a newline, ``hp:tab`` as a tab, ``hp:nbSpace`` as a + no-break space (U+00A0) and ``hp:fwSpace`` as a fixed-width one (U+3000), as python-hwpx reads them; an + ideographic space typed in the text is FormFit's ``_GLYPH_SPACE``, so it is not taken for a fixed-width one, and + a no-break space typed in it ``_TYPED_NO_BREAK_SPACE``, which Hancom lays out at the font's own width. + A table-of-contents mark (``hp:titleMark``) is a character of no width (U+200D): Hancom lays its line out as + tall as the mark's run and spaces it from that size.""" + + parts = [text_element.text or ""] + for child in text_element: + name = _local(child) + parts.append({"lineBreak": "\n", "tab": "\t", "nbSpace": "\u00a0", "fwSpace": "\u3000", + "titleMark": "\u200d"}.get(name, "")) + parts.append(child.tail or "") + return "".join(part.replace("\u3000", _GLYPH_SPACE).replace("\u00a0", _TYPED_NO_BREAK_SPACE) if index % 2 == 0 + else part for index, part in enumerate(parts)) + + +def _indented(line: float, shape: _Shape, style: Any) -> list[float]: + """The first line's and the other lines' room of a paragraph of *shape* *line* wide inside its margins: less + its first-line indent (a hanging one narrows the other lines) and its bullet or number label's room + (``style.head``, see :func:`hwpx.form_fit.measure.indented_widths`). Hancom drops an indent that leaves its + line less room than its narrowest line (:data:`_MIN_LINE_WIDTH`): every line is *line* wide then. A + paragraph whose shape squeezes it (``lineWrap`` SQUEEZE) is never broken into lines: Hancom presses it onto one.""" + + if style is not None and getattr(style, "line_wrap", "BREAK") == "SQUEEZE": + return [_NO_WRAP, _NO_WRAP] + if style is not None and style.head: + return list(indented_widths(line, replace(style, indent=shape.indent))) + rooms = [line - max(shape.indent, 0), line - max(-shape.indent, 0)] + return [line, line] if min(rooms) < _MIN_LINE_WIDTH else rooms + + +def _line_widths(shape: _Shape, width: int, style: Any = None) -> list[float]: + """The first line's and the other lines' widths of a paragraph of *shape* in *width*: less its margins, + its first-line indent (a hanging one narrows the other lines) and its label's room.""" + + return [max(room, _MIN_LINE_WIDTH) for room in _indented(width - shape.left - shape.right, shape, style)] + + +def _drawn_labels(root: Any) -> dict[Any, str]: + """The label Hancom draws for each numbered, outline and bullet paragraph, counted in reading order: the body's + paragraphs, each followed by those of the tables, text boxes and captions placed in it.""" + + from ..tools.exporter import _ListLabels, _paragraph_pieces, _text_box_paragraphs + + labels = _ListLabels(root.headers[0].element if root.headers else None) + drawn: dict[Any, str] = {} + + def visit(paragraph: Any) -> None: + label = labels.label(paragraph) + if label: + drawn[paragraph] = label + for piece in _paragraph_pieces(paragraph): + if isinstance(piece, str): + continue + if piece.tag == f"{HP}tbl": + for cell in piece.findall(f"{HP}tr/{HP}tc"): + for inner in cell.findall(f"{HP}subList/{HP}p"): + visit(inner) + else: + for inner in _text_box_paragraphs(piece): + visit(inner) + + for section in root.sections: + labels.start_section(section.element) + for paragraph in section.element.findall(f"{HP}p"): + visit(paragraph) + return drawn + + +def _run_text(runs: list[Any]) -> str: + return "".join(_t_text(t) for run in runs for t in run.findall(f"{HP}t")) + + +def _cache_lines(paragraph: Any) -> int: + """How many lines the paragraph's own layout cache holds; 0 when it has none or the save path + would drop it as not matching the text.""" + + segments = paragraph.findall(f"{HP}linesegarray/{HP}lineseg") + if not segments: + return 0 + probe = copy.deepcopy(paragraph) + if _remove_stale_paragraph_layout_cache(probe) or _remove_short_paragraph_layout_cache(probe): + return 0 + return len(segments) + + +def _cached_metrics(paragraph: Any) -> tuple[tuple[int, int], ...]: + """(height, advance) of each line of the paragraph's own valid layout cache: the next line of a + paragraph starts the line's text height plus its spacing lower (``vertsize`` can be larger, for a + line an object set as a character follows). Empty without a valid cache.""" + + if not _cache_lines(paragraph): + return () + metrics = [] + segments = paragraph.findall(f"{HP}linesegarray/{HP}lineseg") + for segment, following in zip(segments, [*segments[1:], None]): + height = int(segment.get("textheight", segment.get("vertsize", 0))) + if height <= 0: # a cache of empty lines is none + return () + beside = following is not None and following.get("vertpos") == segment.get("vertpos") \ + and int(following.get("horzpos", 0)) > int(segment.get("horzpos", 0)) # two pieces of one line + metrics.append((height, 0 if beside else height + int(segment.get("spacing", 0)))) + return tuple(metrics) + + +class _Lookups: + """The shape lookups FormFit's text style reads, with the paragraph shapes and tab definitions read once: + the document reads them from the header again on every lookup. (No ``_root`` attribute, so FormFit + uses this object and not the document behind it.)""" + + def __init__(self, root: Any) -> None: + self._document = root + self.headers = root.headers + self.version = root.version # how the paragraph shapes' margins outside hp:switch read + self.sections = root.sections # the outline numbering of a paragraph's label + self._paragraph_shapes: dict[str, Any] | None = None + self._tab_definitions: dict[str, Any] | None = None + + def char_property(self, char_pr_id: Any) -> Any: + return self._document.char_property(char_pr_id) + + def paragraph_property(self, para_pr_id: Any) -> Any: + if self._paragraph_shapes is None: + self._paragraph_shapes = self._document.paragraph_properties + return HwpxOxmlHeader._lookup_by_id(self._paragraph_shapes, para_pr_id) + + def tab_property(self, tab_pr_id: Any) -> Any: + if self._tab_definitions is None: + self._tab_definitions = self._document.tab_properties + return HwpxOxmlHeader._lookup_by_id(self._tab_definitions, tab_pr_id) + + +class _Measure: + """Shapes and line breaking of one document.""" + + def __init__(self, root: Any) -> None: + self._root = root + self._lookups = _Lookups(root) + self._header = root.headers[0].element + self._doubled = margins_doubled(root) + self._shapes: dict[str, _Shape] = {} + self._styles: dict[tuple[str, tuple[str, ...], str | None], Any] = {} + self._drawn: dict[Any, str] | None = None + self._numbered: dict[str, bool] = {} + self._label_sizes: dict[str, int] = {} + self._pictured: dict[str, bool] = {} + self._boxes: dict[str, int] = {} + self._edges: dict[str, int] | None = None + #: how far apart the default tab stops of the section at hand are (see :func:`_tab_stop`) + self.tab_stop = _DEFAULT_TAB_STOP + + def shape(self, para_pr_id: Any) -> _Shape: + key = str(para_pr_id) + if key not in self._shapes: + self._shapes[key] = _para_shape(self._header, key, self._doubled) + return self._shapes[key] + + def char_height(self, char_pr_id: Any) -> int: + style = self._root.char_property(char_pr_id) + return int(style.attributes.get("height", 1000)) if style is not None else 1000 + + def char_box(self, char_pr_id: Any) -> int: + """How tall a character of *char_pr_id* makes its line: its height, and the width of a border its shape + draws above and below it (Hancom: the line that much taller, spaced from that height).""" + + if self._edges is None: # each border fill's width above and below, read once from the header + self._edges = {} + for fill in self._header.iter(f"{HH}borderFill"): + self._edges[fill.get("id")] = sum( + round(float(rule.get("width", "0 mm").split()[0]) * 7200 / 25.4) + for rule in (fill.find(f"{HH}topBorder"), fill.find(f"{HH}bottomBorder")) + if rule is not None and rule.get("type", "NONE") != "NONE") + key = str(char_pr_id) + if key not in self._boxes: + style = self._root.char_property(char_pr_id) + fill = style.attributes.get("borderFillIDRef") if style is not None else None + self._boxes[key] = self.char_height(char_pr_id) + self._edges.get(fill, 0) + return self._boxes[key] + + def font_line(self, size: int, style: Any) -> int: + """How tall a line of characters *size* tall in *style* is in a paragraph taking its line height from + the font (see :func:`~hwpx.form_fit.measure.font_line_height`); *size* for a face the glyph table does + not list.""" + + tall = font_line_height(getattr(style, "hangul_face", None), size) + return size if tall is None else tall + + def headed(self, paragraph: Any) -> bool: + """Whether Hancom heads *paragraph* with a bullet or number label.""" + + if self._drawn is None: + self._drawn = _drawn_labels(self._root) + return bool(self._drawn.get(paragraph)) + + def style(self, para_pr_id: Any, char_pr_ids: list[Any], paragraph: Any = None) -> Any: + """FormFit's text style of a paragraph shape and its characters; with *paragraph*, a number's label + takes the room of the label Hancom draws for that paragraph, and a label without a character shape of + its own that of the paragraph's end.""" + + drawn = None + if paragraph is not None and self.numbered(para_pr_id): + if self._drawn is None: + self._drawn = _drawn_labels(self._root) + drawn = self._drawn.get(paragraph) + end = _end_ref(paragraph) if paragraph is not None else None + key = (str(para_pr_id), tuple(str(ref) for ref in char_pr_ids), drawn, end, self.tab_stop) + if key not in self._styles: + style = text_style_from_refs(self._lookups, para_pr_id, char_pr_ids, drawn, end) + if style is not None and style.tab_stop != self.tab_stop: + style = replace(style, tab_stop=self.tab_stop) + self._styles[key] = style + return self._styles[key] + + def label_size(self, para_pr_id: Any, end: Any = None) -> int: + """The character size of a paragraph shape's bullet or number label: in its own character shape + (``hh:paraHead@charPrIDRef``), or without one in that of the paragraph's end (*end*); 0 when it has + none, or no shape of its own and no *end*.""" + + key = str(para_pr_id) + if key not in self._label_sizes: + label = paragraph_label(self._root, para_pr_id) + ref = label[1].get("charPrIDRef") if label is not None else None + own = ref is not None and ref != "4294967295" and self._root.char_property(ref) is not None + self._label_sizes[key] = self.char_height(ref) if own else -1 if label is not None else 0 + size = self._label_sizes[key] + return size if size >= 0 else self.char_height(end) if end is not None else 0 + + def copied(self, copies: dict[Any, Any]) -> None: + """Give each copied paragraph in *copies* (copy -> original) the label Hancom draws for its original.""" + + if self._drawn is None: + self._drawn = _drawn_labels(self._root) + self._drawn.update({copy: self._drawn[original] for copy, original in copies.items() + if original in self._drawn}) + + def pictured(self, para_pr_id: Any) -> bool: + """Whether a paragraph shape heads its paragraphs with a picture bullet sized by its picture + (``hh:paraHead@useInstWidth``), whose room was not measured: FormFit gives it none.""" + + key = str(para_pr_id) + if key not in self._pictured: + shape = next((el for el in self._header.iter(f"{HH}paraPr") if el.get("id") == key), None) + heading = paragraph_heading(shape) if shape is not None else None + bullet = next((el for el in self._header.iter(f"{HH}bullet") if el.get("id") == heading.get("idRef")), + None) if heading is not None and heading.get("type") == "BULLET" else None + head = bullet.find(f"{HH}paraHead") if bullet is not None else None + self._pictured[key] = bullet is not None and bullet.get("useImage") in {"1", "true"} \ + and head is not None and head.get("useInstWidth") in {"1", "true"} + return self._pictured[key] + + def numbered(self, para_pr_id: Any) -> bool: + """Whether a paragraph shape heads its paragraphs with a number (``NUMBER`` or ``OUTLINE``).""" + + key = str(para_pr_id) + if key not in self._numbered: + shape = next((el for el in self._header.iter(f"{HH}paraPr") if el.get("id") == key), None) + heading = paragraph_heading(shape) if shape is not None else None + self._numbered[key] = heading is not None and heading.get("type") in {"NUMBER", "OUTLINE"} + return self._numbered[key] + + def lines(self, text: str, widths: list[float], size: int, style: Any) -> int: + """How many lines FormFit breaks *text* into (a newline starts a line).""" + + if not text: + return 1 + return sum(len(hancom_line_starts(line, widths if not index else widths[1:] or widths, size / 100, style, + continued=bool(index))) if line else 1 + for index, line in enumerate(text.split("\n"))) # the lines after a line break are no first line + + def line_starts(self, text: str, widths: list[float], size: int, style: Any, + sizes: list[int] | None = None, styles: list[Any] | None = None, + advances: dict[int, int] | None = None, objects: Collection[int] = ()) -> list[int]: + """Where each line starts, as offsets into *text*; *sizes* and *styles* are each character's size + and style when the text mixes them, *advances* the width of each object set as a character (or + mark), *objects* the places of the objects.""" + + starts: list[int] = [] + base = 0 + for number, line in enumerate(text.split("\n")): + points = None if sizes is None else [height / 100 for height in sizes[base:base + len(line)]] + looks = None if styles is None else styles[base:base + len(line)] + fixed = None if advances is None else { + index - base: width for index, width in advances.items() if base <= index < base + len(line)} + placed = {index - base for index in objects if base <= index < base + len(line)} + room = widths if not number else widths[1:] or widths # the lines after a line break are no first line + starts += [base + start for start in (hancom_line_starts(line, room, size / 100, style, points, looks, + fixed, placed, continued=bool(number)) + if line else [0])] + base += len(line) + 1 + return starts + + def stack(self, paragraphs: list[Any], width: int, caches: bool, + floating: bool = False, lead: int = 0) -> tuple[int, int, int, int]: + """(height, lines, pitch, size) of *paragraphs* laid out one under another at *width*; pitch + and size are the last paragraph's. With *caches* a paragraph keeps the lines of its cache. With + *floating* (a cell's paragraphs) the height reaches down to the foot of any object in front of or + behind the text placed from a paragraph's top (see :func:`_floating_reach`). *lead* is room above + the first paragraph's lines (a cell's first paragraph's spacing before): Hancom places an object + from that paragraph's top above it.""" + + height, lines, pitch, size, pending, far = lead, 0, 0, 0, None, 0 + for paragraph in paragraphs: + runs = paragraph.findall(f"{HP}run") + size, refs, _ = _text_size(self, runs, paragraph) # an empty run takes no room, as in the body + shape = self.shape(paragraph.get("paraPrIDRef")) + pitch = _pitch(shape.kind, shape.value, size) + table = _table_alone(runs) + alone = None if table is not None or caches and _cached_metrics(paragraph) else _object_alone(runs) + spread = self.spread_lines(paragraph, runs, width, caches=caches) \ + if table is not None or alone is not None else () + if spread: # spaces besides it, some of which go on to the next line + table = alone = None + if table is not None: # one line as tall as the table, spaced like the text + tall = _inline_table_height(self, table) + _extent_margins(table) + sum(_caption(self, table)) + count, size, pitch = 1, tall, _object_pitch(shape, table, tall, size) + elif alone is not None: # so with another object set as a character + tall = _object_extent(alone, self)[1] + count, size, pitch = 1, tall, _object_pitch(shape, alone, tall, size) + else: + cached = spread or (_cached_metrics(paragraph) if caches else ()) + cached = cached or self.pushed_lines(paragraph, runs, width) \ + or self.marked_lines(paragraph, runs, width) or self.mixed_lines(paragraph, runs, shape, width) + if cached: # the lines Hancom laid out, each as tall as it drew it + anchor = height - lead if pending is None else height + pending + shape.prev + above = lead if pending is None else shape.prev # its spacing before, above its line + if pending is not None: + height += pending + shape.prev + top = height + far = max(far, anchor + _floating_reach(runs, self)) if floating else far + height += sum(advance for _, advance in cached[:-1]) + cached[-1][0] + size, pitch = cached[-1] + pending = pitch - size + shape.next + if top + _objects_reach(runs, self, above) > height: # an object placed from it reaches lower + height, pending = top + _objects_reach(runs, self, above), shape.next + lines += len(cached) + continue + style = self.style(paragraph.get("paraPrIDRef"), refs, paragraph) + count = (_cache_lines(paragraph) if caches else 0) or self.lines( + _run_text(runs), _line_widths(shape, width, style), size, style + ) + # an empty line keeps the character size: Hancom makes only a line of characters as tall as + # its font makes it + anchor = height - lead if pending is None else height + pending + shape.prev + above = lead if pending is None else shape.prev # its spacing before, above its line + if pending is not None: + height += pending + shape.prev + top = height + far = max(far, anchor + _floating_reach(runs, self)) if floating else far + height += (count - 1) * pitch + size + pending = pitch - size + shape.next + if top + _objects_reach(runs, self, above) > height: # an object placed from the paragraph reaches lower + height, pending = top + _objects_reach(runs, self, above), shape.next + lines += count + return max(height, far), lines, pitch, size + + def mixed_lines(self, paragraph: Any, runs: list[Any], shape: _Shape, width: int) -> tuple[tuple[int, int], ...]: + """(height, advance) of each line of a paragraph whose characters differ in size or style, or that takes + its line height from the font, laid out at *width* as in the body; empty for any other paragraph.""" + + _, refs, sizes = _text_size(self, runs) + looks = _char_styles(self, paragraph, runs) + end = _end_size(self, runs, sizes) + head = _head_size(self, paragraph, sizes) + held = _held_sizes(self, runs, sizes) + if len(set(sizes)) < 2 and looks is None and not end and not head and not held and not (shape.font_line and sizes): + return () + style = self.style(paragraph.get("paraPrIDRef"), refs, paragraph) + return _line_metrics(self, _run_text(runs), _line_widths(shape, width, style), sizes, style, shape, {}, looks, + end=end, head=head, held=held) + + def stack_lines(self, paragraphs: list[Any], width: int, caches: bool, + pieces: bool = False) -> tuple[tuple[int, int], ...]: + """(height, advance to the next line's top) of every line of *paragraphs* laid out as in + :meth:`stack`, a table set as a character alone in its paragraph as one line; with *pieces*, a table + that splits on its own in a paragraph as its pieces (see :func:`_table_pieces`).""" + + metrics: list[tuple[int, int]] = [] + for paragraph in paragraphs: + shape = self.shape(paragraph.get("paraPrIDRef")) + if metrics: # the gap between the paragraphs + last_height, last_advance = metrics[-1] + metrics[-1] = (last_height, last_advance + shape.prev) + runs = paragraph.findall(f"{HP}run") + split = _table_pieces(self, paragraph) if pieces else None + if split is not None: # a table placed top and bottom on its own: its rows (or their lines) + lines = split[0] + metrics += list(lines[:-1]) + [(lines[-1][0], lines[-1][1] + shape.next)] + continue + cached = () if _table_alone(runs) is not None or not caches else _cached_metrics(paragraph) + cached = cached or self.spread_lines(paragraph, runs, width, caches=caches) + if not cached and _table_alone(runs) is None: # each line as tall as stack makes it + cached = self.pushed_lines(paragraph, runs, width) or self.marked_lines(paragraph, runs, width) \ + or self.mixed_lines(paragraph, runs, shape, width) + if cached: + metrics += list(cached[:-1]) + [(cached[-1][0], cached[-1][1] + shape.next)] + continue + height, count, pitch, size = self.stack([paragraph], width, caches) + last = height - (count - 1) * pitch # down to the foot of an object placed from it: the next below + metrics += [(size, pitch)] * (count - 1) + [(last, (last if last > size else pitch) + shape.next)] + return tuple(metrics) + + def spread_lines(self, paragraph: Any, runs: list[Any], width: int, end: int = 0, head: int = 0, + caches: bool = False) -> tuple[tuple[int, int], ...]: + """(height, advance) of each line of a paragraph holding one object set as a character and, besides it, + only spaces or line breaks, when Hancom lays it out on several lines: a space before the object is text + (the object goes on to the next line when it does not fit after it), the two spaces right after it hang + past the margin and a further one starting there begins the next line, and a line break begins one (an + empty line before the object goes down as a line of text); empty for any other paragraph, or one of a + line. With *caches* a paragraph with a valid layout cache keeps Hancom's lines.""" + + objects = _placed_objects(runs) + text = _run_text(runs) + if len(objects) != 1 or not text or text.strip() or objects[0].find(f"{HP}pos").get("treatAsChar") != "1": + return () + own = _cached_metrics(paragraph) if caches else () + if own: + return own if len(own) > 1 else () + shape = self.shape(paragraph.get("paraPrIDRef")) + if shape.kind not in ("PERCENT", "FIXED"): + return () + inline, sizes, looks, placed, marked = _inline_content(self, paragraph, runs) + style = self.style(paragraph.get("paraPrIDRef"), [run.get("charPrIDRef") for run in runs] or ["0"], paragraph) + lines = _line_metrics(self, inline, _line_widths(shape, width, style), sizes, style, shape, placed, + looks if len(set(looks)) > 1 else None, marked, end, head) + return lines if len(lines) > 1 else () + + def pushed_lines(self, paragraph: Any, runs: list[Any], width: int) -> tuple[tuple[int, int], ...]: + """(height, advance) of each line of a cell paragraph without a layout cache whose text follows a table + placed top and bottom from its top: the first line reaching the table (with a caption above or below + it) and the lines after it go below it, and the paragraph reaches down to the table's foot at least; + empty for any other paragraph.""" + + obj = _object_before_text(runs, self.headed(paragraph)) + if obj is None or _local(obj) != "tbl" and obj.find(f"{HP}pos").get("flowWithText") == "0": + return () # a picture or drawing that stays put pushes no line aside in a cell + top = _down(obj.find(f"{HP}pos")) + foot = top + (_cell_extent(self, obj) if _local(obj) == "tbl" else _extent(obj, "height", self)) + shape = self.shape(paragraph.get("paraPrIDRef")) + lines = list(self.marked_lines(paragraph, runs, width) or self.mixed_lines(paragraph, runs, shape, width)) + if not lines: + size, refs, _ = _text_size(self, runs, paragraph) + style = self.style(paragraph.get("paraPrIDRef"), refs, paragraph) + count = max(1, self.lines(_run_text(runs), _line_widths(shape, width, style), size, style)) + lines = [(size, _pitch(shape.kind, shape.value, size))] * count # an empty line keeps its size + y = 0 + for index, (height, advance) in enumerate(lines): + if y < foot and y + height > top: # it reaches the table: below it, and the lines after it; it takes + lines[index] = (height + foot - y, advance + foot - y) # the room above it (and goes on to a next + break # page with the table) + y += advance + above = sum(advance for _, advance in lines[:-1]) + if above + lines[-1][0] < foot: # every line above the table: the paragraph holds it + lines[-1] = (foot - above, foot - above) + return tuple(lines) + + def wrapped_lines(self, paragraphs: list[Any], width: int, tables: bool = False + ) -> tuple[tuple[tuple[int, int], ...], tuple[int, ...], tuple[_Reach, ...]]: + """(height, advance) of every line of a cell's *paragraphs*, and the room above each when a part of the + cell starts with it (a paragraph's spacing before at its first line), when one of them holds a picture + or drawing placed top and bottom or square from its top that moves with the text (see + :func:`_wraps_in_cell`; with *tables*, a table so placed, or in front of or behind the text, too); + empty for any other cell. Hancom stands such an object its offset below the + top of the line its control falls on (the paragraph laid out the cell's whole width), or of the + paragraph, above its spacing before, when that is the first line (an offset up counts as none), and + lays every line from there on, of that paragraph and the next ones, clear of it (see :func:`_clear_of`). + The cell reaches down to the lowest object's foot, and to that of any object in front of or behind + the text placed from a paragraph's top (see :func:`_floating_reach`; such a table stands from the top + of the line its control falls on, as an object wrapped does, and pushes no line aside). A paragraph + with a valid layout cache keeps its lines. With *tables*, also where each object stands among the lines + (see :class:`_Reach`).""" + + owned = [[obj for run in paragraph.findall(f"{HP}run") for obj in run if _wraps_in_cell(obj, tables)] + for paragraph in paragraphs] + floats = [[obj for run in paragraph.findall(f"{HP}run") for obj in run + if tables and _local(obj) == "tbl" and _floating(obj)] for paragraph in paragraphs] + if not any(owned) and not any(floats) or any(len(objects) + len(over) > 1 + for objects, over in zip(owned, floats)): + return (), (), () # several in a paragraph: Hancom stacks them, which is not followed here (they + # count as before) + for table in (obj for over in floats for obj in over): + pos = table.find(f"{HP}pos") + if pos.get("flowWithText") == "0" or pos.get("vertRelTo") != "PARA" or pos.get("vertAlign", "TOP") != "TOP": + raise _Unsupported("a table in front of or behind the text in a cell placed otherwise than from " + "its paragraph's top, moving with the text") + bands: list[tuple[int, int, int | None]] = [] # top, foot and room beside it (None: the lines go below) + tops: list[int] = [] + heights: list[int] = [] + leads: list[int] = [] + reaches: list[_Reach] = [] + after = 0 # where the next paragraph's first line stands, above its spacing before + far = 0 # the foot of the lowest object in front of or behind the text + for paragraph, objects, over in zip(paragraphs, owned, floats): + obj = objects[0] if objects else None + shape = self.shape(paragraph.get("paraPrIDRef")) + runs = paragraph.findall(f"{HP}run") + text = _run_text(runs) + empty = not text and not self.headed(paragraph) # a label is text + if obj is not None and _local(obj) == "tbl" and empty and obj.find(f"{HP}pos").get("allowOverlap") != "0": + raise _Unsupported("a table that may overlap the text placed top and bottom or square in an empty " + "cell paragraph") + top = after + shape.prev if tops else 0 + far = max(far, top + _floating_reach(runs, self)) + place = 0 if obj is None and not over else _control_place(runs, obj if obj is not None else over[0]) + fixed = list(_cached_metrics(paragraph)) # Hancom keeps the lines of a valid cache + simple = not fixed and _table_alone(runs) is None and not self.spread_lines(paragraph, runs, width) \ + and not self.marked_lines(paragraph, runs, width) \ + and not self.mixed_lines(paragraph, runs, shape, width) + anchor = 0 + mixed: tuple[tuple[int, int], ...] = () + if not fixed and not simple: + if obj is not None and obj.get("textWrap") == "TOP_AND_BOTTOM": + mixed = self.mixed_lines(paragraph, runs, shape, width) + if obj is not None and not mixed: + raise _Unsupported("an object placed top and bottom or square beside text laid out otherwise " + "in a cell") + # one placed top and bottom narrows no line: the lines of characters differing in size or style + # stand as they are, those up to the one its control falls on above it and the rest below + fixed = list(mixed) if mixed else list(self.stack_lines([paragraph], width, caches=True)) + if mixed and place: + size, refs, sizes = _text_size(self, runs, paragraph) + style = self.style(paragraph.get("paraPrIDRef"), refs, paragraph) + starts = self.line_starts(text, _line_widths(shape, width, style), size, style, sizes, + _char_styles(self, paragraph, runs)) + if len(starts) != len(fixed): + raise _Unsupported("an object placed top and bottom among text laid out otherwise in a cell") + anchor = sum(1 for start in starts[1:] if start < place) + if mixed: + fixed[-1] = (fixed[-1][0], fixed[-1][1] + shape.next) + elif fixed: + fixed[-1] = (fixed[-1][0], fixed[-1][1] + shape.next) + if fixed: + if place and not mixed: + raise _Unsupported("an object placed top and bottom or square after the text of a paragraph " + "with a layout cache in a cell") + lines, narrow, own = _clear_of(self, fixed, top, shape.prev, anchor, obj, bands, empty, width) + _beside_one_side(narrow, empty) + if narrow and not _cache_lines(paragraph): + raise _Unsupported("text laid out otherwise beside a square-wrapped object in a cell") + else: + size, refs, _ = _text_size(self, runs, paragraph) + style = self.style(paragraph.get("paraPrIDRef"), refs, paragraph) + pitch = _pitch(shape.kind, shape.value, size) # an empty line keeps the character size + full = _line_widths(shape, width, style) + starts = self.line_starts(text, full, size, style) if text else [0] + anchor = sum(1 for start in starts[1:] if start < place) + narrow = {} + for _ in range(10): # FormFit breaks the lines, and which are beside an object follows from them + rooms = [(_line_widths(shape, narrow[index], style) if index in narrow else full)[min(index, 1)] + for index in range(max(narrow, default=0) + 2)] + count = len(self.line_starts(text, rooms, size, style)) if text else 1 + metrics = [(size, pitch)] * (count - 1) + [(size, pitch + shape.next)] + lines, found, own = _clear_of(self, metrics, top, shape.prev, anchor, obj, bands, empty, width) + if found == narrow: + break + narrow = found + else: + raise _Unsupported("lines beside a square-wrapped object in a cell that do not settle") + _beside_one_side(narrow, empty) + if narrow and ("\n" in text or style.head): + raise _Unsupported("a paragraph with margins, a label or line breaks beside a square-wrapped " + "object in a cell") + if obj is not None and own is None: + raise _Unsupported("an object placed top and bottom or square past its paragraph's lines in a cell") + if own is not None: + bands.append(own) + anchor = min(anchor, len(lines) - 1) + line = top if anchor == 0 else lines[anchor - 1][0] + lines[anchor - 1][2] # where it would stand + if own is not None and tables: + if own[2] is None: # it pushes the lines below it: the first of them, where it would stand + pushed = next(((index, top if index == 0 else lines[index - 1][0] + lines[index - 1][2]) + for index in range(anchor, len(lines)) + if lines[index][0] > (top if index == 0 else lines[index - 1][0] + lines[index - 1][2])), + None) + reaches.append(_Reach(line, own[0], own[1], _table_first(self, obj), + None if pushed is None else pushed[1], + 0 if pushed is None else lines[pushed[0]][1], *_split_rows(self, obj))) + else: + reaches.append(_Reach(line, own[0], own[1])) + for table in over: # from the top of the line its control falls on, where that line would follow the + # one before (of the paragraph, above its spacing before, on its first line) + up = (top - shape.prev if anchor == 0 else line) + _down(table.find(f"{HP}pos")) + far = max(far, up + _cell_extent(self, table)) + reaches.append(_Reach(line, up, up + _cell_extent(self, table))) + for index, (line_top, height, advance) in enumerate(lines): + if index == 0 and line_top > top: # below an object: the line takes the room above it + height, line_top = height + line_top - top, top + elif index and tables and line_top > lines[index - 1][0] + lines[index - 1][2]: # so a later + # line (a table goes on over a page end with it) + follow = lines[index - 1][0] + lines[index - 1][2] + height, line_top = height + line_top - follow, follow + tops.append(line_top) + heights.append(height) + leads.append(shape.prev if index == 0 else 0) + after = lines[-1][0] + lines[-1][2] + heights[-1] = max(heights[-1], max((foot for _, foot, _ in bands), default=0) - tops[-1], far - tops[-1]) + if any(later < earlier for earlier, later in zip(tops, tops[1:])): + raise _Unsupported("lines in a cell placed up past an object placed top and bottom or square") + return tuple((height, (nxt - line_top) if nxt is not None else height) + for height, line_top, nxt in zip(heights, tops, [*tops[1:], None])), tuple(leads), tuple(reaches) + + def marked_lines(self, paragraph: Any, runs: list[Any], width: int) -> tuple[tuple[int, int], ...]: + """(height, advance) of each line of a paragraph holding composed characters, ruby text, or objects + set as characters among its text or several of them, laid out at *width* as in the body; empty for + a paragraph holding none of them.""" + + if not _marks(runs) and not _objects_among(runs): + return () + shape = self.shape(paragraph.get("paraPrIDRef")) + _check_ruby_spacing(runs, shape) + text, sizes, looks, placed, marked = _inline_content(self, paragraph, runs) + style = self.style(paragraph.get("paraPrIDRef"), [run.get("charPrIDRef") for run in runs] or ["0"], paragraph) + end = _end_size(self, runs, _text_size(self, runs)[2]) # an empty run ending it, as in the body + return _line_metrics(self, text, _line_widths(shape, width, style), sizes, style, shape, placed, + looks if len(set(looks)) > 1 else None, marked, end) + + +@dataclass(frozen=True) +class _Reach: + """Where an object placed from a cell paragraph stands among the cell's lines, from the top of its first line: + where the line its control falls on would stand (``line``), the object's top and foot, and, for a table + pushing the lines below it, how far below its top its first row ends (``first``; 0 for anything else), where + the first line it pushes below it would stand (``unit``; ``line`` when it pushes that very line) and how + tall that line is (``text``), and, for one that may split between its rows, the room above its first row, + the pieces it splits into and the room below its last row (``above``, ``rows``, ``below``; see + :func:`_split_rows`), with the table and its rows joined by merged cells, one piece each (where the + first's piece stands among the pieces, its first and last row), which a page end splits cell by cell.""" + + line: int + top: int + foot: int + first: int = 0 + unit: int | None = None + text: int = 0 + above: int = 0 + rows: tuple[tuple[int, int, int, int], ...] = () + below: int = 0 + table: _FlowTable | None = None + blocks: tuple[tuple[int, int, int], ...] = () + + +@dataclass(frozen=True) +class _Row: + height: int # the row's full height + lines: int # lines of its tallest cell, for splitting between them + pitch: int + size: int + margins: int # top + bottom cell margins + header: bool + merged: bool = False # under a cell merged over rows: no page break in or around it + joined: bool = False # a cell merged over rows joins it to the next row + spare: int = 0 # room the row's declared height leaves under its text + nested: bool = False # a cell holds a table + #: (height, advance) of each line of the row's tallest cell when it holds a table or several paragraphs + metrics: tuple[tuple[int, int], ...] = () + first: int = 0 # the tallest first line of any of its cells + #: the room above each of those lines when a part of the cell starts with it (a paragraph's spacing + #: before its first line, none before the others) + leads: tuple[int, ...] = () + #: its tables are placed top and bottom on their own and split (see :func:`_table_pieces`): its lines + #: (those tables' pieces among them) split as any cell's + pieces: bool = False + #: the room each of those lines needs below it to stay above a page end: a table's piece a table's cut + #: (101) more than a line of text + cuts: tuple[int, ...] = () + #: rows of those tables joined by merged cells, one piece each: (where the first's piece stands among the + #: lines, the table, its first and last row); a page end among them splits them cell by cell + blocks: tuple[tuple[int, _FlowTable, int, int], ...] = () + #: the tables among its tallest cell's text placed top and bottom, square, or in front of or behind it + #: (laid out by :meth:`_Measure.wrapped_lines`): a page end is not followed through them + reaches: tuple[_Reach, ...] = () + + +@dataclass(frozen=True) +class _FlowTable: + rows: list[_Row] + mode: str # hp:tbl@pageBreak: CELL, TABLE or NONE + repeat_header: bool + margins: tuple[int, int] # hp:outMargin top, bottom: kept above and below the table + #: every cell as (the position of its first row in ``rows``, rows it spans, the cell as a row) + cells: tuple[tuple[int, int, _Row], ...] = () + offset: int = 0 # alone in its paragraph: how far below the paragraph's line it starts + caption: tuple[int, int] = (0, 0) # a caption above it, below it: its lines and its gap + cut: int = _SPARE_CUT # how far above the body's foot its rows end at most + + @property + def above(self) -> int: + """Room above the first row: the top margin and a caption above.""" + + return self.margins[0] + self.caption[0] + + @property + def below(self) -> int: + """Room below the last row: a caption below and the bottom margin.""" + + return self.margins[1] + self.caption[1] + + +def _rows(measure: _Measure, table: Any) -> list[_Row]: + """Each row as its tallest cell of one row: the cell's declared height or its content with its + margins (a row with no cell of its own starts at 0). Then each cell merged over rows, the one + ending first first, adds what its rows lack to the last of them.""" + + return _table_rows(measure, table)[0] + + +def _table_rows(measure: _Measure, table: Any) -> tuple[list[_Row], list[tuple[int, int, _Row]]]: + """The rows (see :func:`_rows`) and every cell as (its first row's position, rows spanned, the cell + as a row). A table's cell spacing (``hp:tbl@cellSpacing``) stands above each row: every cell is that much + taller (a cell merged over rows spans the spacings between them), and the spacing below the last row is + the table's (see :func:`_table_ends`).""" + + if any(int(cols.get("colCount", "1")) > 1 for cols in table.iter(f"{HP}colPr")): + raise _Unsupported("columns in a table cell") # Hancom lays the cell's text out in them + rows: dict[int, _Row] = {} + merged: list[tuple[int, int, _Row]] = [] # (first row, rows spanned, the cell as a row) + cells: list[tuple[int, int, _Row]] = [] + nested: set[int] = set() # rows with a cell holding a table + headers: set[int] = set() # rows with a header cell of their own + reached: set[int] = set() # rows with a table among a cell's text (see _Reach) + firsts: dict[int, int] = {} # each row's tallest first line of a cell of its own + tallest: dict[int, int] = {} # each row's tallest cell of its own, and the most any fills with its text + filled: dict[int, int] = {} + widths = grid_widths_of(table) + spacing = _cell_spacing(table) + for tc in (tc for tr in table.findall(f"{HP}tr") for tc in tr.findall(f"{HP}tc")): + row, span = _cell_row(measure, table, tc, widths.get(tc)), _row_span(tc) + if spacing: # the cell spacing above it, kept with its lines when it goes on over a page end + row = replace(row, height=row.height + spacing, margins=row.margins + spacing) + address = tc.find(f"{HP}cellAddr") + first = int(address.get("rowAddr", 0)) if address is not None else len(rows) + cells.append((first, span, row)) + if row.nested: + nested.update(range(first, first + span)) + if row.header and span == 1: + headers.add(first) + if span == 1: + firsts[first] = max(firsts.get(first, 0), row.first) + tallest[first] = max(tallest.get(first, 0), row.height) + filled[first] = max(filled.get(first, 0), row.height - row.spare) + if span > 1 and row.reaches: + raise _Unsupported("a table among the text of a cell merged over rows") + if row.reaches: + reached.add(first) + if span > 1: + merged.append((first, span, row)) + elif first not in rows or (row.height - row.spare, row.height, row.lines) > (rows[first].height - rows[first].spare, rows[first].height, rows[first].lines): + rows[first] = row # the cell its text fills most: its lines split the row over a page end + for first in reached: # one among the text of a cell that is not the tallest: no page end followed + if not rows[first].reaches: + rows[first] = replace(rows[first], reaches=(_Reach(-1, 0, 1 << 62),)) + for first in headers: # a header row whatever cell is the tallest + rows[first] = replace(rows[first], header=True) + for first, line in firsts.items(): + rows[first] = replace(rows[first], first=line) + for first, height in tallest.items(): # as tall as its tallest cell, with room to spare under the text + rows[first] = replace(rows[first], height=height, spare=height - filled[first]) # filling one most + least = 0 if _on(dict(table.attrib), "noAdjust") else _MERGED_ROW_LEAST + for first, span, cell in merged: + for index in range(first, first + span): + if index not in rows: # every cell over it is merged over rows + rows[index] = replace(cell, height=least, lines=1, margins=0, spare=0) + for first, span, cell in sorted(merged, key=lambda cell: (cell[0] + cell[1], cell[0])): + spanned = range(first, first + span) + for index in spanned: + rows[index] = replace(rows[index], merged=True, joined=rows[index].joined or index < first + span - 1) + last = rows[first + span - 1] + lacking = cell.height - sum(rows[index].height for index in spanned) + rows[first + span - 1] = replace(last, height=last.height + max(lacking, 0)) + order = sorted(rows) # a row address no cell covers is skipped + place = {address: position for position, address in enumerate(order)} + return ([replace(rows[address], nested=address in nested) for address in order], + [(place[first], span, cell) for first, span, cell in cells]) + + +def _cell_spacing(table: Any) -> int: + """The room Hancom keeps between a table's cells and around them (``hp:tbl@cellSpacing``).""" + + spacing = int(table.get("cellSpacing", 0) or 0) + return spacing if 0 < spacing < 1 << 31 else 0 + + +def _table_ends(table: Any) -> tuple[int, int]: + """The room a table that flows with the text keeps above its rows and below them on each page it goes on: + its outer margins (``hp:outMargin`` top and bottom), and below the rows its cell spacing too.""" + + margin = table.find(f"{HP}outMargin") + top, bottom = (0, 0) if margin is None else (_margin(margin, "top"), _margin(margin, "bottom")) + return top, bottom + _cell_spacing(table) + + +def _row_span(cell: Any) -> int: + span = cell.find(f"{HP}cellSpan") + return 1 if span is None else int(span.get("rowSpan", 1)) + + +def _object_alone(runs: list[Any]) -> Any: + """The object set as a character, not a table, that is all a paragraph holds (but objects in front of or + behind the text), or ``None``.""" + + objects = _placed_objects(runs) + if len(objects) != 1 or _local(objects[0]) == "tbl" or _run_text(runs).strip(): + return None + return objects[0] if objects[0].find(f"{HP}pos").get("treatAsChar") == "1" else None + + +def _objects_among(runs: list[Any]) -> bool: + """Whether the runs hold objects set as characters, and nothing else placed, among text or several.""" + + objects = _placed_objects(runs) + return bool(objects) and (len(objects) > 1 or bool(_run_text(runs).strip())) and all( + obj.find(f"{HP}pos").get("treatAsChar") == "1" for obj in objects) + + +def _table_alone(runs: list[Any]) -> Any: + """The table set as a character that is all a paragraph holds (but objects in front of or behind the text, + which take no room), or ``None``.""" + + children = [child for run in runs for child in run if _local(child) not in ("t", "secPr", "ctrl") + and not (_local(child) in _OBJECTS and _floating(child))] + if len(children) != 1 or _local(children[0]) != "tbl" or _run_text(runs).strip(): + return None + pos = children[0].find(f"{HP}pos") + return children[0] if pos is not None and pos.get("treatAsChar") == "1" else None + + +def _size_protected(table: Any) -> bool: + """Whether *table* is set not to change size (``hp:sz@protect``): Hancom keeps its rows as declared, however + tall their text.""" + + size = table.find(f"{HP}sz") + return size is not None and size.get("protect") == "1" + + +def _cell_height(size: Any) -> int: + """A cell's stored height (hp:cellSz): a negative one, which the file keeps as an unsigned 32-bit number, + counts as none -- Hancom gives that cell its top and bottom margins and grows it to fit its text.""" + + height = int(size.get("height", 0)) if size is not None else 0 + return 0 if height >= 1 << 31 else height + + +def _margin(margin: Any, side: str) -> int: + """One side of an object's outer margins (hp:outMargin): a negative one, which the file keeps as an + unsigned 32-bit number, counts as none, as Hancom lays it out (and saves it).""" + + value = int(margin.get(side, 0)) + return 0 if value < 0 or value >= 1 << 31 else value + + +def _extent_margins(obj: Any) -> int: + margin = obj.find(f"{HP}outMargin") + return 0 if margin is None else _margin(margin, "top") + _margin(margin, "bottom") + + +def _drawn_lines(measure: _Measure, paragraphs: list[Any], width: int | None = None, cell: int | None = None + ) -> tuple[tuple[tuple[int, int], ...], tuple[_Reach, ...]]: + """(height, advance) of every line of *paragraphs* as Hancom placed them, when every paragraph keeps a + valid layout cache; the last line reaches down to the foot of any top-and-bottom or square-wrapped + object placed from its paragraph that moves with the text. A picture or drawing stands from the top of + the line its control falls on (see :meth:`_Measure.wrapped_lines`): in a cell *width* wide, the line + laid out at the whole width, which is the first one narrower than that when the lines beside the object + broke again (for a table, so in a cell *cell* wide too). A table, with a caption above or below it, stands + from its paragraph's top (where the first line would stand without it) on the first line, and from the top + of the line its control falls on, where that line would follow the one before, on a later one; so does one + in front of or behind the text moving with it (from the paragraph's top above its spacing before on the + first line), which pushes no line but makes the cell reach its foot. + A row that went on over a page end has its cell's lines start over at the top of the next page: a + line above where it would follow the one before (that one's height and spacing below it, or the + paragraph's top for a paragraph's first line, the part starting at that top) stands where it would + in the unsplit cell, and so does a line that starts the part below a table placed top and bottom on it + (the table went on with it). A paragraph's first line below an object placed from its top takes the room + above it, and so does a later line below a table placed top and bottom on it. Empty otherwise; not followed + when a table on a later line, or in front of or behind the text, is not as tall as its rows (Hancom split + it over a page end). Also where those tables stand among the lines (see :class:`_Reach`).""" + + if not paragraphs or not all(_cached_metrics(paragraph) for paragraph in paragraphs): + return (), () + tops: list[int] = [] + heights: list[int] = [] + reaches: list[_Reach] = [] + foot, after, base = 0, 0, 0 # after: where the next paragraph's first line would stand + for paragraph in paragraphs: + shape = measure.shape(paragraph.get("paraPrIDRef")) + start = after if tops else 0 # the paragraph's top, above its spacing before + top = start + shape.prev if tops else 0 + first = len(tops) # the paragraph's first line's index + segments = paragraph.findall(f"{HP}linesegarray/{HP}lineseg") + runs = paragraph.findall(f"{HP}run") + objects = [] + floats = [] # tables in front of or behind the text + for obj in (child for run in runs for child in run if _local(child) in _OBJECTS): + pos = obj.find(f"{HP}pos") + if pos is None or pos.get("treatAsChar") == "1": + continue + if _floating(obj): + if _local(obj) == "tbl": + if pos.get("flowWithText") == "0" or pos.get("vertRelTo") != "PARA" \ + or pos.get("vertAlign", "TOP") != "TOP": + return (), () + floats.append(obj) + continue + if obj.get("textWrap") not in ("TOP_AND_BOTTOM", "SQUARE") or pos.get("vertRelTo") != "PARA": + return (), () + if _local(obj) != "tbl" and pos.get("flowWithText") == "0": # stays put: pushes no line, the row + continue # as it is + objects.append(obj) + lines = {id(obj): _anchor_line(measure, paragraph, runs, "", obj, [], 0, None, ((0, 0),), len(segments)) + for obj in (*objects, *floats) if _local(obj) == "tbl"} + whole = width if width is not None else cell + if whole is not None: # the lines beside a table Hancom broke anew, narrower: it stands from the line it + full = whole - shape.left - shape.right # fell on at the cell's whole width, the first of them + lines = {key: next((index for index, segment in enumerate(segments[:line]) + if int(segment.get("horzsize", 0)) < full - (abs(shape.indent) if index == 0 else 0)), + line) for key, line in lines.items()} + pushing: dict[int, Any] = {} # a later line: the table placed top and bottom on it (or so wrapped square) + for obj in (*objects, *floats): + if _local(obj) != "tbl" or not lines[id(obj)] and obj not in floats: + continue + if int(obj.find(f"{HP}sz").get("height", 0)) != _inline_table_height(measure, obj): + raise _Unsupported("a table in a cell not as tall as its rows (split over a page end)") + if obj in objects and (obj.get("textWrap") == "TOP_AND_BOTTOM" + or whole is not None and _wraps_top_and_bottom(obj, whole)): + pushing[lines[id(obj)]] = obj + follows: list[int] = [] # where each line would follow the one before + moved: set[int] = set() # the lines below a table on a later line + below = top # where the paragraph's next line would stand + for index, segment in enumerate(segments): + vertpos = int(segment.get("vertpos", 0)) + if index and vertpos == int(segments[index - 1].get("vertpos", 0)) \ + and int(segment.get("horzpos", 0)) > int(segments[index - 1].get("horzpos", 0)): + follows.append(follows[-1]) # a line's second piece beside an object with text on both sides: at + tops.append(tops[-1]) # the first's height + heights.append(int(segment.get("textheight", segment.get("vertsize", 0)))) + continue + follows.append(below) + table = pushing.get(index) + if table is not None and vertpos == _cell_extent(measure, table) + _down(table.find(f"{HP}pos")) \ + and base < below: # the next page's part of a split row, starting below the table that went + base = below # on with the line + elif tops and vertpos + base < below: # the next page's part of a split row: the lines start over + base = (top if index == 0 else below) - (0 if index == 0 else vertpos) + tops.append(vertpos + base) + heights.append(int(segment.get("textheight", segment.get("vertsize", 0)))) + below = tops[-1] + int(segment.get("vertsize", 0)) + int(segment.get("spacing", 0)) + if index == 0 and tops[-1] > top: # below an object placed from the paragraph's top: the line + heights[-1] += tops[-1] - top # takes the room above it, and goes on to a next page with it + tops[-1] = top + elif table is not None and tops[-1] > follows[-1]: # so below a table on a later line + heights[-1] += tops[-1] - follows[-1] + tops[-1] = follows[-1] + moved.add(index) + for obj in (*objects, *floats): + if _local(obj) == "tbl": + line = lines[id(obj)] + if not line and obj not in floats: # from the paragraph's top + foot = max(foot, top + _down(obj.find(f"{HP}pos")) + _extent(obj, "height", measure) + + sum(_caption(measure, obj))) + continue + up = (start if line == 0 else follows[line]) + _down(obj.find(f"{HP}pos")) + foot = max(foot, up + _cell_extent(measure, obj)) + if pushing.get(line) is obj: # it pushes that very line + reaches.append(_Reach(follows[line], up, up + _cell_extent(measure, obj), _table_first(measure, obj), + follows[line] if line in moved else None, + int(segments[line].get("textheight", 0)), *_split_rows(measure, obj))) + else: + reaches.append(_Reach(follows[line] if line else top, up, up + _cell_extent(measure, obj))) + continue + # a picture or drawing stands its offset below the top of the line its control falls on, where + # that line would follow the one before (Hancom then moves it clear), or of the paragraph, above + # its spacing before, on its first line + line = _anchor_line(measure, paragraph, paragraph.findall(f"{HP}run"), "", obj, [], 0, None, + ((0, 0),), len(segments)) + if width is not None: # the lines beside it Hancom broke anew, narrower: it stands from the line + full = width - shape.left - shape.right # it fell on at the cell's whole width, the first of them + line = next((index for index, segment in enumerate(segments[:line]) + if int(segment.get("horzsize", 0)) < full - (abs(shape.indent) if index == 0 else 0)), + line) + up = start if line == 0 else \ + tops[first + line - 1] + heights[first + line - 1] + int(segments[line - 1].get("spacing", 0)) + foot = max(foot, up + _down(obj.find(f"{HP}pos")) + _extent(obj, "height", measure)) + last = segments[-1] + after = int(last.get("vertpos", 0)) + base + int(last.get("textheight", 0)) + int(last.get("spacing", 0)) \ + + shape.next + if any(later < earlier for earlier, later in zip(tops, tops[1:])): + return (), () + heights[-1] = max(heights[-1], foot - tops[-1]) + return tuple((height, (nxt - top) if nxt is not None else height) + for height, top, nxt in zip(heights, tops, [*tops[1:], None])), tuple(reaches) + + +def _holds_table(element: Any) -> bool: + """Whether *element* (a cell, a paragraph or a table) holds a table laid out in its text: one in a header, + footer or note control placed in it is laid out with that, elsewhere.""" + + for table in element.iter(f"{HP}tbl"): + if table is element: + continue + for up in table.iterancestors(): + if up is element: + return True + if _local(up) == "ctrl": + break + return False + + +def _pos_offset(pos: Any, name: str) -> int: + """An object's ``vertOffset`` or ``horzOffset`` as Hancom reads it: the file keeps an offset up or left as + an unsigned 32-bit number; one written with a minus sign Hancom reads as 0 (and saves so).""" + + value = pos.get(name, "0").strip() + return 0 if value.startswith("-") else int(value) + + +def _down(pos: Any) -> int: + """How far below its paragraph's top an object placed from there stands: one offset up (a negative + offset, which the file keeps as an unsigned 32-bit number) stands at the paragraph's top.""" + + offset = _pos_offset(pos, "vertOffset") + return 0 if offset >= 1 << 31 else offset + + +def _vertical(cell: Any) -> bool: + """Whether *cell* holds vertical text (``hp:subList@textDirection``): Hancom lays its lines down the + cell's height, side by side across it, cuts what does not fit and never makes its row taller.""" + + sub_list = cell.find(f"{HP}subList") + return sub_list is not None and sub_list.get("textDirection", "HORIZONTAL") != "HORIZONTAL" + + +def _page_break(table: Any) -> str: + """How a flowing table goes over a page end (``hp:tbl@pageBreak``): one holding a cell of vertical text + does not split, as if set not to (NONE): it moves to the next page whole.""" + + if any(_vertical(cell) for row in table.findall(f"{HP}tr") for cell in row.findall(f"{HP}tc")): + return "NONE" + return table.get("pageBreak", "CELL") + + +def _split_before_text(paragraphs: list[Any]) -> bool: + """Whether a cell's paragraphs hold a table placed top and bottom from its paragraph's top before its text + where Hancom split the cell over a page end: their layout caches start over at the top of the next page at + that paragraph or the next. Its declared height, as those caches, holds a part of it.""" + + tops = [int(cache.get("vertpos", 0)) if cache is not None else None + for cache in (paragraph.find(f"{HP}linesegarray/{HP}lineseg") for paragraph in paragraphs)] + for index, paragraph in enumerate(paragraphs): + table = _table_before_text(paragraph.findall(f"{HP}run")) + if table is None or _local(table) != "tbl": + continue + for at in (index, index + 1): + if 0 < at < len(tops) and tops[at] is not None and tops[at - 1] is not None and tops[at] < tops[at - 1]: + return True + return False + + +def _uncached(paragraph: Any) -> Any: + """A copy of *paragraph* without its layout caches, its cells' paragraphs' among them.""" + + copied = copy.deepcopy(paragraph) + for cache in list(copied.iter(f"{HP}linesegarray")): + cache.getparent().remove(cache) + return copied + + +def _cell_row(measure: _Measure, table: Any, cell: Any, width: int | None = None) -> _Row: + if _vertical(cell) or _size_protected(table) and _cell_height(cell.find(f"{HP}cellSz")): # its lines go across + # it, or its table is set not to change size (its text cut off below): the row as declared, one block, not split + margins = cell_margins_of(cell, table) + vertical = margins.top + margins.bottom + height = max(_cell_height(cell.find(f"{HP}cellSz")), vertical) + return _Row(height, 1, height - vertical, height - vertical, vertical, cell.get("header") == "1", + first=height - vertical) + paragraphs = cell.findall(f"{HP}subList/{HP}p") + if _split_before_text(paragraphs): # the lines as Hancom drew them hold the parts: laid out anew + paragraphs = [_uncached(paragraph) for paragraph in paragraphs] + nested = _holds_table(cell) + drawn: tuple[tuple[int, int], ...] = () + placed = [paragraph for paragraph in paragraphs if _placed_from(paragraph) + or _holds_table(paragraph) and _table_alone(paragraph.findall(f"{HP}run")) is None] + pieces = nested and bool(placed) and all(_table_pieces(measure, paragraph) is not None for paragraph in placed) + size = cell.find(f"{HP}cellSz") + margins = cell_margins_of(cell, table) + inner = (int(size.get("width", 0)) if width is None else width) - margins.left - margins.right + sub_list = cell.find(f"{HP}subList") + squeezed = sub_list is not None and sub_list.get("lineWrap") in ("SQUEEZE", "KEEP") + wrapped: tuple[tuple[int, int], ...] = () + wrapped_leads: tuple[int, ...] = () + reaches: tuple[_Reach, ...] = () + if nested and not pieces and any(_holds_table(paragraph) and _table_alone(paragraph.findall(f"{HP}run")) is None + for paragraph in paragraphs): + drawn, reaches = _drawn_lines(measure, paragraphs, cell=inner) # among text, or not set as a character: + # as Hancom drew it + if not drawn and not all(_table_on_its_own(paragraph) + or _table_before_text(paragraph.findall(f"{HP}run")) is not None + or _objects_among(paragraph.findall(f"{HP}run")) # laid out as in the body + for paragraph in paragraphs + if _holds_table(paragraph) + and _table_alone(paragraph.findall(f"{HP}run")) is None): + # placed top and bottom or square among or after the text, or in front of or behind it: clear of + # it, as a picture so placed + wrapped, wrapped_leads, reaches = ((), (), ()) if squeezed \ + else measure.wrapped_lines(paragraphs, inner, tables=True) + if not wrapped: + raise _Unsupported("a nested table") + elif not pieces and any(_placed_from(paragraph) for paragraph in paragraphs): # an object placed from a + drawn = _drawn_lines(measure, paragraphs, inner)[0] # paragraph: the lines as Hancom drew them, below it or + # beside it + if squeezed: # never broken into lines: + inner = _NO_WRAP # each paragraph one line but for its line breaks, pressed into the cell when drawn + # an object placed top and bottom or square from a paragraph without a layout cache: the lines clear of it + if not (wrapped or drawn or nested or pieces or inner == _NO_WRAP): + wrapped, wrapped_leads, _ = measure.wrapped_lines(paragraphs, inner) + # Hancom starts the cell's first line below its first paragraph's spacing before (the lines as drawn + # take that room already) + before = 0 if drawn or not paragraphs else measure.shape(paragraphs[0].get("paraPrIDRef")).prev + content, lines, pitch, char_size = measure.stack(paragraphs, inner, caches=True, floating=True, lead=before) + if drawn: + content, lines = sum(advance for _, advance in drawn[:-1]) + drawn[-1][0], len(drawn) + elif wrapped: + content, lines = before + sum(advance for _, advance in wrapped[:-1]) + wrapped[-1][0], len(wrapped) + vertical = margins.top + margins.bottom + height = max(_cell_height(size), vertical + content) + first = drawn[0][0] if drawn else before + wrapped[0][0] if wrapped else \ + before + (measure.stack_lines(paragraphs[:1], inner, caches=True, pieces=pieces) or ((0, 0),))[0][0] + several = not nested and len(paragraphs) > 1 # its lines split at their own places, spacing included + metrics = (drawn or wrapped or measure.stack_lines(paragraphs, inner, caches=True, pieces=pieces)) \ + if nested or several else () + if nested and not (drawn or wrapped or pieces): + reaches = _pushed_reaches(measure, paragraphs, inner, metrics) + # its paragraphs, a table's among them, spaced apart (lines drawn as Hancom did hold their spacing already) + spaced = several or nested and len(paragraphs) > 1 and not drawn + leads = wrapped_leads if wrapped else _line_leads(measure, paragraphs, inner, pieces) \ + if spaced or before or pieces else () + if pieces and metrics: # as tall as its lines and its tables' pieces: the caches of a cell Hancom split over a + content = max(content, _lines_height(metrics, leads)) # page end hold its parts, each from the top + height = max(height, vertical + content) + return _Row(height, len(metrics) if pieces else lines, pitch, char_size, vertical, + cell.get("header") == "1", spare=height - vertical - content, nested=nested, metrics=metrics, + first=first, leads=leads if spaced or before or pieces else (), pieces=pieces, reaches=reaches, + cuts=_line_cuts(measure, paragraphs, inner) if pieces else (), + blocks=_line_blocks(measure, paragraphs, inner) if pieces else ()) + + +def _table_first(measure: _Measure, obj: Any) -> int: + """How far below its top a table's first row ends, its top outer margin and a caption above it included; 0 for + an object that is not a table.""" + + if _local(obj) != "tbl": + return 0 + margin = obj.find(f"{HP}outMargin") + rows = _rows(measure, obj) + return (0 if margin is None else _margin(margin, "top")) + _caption(measure, obj)[0] + (rows[0].height if rows else 0) + + +def _split_rows(measure: _Measure, obj: Any) \ + -> tuple[int, tuple[tuple[int, int, int, int], ...], int, _FlowTable | None, tuple[tuple[int, int, int], ...]]: + """How a table placed top and bottom in a cell may split over a page end: the room above its first row (its + top outer margin and a caption above it), the pieces it splits into, and the room below its last row (a + caption below it and its bottom outer margin). A piece is a row, or, split between lines (CELL), each + line of a row of several, the first with the row's top cell margin, the last with its bottom one: its + height, advance, the room it needs below it when a page ends after it (the bottom margin of a row going on) + and the room above it when a page starts with it (the top margin of a row going on); rows joined by merged + cells are a piece each, split cell by cell (see :func:`_block_rest`): last, the table and those rows (where + the first's piece stands, the first and the last). No pieces for a table set not to split or not to be + adjusted (``noAdjust``), with rows holding tables, or header rows it repeats, which is not followed.""" + + margin = obj.find(f"{HP}outMargin") + if _local(obj) != "tbl" or _page_break(obj) not in ("CELL", "TABLE") or obj.get("noAdjust") == "1": + return 0, (), 0, None, () + rows, merged = _table_rows(measure, obj) + if not rows or any(row.nested or row.header and obj.get("repeatHeader") == "1" for row in rows): + return 0, (), 0, None, () + above, below = _caption(measure, obj) + above += 0 if margin is None else _margin(margin, "top") + below += 0 if margin is None else _margin(margin, "bottom") + pieces: list[tuple[int, int, int, int]] = [] + blocks: list[tuple[int, int, int]] = [] + cells = [tr.find(f"{HP}tc") for tr in obj.findall(f"{HP}tr")] + for index, (row, cell) in enumerate(zip(rows, cells)): + if row.joined and not (index and rows[index - 1].joined): # the first of rows joined by merged cells + last = index + while rows[last].joined and last + 1 < len(rows): + last += 1 + blocks.append((len(pieces), index, last)) + joined = row.joined or index and rows[index - 1].joined + lines = (row.metrics or ((row.size, row.pitch),) * row.lines) \ + if _page_break(obj) == "CELL" and not joined else () + if len(lines) < 2 or cell is None: + pieces.append((row.height - (row.spare if index < len(rows) - 1 else 0), row.height, 0, 0)) # its text + # fitting, the room it declares to spare under it is cut at the page end, as a flowing table's row's + continue + top = cell_margins_of(cell, obj).top + bottom = row.margins - top + last = row.height - top - sum(advance for _, advance in lines[:-1]) + pieces += [(top + lines[0][0], top + lines[0][1], bottom, 0)] \ + + [(height, advance, bottom, top) for height, advance in lines[1:-1]] + [(last, last, 0, top)] + table = _FlowTable(rows, _page_break(obj), obj.get("repeatHeader") == "1", _table_ends(obj), tuple(merged), + cut=_SPARE_CUT + below) if blocks else None + return above, tuple(pieces), below, table, tuple(blocks) + + +def _pushed_reaches(measure: _Measure, paragraphs: list[Any], width: int, + metrics: tuple[tuple[int, int], ...]) -> tuple[_Reach, ...]: + """Where the tables placed top and bottom before the text of a cell's paragraphs without a layout cache + (see :meth:`_Measure.pushed_lines`) stand among the cell's lines *metrics* (see :class:`_Reach`): from the + top of the paragraph's first line. Only those that may split between their rows (see :func:`_split_rows`): + another goes on to the next page whole with the line below it, which is not checked against Hancom here.""" + + reaches: list[_Reach] = [] + index = 0 + for paragraph in paragraphs: + runs = paragraph.findall(f"{HP}run") + obj = _object_before_text(runs, measure.headed(paragraph)) + if obj is not None and _local(obj) == "tbl" and measure.pushed_lines(paragraph, runs, width): + count = len(measure.stack_lines([paragraph], width, caches=True)) + line = sum(advance for _, advance in metrics[:index]) + up = line + _down(obj.find(f"{HP}pos")) + foot = up + _cell_extent(measure, obj) + unit, text, y = None, 0, line # the first line reaching it, which goes below it taking the room above + for height, advance in metrics[index:index + count]: + if y + height > up and y < foot: + unit, text = y, height - (foot - y) + break + y += advance + split = _split_rows(measure, obj) + if split[1]: # one that may not split goes on whole with its line, as it did before + reaches.append(_Reach(line, up, foot, _table_first(measure, obj), unit, text, *split)) + index += count + continue + index += len(measure.stack_lines([paragraph], width, caches=True)) + return tuple(reaches) + + +def _line_leads(measure: _Measure, paragraphs: list[Any], width: int, pieces: bool = False) -> tuple[int, ...]: + """The room above each line of *paragraphs* (as :meth:`_Measure.stack_lines` lays them out) when a part + of their cell starts with it: a paragraph's spacing before at its first line, none at the others.""" + + leads: list[int] = [] + for paragraph in paragraphs: + prev = measure.shape(paragraph.get("paraPrIDRef")).prev + split = _table_pieces(measure, paragraph) if pieces else None + if split is not None: # a table's: the room above each (a repeated header, a row's top margin) + leads += [prev + split[1][0]] + list(split[1][1:]) + continue + count = len(measure.stack_lines([paragraph], width, caches=True)) + leads += [prev] + [0] * (count - 1) + return tuple(leads) + + +def _line_cuts(measure: _Measure, paragraphs: list[Any], width: int) -> tuple[int, ...]: + """The room each line of *paragraphs* (as :meth:`_Measure.stack_lines` lays them out with tables' pieces) + needs below it to stay above a page end: none for a line of text, a table's cut (101) for a piece of a + table and its bottom margin under it but for the last (which holds it), as Hancom keeps a table's rows + among a cell's text.""" + + cuts: list[int] = [] + for paragraph in paragraphs: + split = _table_pieces(measure, paragraph) + if split is None: + cuts += [0] * len(measure.stack_lines([paragraph], width, caches=True)) + continue + table = next(child for run in paragraph.findall(f"{HP}run") for child in run if _local(child) == "tbl") + below = _table_ends(table)[1] + cuts += [_SPARE_CUT + below + room for room in split[3][:-1]] + [_SPARE_CUT] + return tuple(cuts) + + +def _line_blocks(measure: _Measure, paragraphs: list[Any], + width: int) -> tuple[tuple[int, _FlowTable, int, int], ...]: + """The rows joined by merged cells of the tables among the lines of *paragraphs* (as + :meth:`_Measure.stack_lines` lays them out with tables' pieces): where the first's piece stands among those + lines, the table, and its first and last row.""" + + blocks: list[tuple[int, _FlowTable, int, int]] = [] + count = 0 + for paragraph in paragraphs: + split = _table_pieces(measure, paragraph) + if split is None: + count += len(measure.stack_lines([paragraph], width, caches=True)) + continue + table = next(child for run in paragraph.findall(f"{HP}run") for child in run if _local(child) == "tbl") + rows, cells = _table_rows(measure, table) + flowing = _FlowTable(rows, _page_break(table), table.get("repeatHeader") == "1", _table_ends(table), + tuple(cells), cut=_spare_cut(table)) + first = 0 + while first < len(rows): + last = first + while rows[last].joined and last + 1 < len(rows): + last += 1 + if last > first: + blocks.append((count + split[2][first], flowing, first, last)) + first = last + 1 + count += len(split[0]) + return tuple(blocks) + + +def _table_pieces(measure: _Measure, paragraph: Any) \ + -> tuple[tuple[tuple[int, int], ...], tuple[int, ...], tuple[int, ...], tuple[int, ...]] | None: + """How a table placed top and bottom on its own in a cell paragraph, from the paragraph's top, splits with + its row over a page end: (height, advance) of each piece and the room above each when a part of the cell + starts with it. Hancom splits such a table between its rows, one moved row by row (TABLE) as well as one + split between lines (CELL), which splits a row of several lines between them too, the row's cell + margins around each part; its top outer margin and a repeated header go above each part but the first. + ``None`` for any other + paragraph, and for a table set not to split (NONE), offset down, with a caption, or with rows holding + tables that do not split so (a row holding one that does splits between its pieces as between lines, and + one holding tables set as characters between its lines, a table one, as in the body). + Rows joined by merged cells are a piece each (see :func:`_line_blocks`). Third: where each row's first + piece stands among the pieces; fourth: the room each needs below it when a page ends after it (the bottom + margin of a row going on).""" + + if not _table_on_its_own(paragraph): + return None + table = next(child for run in paragraph.findall(f"{HP}run") for child in run if _local(child) == "tbl") + mode = _page_break(table) + if mode not in ("CELL", "TABLE") or _down(table.find(f"{HP}pos")) or table.find(f"{HP}caption") is not None: + return None + rows = _rows(measure, table) + cells = [tr.find(f"{HP}tc") for tr in table.findall(f"{HP}tr")] + if len(rows) != len(cells) or any(row.nested and not (row.pieces or row.metrics and not row.reaches) + for row in rows): + return None + header = sum(row.height for row in rows if row.header) if table.get("repeatHeader") == "1" else 0 + margin = table.find(f"{HP}outMargin") + above, below = (0, 0) if margin is None else (_margin(margin, "top"), _margin(margin, "bottom")) + pieces: list[tuple[int, int]] = [] + leads: list[int] = [] + starts: list[int] = [] + rooms: list[int] = [] + for index, (row, cell) in enumerate(zip(rows, cells)): + starts.append(len(pieces)) + lead = 0 if row.header or not pieces else above + header # a part going on: below its top margin again + joined = row.joined or index and rows[index - 1].joined + lines = (row.metrics or ((row.size, row.pitch),) * row.lines) if mode == "CELL" and not joined else () + if len(lines) < 2: + pieces.append((row.height - (row.spare if index < len(rows) - 1 else 0), row.height)) # room to spare + # under its text cut at the page end (see _split_rows) + leads.append(lead) + rooms.append(0) + continue + margins = cell_margins_of(cell, table) + top = margins.top + last = row.height - top - sum(advance for _, advance in lines[:-1]) # its foot, its room to spare + pieces += [(top + lines[0][0], top + lines[0][1])] + list(lines[1:-1]) + [(last, last)] + leads += [lead] + [lead + top] * (len(lines) - 1) + rooms += [margins.bottom + (row.cuts[line] if row.cuts else 0) # a part of the row ending there: its + for line in range(len(lines) - 1)] # bottom margin under it, and what its own tables keep + rooms.append(0) + continue + pieces[0] = (pieces[0][0] + above, pieces[0][1] + above) + pieces[-1] = (pieces[-1][0] + below, pieces[-1][1] + below) + return tuple(pieces), tuple(leads), tuple(starts), tuple(rooms) + + +@dataclass(frozen=True) +class _Wrap: + """The band a square-wrapped object takes beside the text, from *top* to *bottom* below the top of + the first line of the paragraph at hand; a line in it is *cut* narrower. A top-and-bottom object's + band (*push*) has no room beside it: the first line reaching it goes below it instead.""" + + top: int + bottom: int + cut: int + push: bool = False + #: with text on both sides: the left piece's width (a line in the band is two pieces at one height, + #: the right one the line's width less *cut* and this) + split: int = 0 + #: its object does not flow with the text (pos@flowWithText="0"): it stays on its page past the + #: body's foot, and the band goes no further than that page + stays: bool = False + #: its object is placed on the paper or the page: the band is in the body of its page, and the lines of + #: any paragraph there reaching it go beside it + paper: bool = False + #: such an object's room on its left and on its right in a column *column* wide (see :func:`_square_sides`): + #: a line beside it runs from the paragraph's left margin to the object, or from the object to the + #: paragraph's right margin, the margin on the object's side taking no more (see :meth:`pieces`) + room: tuple[int, int] = (0, 0) + column: int = 0 + + def pieces(self, full: float, right: int) -> list[float]: + """The widths of a line beside an object with *room*, its pieces one on each side with text: a line + *full* wide, its right margin *right*.""" + + end = self.column - right + start = end - full + left, beside = self.room + widths = ([min(end, left) - start] if left else []) + ([end - max(start, self.column - beside)] + if beside else []) + if any(width <= 0 for width in widths): + raise _Unsupported("a paragraph's margin reaching past a square-wrapped object placed on the paper") + return widths + + def lower(self, by: int) -> "_Wrap | None": + """The band seen from *by* further down, or ``None`` once it is above.""" + + return replace(self, top=self.top - by, bottom=self.bottom - by) if self.bottom > by else None + + +@dataclass(frozen=True) +class _Anchor: + """A top-and-bottom object anchored in a paragraph of text: it stands at the top of line *line*, + and that line and the rest of the paragraph come below it.""" + + line: int + table: _FlowTable | None # a table flowing with the text, or + height: int # the height of any other object, its outer margins included + stays: bool = False # that object does not flow with the text (pos@flowWithText="0") + + +@dataclass(frozen=True) +class _Band: + """A table flowing with the text, top and bottom in a paragraph of text and *offset* down from the top + of line *line* (its outer margin above included): it flows from there over the page end, and the + first line reaching it, in that paragraph or the ones after, and the lines after go below its end.""" + + line: int + offset: int + table: _FlowTable + + +@dataclass(frozen=True) +class _Stacked: + """An object placed top and bottom in a paragraph holding nothing else but more such objects: its + offset below the paragraph's top (above its spacing), its span across the column and its height, outer + margins included (a table as tall as its rows), and a table's rows, which split over the pages when + it is taller than a page.""" + + offset: int + left: int + right: int + height: int + table: _FlowTable | None = None + + +@dataclass(frozen=True) +class _Para: + lines: int + size: int + pitch: int + prev: int + next: int + break_before: bool + keep_lines: bool + keep_next: bool + widow_orphan: bool + page_break: bool = False # hp:p@pageBreak + column_break: bool = False # hp:p@columnBreak + table: _FlowTable | None = None + #: line index -> (height of the notes anchored in it, how many, size of the first one's first line) + notes: dict[int, tuple[int, int, int]] = field(default_factory=dict) + #: (height, advance) of each line from the paragraph's valid layout cache, or of each line of a + #: paragraph of several character sizes; empty when every line is ``size`` tall and ``pitch`` apart. + cached: tuple[tuple[int, int], ...] = () + anchor: _Anchor | None = None + #: a square-wrapped object's band starts in this paragraph, this far below its first line's top + wrap_bottom: int = 0 + #: how many of the first lines are beside such a band (they must stay on the band's page) + wrap_lines: int = 0 + #: the paragraph keeps its layout cache and such a band is a square-wrapped object's, which takes no + #: line's height: where the object goes moves none of its lines + wrap_fixed: bool = False + #: the band's object does not flow with the text (pos@flowWithText="0"): past the body's foot it stays + #: on its page, overflowing it, instead of going on to the next + wrap_stays: bool = False + #: beside such a staying band, its lines do not depend on the band (it keeps its layout cache or holds no + #: text): a page break among them puts the rest on the next page, where Hancom lays them out whole + wrap_free: bool = False + #: the line the object laid out around the text (the caller's) stands on + wrap_anchor: int = 0 + band: _Band | None = None + #: for each object anchored here and placed on the paper or the page: (top, bottom) in the body, whether it + #: leaves a line's room beside it, the columns it reaches over and the band the lines beside it are broken + #: in (see :func:`_paper_bands`) + paper: tuple[tuple[int, int, bool, tuple[int, ...], _Wrap | None], ...] = () + #: the top of such a band that pushes the lines below it to the body's foot and that keeps the object on its + #: paragraph's page (pos@holdAnchorAndSO="1"): when the first line with its spacing reaches it there, the + #: paragraph goes on to the next page's top with the object, the lines above staying where they are + held: int | None = None + #: in columns of unequal width, a paragraph without a layout cache: its text, to break again + reflow: _Reflow | None = None + #: holding nothing, in a section hiding a page's first empty lines (see :meth:`_Paginator._paragraph`) + hides: bool = False + #: its lines are Hancom's own, from the paragraph's valid layout cache + kept: bool = False + #: the step of the line grid its lines snap to (see :func:`_on_grid`), 0 for none + grid: int = 0 + #: an object anchored in this paragraph holding nothing else but spaces on one line: a table of it starting + #: on the next page goes there as when the paragraph holds it alone, the paragraph's line staying + spaced: bool = False + #: the top-and-bottom objects stacked in this paragraph, which holds nothing else (see :func:`_stack`) + stack: tuple[_Stacked, ...] = () + #: a square-wrapped object anchored here and flowing with the text went past the body's foot: Hancom sets + #: it at the next page's body top, whatever its offset (this band, from there) + moved: _Wrap | None = None + #: holding no text: its line goes beside such a band as it is + blank: bool = False + #: holding nothing but a top-and-bottom object offset down from it (see :func:`_pushing_object`): its empty + #: line stays where it is beside the object's band, which only the lines after reaching it go below + bare: bool = False + #: a top-and-bottom object offset from this paragraph (not a flowing table) pushes its lines below it: + #: when its band would pass the body's foot, Hancom moves it to the next page's top instead + wrap_push: bool = False + #: how far such an object pushed the paragraph's first line down (its band's foot is measured from where + #: that line stood before) + wrap_shift: int = 0 + #: how far an earlier paragraph's top-and-bottom object pushed this paragraph's first line down (part of + #: :attr:`prev`): going on to the next page, the line drops it and starts at that page's top + lead: int = 0 + #: a table wrapped square anchored here, flowing with the text and allowed to split, that goes on over the + #: page end: it as it flows, how far below the paragraph's first line it starts, and its band beside the + #: text (see :meth:`_Paginator._span_bands`) + spans: tuple[_FlowTable, int, _Wrap] | None = None + #: such an object alone in this empty paragraph, its foot this far below the paragraph's top (the line is + #: as tall as that): past the body's foot it goes on to the next page's top, the empty line staying when + #: it fits there (*own* tall) + moves: int = 0 + own: int = 0 + #: a top-and-bottom object alone in this empty paragraph, its foot this far below the line's top: the next + #: paragraph starts no higher, but its spacing and this one's count only where the empty line's own advance + #: with them reaches lower (Hancom's empty line stays beside the object, which the next line goes below) + floor: int = 0 + #: a top-and-bottom object alone in this empty paragraph placed up from its top: (how far up, as a negative + #: offset, how tall, and the paragraph's own line and advance) -- see :meth:`_Paginator._below_a_rising_object` + rises: tuple[int, int, int, int] | None = None + #: a flowing table alone in this empty paragraph, allowed to overlap and starting on the line: the line goes + #: below it (see :meth:`_Paginator._flow`) + under: bool = False + + def height(self, line: int) -> int: + return self.cached[line][0] if self.cached else self.size + + def advance(self, line: int) -> int: + return self.cached[line][1] if self.cached else self.pitch + + def span(self, first: int, count: int) -> int: + """From the top of line *first* to the top of the line *count* lines further down.""" + + if not self.cached: + return count * self.pitch + return sum(self.cached[line][1] for line in range(first, first + count)) + + +@dataclass(frozen=True) +class _Reflow: + """A paragraph without a layout cache in columns of unequal width, its lines broken at a column + *width* from *offset* in its text on (*starts*: where each of them starts, from *offset*).""" + + measure: _Measure + text: str + sizes: tuple[int, ...] + looks: tuple[Any, ...] | None + style: Any + shape: _Shape + width: int = 0 + offset: int = 0 + starts: tuple[int, ...] = () + end: int = 0 # the paragraph's end (see :func:`_end_size`) + head: int = 0 # its label (see :func:`_head_size`) + wrapped: bool = False # its lines from *offset* on are broken beside a band (see :meth:`banded`) + + def at(self, para: _Para, width: int, line: int) -> _Para: + """*para* with its lines from line *line* on (the lines before it laid out already) broken + again at a column *width* wide: Hancom breaks the text a column holds at that column's width, + the paragraph's first line less its first-line indent, the others less a hanging one.""" + + offset = self.offset + (self.starts[line] if line else 0) + text = self.text[offset:] # empty only after a line break ending the paragraph + sizes = list(self.sizes[offset:] or self.sizes[-1:]) + looks = None if self.looks is None else list(self.looks[offset:] or self.looks[-1:]) + room = width - self.shape.left - self.shape.right + widths: list[float] = [room - max(self.shape.indent, 0), room - max(-self.shape.indent, 0)] + if offset: # the rest: none of its lines is the paragraph's first + widths = widths[1:] + mixed = len(set(sizes)) > 1 + starts = self.measure.line_starts(text, widths, min(sizes), self.style, sizes if mixed else None, looks) + cached = _line_metrics(self.measure, text, widths, sizes, self.style, self.shape, {}, looks) \ + if mixed or looks is not None or self.shape.font_line else () + return replace(para, lines=len(starts), cached=cached, + reflow=replace(self, width=width, offset=offset, starts=tuple(starts), wrapped=False)) + + def banded(self, para: _Para, line: int, wrap: _Wrap) -> _Para: + """*para* with its lines from line *line* on (the lines before it laid out already) broken again + beside *wrap*'s band, as seen from that line's top: a line whose top is above the band's foot is as + wide as the room beside the object, or two pieces at one height with text on both sides; the lines + below are the whole width.""" + + mixed = len(set(self.sizes)) > 1 + widths = _indented(self.width - self.shape.left - self.shape.right, self.shape, self.style) + starts = self.starts + if line and not starts: # where its lines start as laid out so far + starts = tuple(self.measure.line_starts(self.text, widths, min(self.sizes), self.style, + list(self.sizes) if mixed else None, + None if self.looks is None else list(self.looks))) + if len(starts) != para.lines: + raise _Unsupported("lines beside a square-wrapped object moved to the next page") + offset = self.offset + (starts[line] if line else 0) + text = self.text[offset:] + if not text: # only a line break ending the paragraph is left + return para + sizes = list(self.sizes[offset:]) + looks = None if self.looks is None else list(self.looks[offset:]) + if offset: # the rest: none of its lines is the paragraph's first + widths = [widths[1], widths[1]] + several = sizes if len(set(sizes)) > 1 else None + lines, firsts = _wrapped_widths(self.measure, text, widths, min(sizes), self.style, self.shape, wrap, + several, looks) + pieces = self.measure.line_starts(text, lines, min(sizes), self.style, several, looks) + metrics = _at_one_height(_line_metrics(self.measure, text, lines, sizes, self.style, self.shape, {}, looks, + end=self.end, head=0 if offset else self.head), firsts) + return replace(para, lines=len(metrics), cached=metrics, + reflow=replace(self, offset=offset, starts=tuple(pieces), wrapped=True)) + + +def _caption(measure: _Measure, table: Any) -> tuple[int, int]: + """How much room a table's (or another object's) caption takes above it and below it: its first + paragraph's spacing before (Hancom starts the caption's first line below it), its lines and its gap (a + caption beside the object takes none).""" + + caption = table.find(f"{HP}caption") + if caption is None or caption.get("side") not in ("TOP", "BOTTOM"): + return (0, 0) + paragraphs = caption.findall(f"{HP}subList/{HP}p") + width = int(caption.get("lastWidth", 0)) or int(table.find(f"{HP}sz").get("width", 0)) + before = measure.shape(paragraphs[0].get("paraPrIDRef")).prev if paragraphs else 0 + tall = before + measure.stack(paragraphs, width, caches=True)[0] + int(caption.get("gap", 0)) + return (tall, 0) if caption.get("side") == "TOP" else (0, tall) + + +def _inline_table_height(measure: _Measure, table: Any) -> int: + """A table set as a character (or placed top and bottom in a cell): its rows as the estimate measures + them. When the row model does not follow the table (merged rows, a nested table) but every paragraph in + it keeps a valid layout cache, Hancom laid it out as it is, and the height it saved (hp:sz) is the height + it draws.""" + + if _holds_table(table) or any(_row_span(tc) != 1 for tc in table.iter(f"{HP}tc")): + paragraphs = list(table.iter(f"{HP}p")) + if paragraphs and all(_cache_lines(paragraph) for paragraph in paragraphs): + return int(table.find(f"{HP}sz").get("height", 0)) + return _rows_height(measure, table) + + +def _rows_height(measure: _Measure, table: Any) -> int: + """How tall a table's rows make it: the rows (see :func:`_rows`, each with the cell spacing above it) and + the spacing below the last.""" + + return sum(row.height for row in _rows(measure, table)) + _cell_spacing(table) + + +def _objects_reach(runs: list[Any], measure: _Measure, spacing: int = 0) -> int: + """How far below the top of their paragraph's line in a cell, holding no text, the pictures and drawings + placed from it reach: top and bottom or square, not set as a character, moving with the text, their outer + margins included (the cell holds them, and its row grows to; one that stays put does not count). So do the + tables placed top and bottom from it, as tall as their rows and a caption above or below them (one placed + up stands at the paragraph's top), placed from the paragraph's top above its *spacing* before.""" + + reach = 0 + if _run_text(runs).strip(): # text goes on below such an object: not followed here + return reach + for obj in (child for run in runs for child in run): + name, pos = _local(obj), obj.find(f"{HP}pos") + if name == "tbl" and _placed_top_and_bottom(obj): + reach = max(reach, _down(pos) - spacing + _inline_table_height(measure, obj) + _extent_margins(obj) + + sum(_caption(measure, obj))) + continue + if name not in _OBJECTS or name == "tbl" or pos is None or obj.find(f"{HP}sz") is None \ + or pos.get("treatAsChar") == "1" or obj.get("textWrap") not in ("TOP_AND_BOTTOM", "SQUARE") \ + or pos.get("flowWithText") == "0" or pos.get("vertRelTo") != "PARA" \ + or pos.get("vertAlign", "TOP") != "TOP": + continue + reach = max(reach, _down(pos) + _extent(obj, "height", measure)) # one placed up stands at the top + return reach + + +def _floating_reach(runs: list[Any], measure: _Measure) -> int: + """How far below the top of their paragraph in a cell the pictures and drawings in front of or behind the + text placed from it reach, when they move with the text (pos@flowWithText not "0"), their outer margins + included: they push no line aside, but the cell grows to hold them. One that stays put does not.""" + + reach = 0 + for obj in (child for run in runs for child in run): + pos = obj.find(f"{HP}pos") + if _local(obj) not in _OBJECTS or _local(obj) == "tbl" or pos is None or obj.find(f"{HP}sz") is None or not _floating(obj) or pos.get("flowWithText") == "0" or pos.get("vertRelTo") != "PARA" or pos.get("vertAlign", "TOP") != "TOP": + continue + reach = max(reach, _down(pos) + _extent(obj, "height", measure)) # one placed up stands at the top + return reach + + +def _wraps_in_cell(obj: Any, tables: bool = False) -> bool: + """A picture or drawing (with *tables*, a table too) placed top and bottom or square from the top of its + paragraph, not set as a character, that moves with the text: in a cell, one that stays put + (pos@flowWithText="0") pushes no line aside and leaves the row as it is.""" + + pos = obj.find(f"{HP}pos") + return _local(obj) in _OBJECTS and (tables or _local(obj) != "tbl") and pos is not None \ + and obj.find(f"{HP}sz") is not None \ + and pos.get("treatAsChar") != "1" and obj.get("textWrap") in ("TOP_AND_BOTTOM", "SQUARE") \ + and pos.get("flowWithText") != "0" and pos.get("vertRelTo") == "PARA" and pos.get("vertAlign", "TOP") == "TOP" + + +def _cell_extent(measure: _Measure, obj: Any) -> int: + """How tall an object placed from a cell paragraph stands, its outer margins included: a table as its rows + (see :func:`_inline_table_height`) with a caption above or below it (its lines and its gap; one beside it is + not followed), anything else as Hancom draws it.""" + + if _local(obj) != "tbl": + return _extent(obj, "height", measure) + caption = obj.find(f"{HP}caption") + if caption is not None and caption.get("side") not in ("TOP", "BOTTOM"): + raise _Unsupported("a table in a cell with a caption beside it") + return _inline_table_height(measure, obj) + _extent_margins(obj) + sum(_caption(measure, obj)) + + +def _control_place(runs: list[Any], obj: Any) -> int: + """How many characters of the paragraph's text come before *obj*'s control.""" + + place = 0 + for child in (child for run in runs for child in run): + if child is obj: + break + if _local(child) == "t": + place += len(_t_text(child)) + return place + + +def _cell_band(measure: _Measure, obj: Any, top: int, width: int) -> tuple[int, int, int | None]: + """The band an object wrapped in a cell *width* wide (see :func:`_wraps_in_cell`) placed from *top* takes: + its top and foot, its outer margins included, and the room beside it, ``None`` when it pushes the lines + below it (top and bottom, or less than 1440 beside it). Placed from the paragraph's or the column's left or + right, it stands from the cell's text area's.""" + + pos = obj.find(f"{HP}pos") + up = top + _down(pos) # one placed up stands at that top + foot = up + _cell_extent(measure, obj) + if _wraps_top_and_bottom(obj, width): + return up, foot, None + if pos.get("horzRelTo") not in ("PARA", "COLUMN") or pos.get("horzAlign") not in ("LEFT", "RIGHT") \ + or obj.get("textFlow", "BOTH_SIDES") not in ("BOTH_SIDES", "LARGEST_ONLY", "LEFT_ONLY", "RIGHT_ONLY"): + raise _Unsupported(f"{_local(obj)} wrapped square elsewhere than at a cell's edge") + wide, offset = _extent(obj, "width"), _pos_offset(pos, "horzOffset") + if offset >= 1 << 31: # kept unsigned: one placed out past the edge + offset -= 1 << 32 + start = offset if pos.get("horzAlign") == "LEFT" else width - wide - offset + left, right = start, width - start - wide + flow = obj.get("textFlow", "BOTH_SIDES") + if flow == "LARGEST_ONLY": + flow = "LEFT_ONLY" if left > right else "RIGHT_ONLY" + left = left if left >= _MIN_SIDE and flow != "RIGHT_ONLY" else 0 + right = right if right >= _MIN_SIDE and flow != "LEFT_ONLY" else 0 + if left and right: + return up, foot, _BothSides(min(left, right)) + return up, foot, (left or right) or None + + +class _BothSides(int): + """The room beside an object wrapped square in a cell with text on both sides of it (the narrower side's): an + empty line goes beside it, two empty pieces at one height as tall as the line; text there is not followed.""" + + +def _beside_one_side(narrow: dict[int, int], empty: bool) -> None: + """Text on lines *narrow* beside an object wrapped square in a cell with text on both sides of it (unless + the paragraph is *empty*) is not followed.""" + + if not empty and any(isinstance(room, _BothSides) for room in narrow.values()): + raise _Unsupported("text on both sides of an object wrapped square in a cell") + + +def _clear_of(measure: _Measure, metrics: list[tuple[int, int]], top: int, prev: int, anchor: int, obj: Any, + bands: list[tuple[int, int, int | None]], empty: bool, width: int + ) -> tuple[list[tuple[int, int, int]], dict[int, int], tuple[int, int, int | None] | None]: + """(top, height, advance) of each line of a cell paragraph whose lines are *metrics* (height, advance), its + first line's top *top* below its spacing before *prev*, laid out clear of the *bands* of the objects above + and of the band of its own object *obj* (see :func:`_cell_band`), whose control is on line *anchor*: a + line reaching a band with no room beside it goes below its foot, and one in a square object's band takes + the room beside it (returned by the line's index), as does *obj*'s band. An *empty* paragraph's line stays + beside its own object when that may not overlap the text (pos@allowOverlap="0").""" + + placed: list[tuple[int, int, int]] = [] + narrow: dict[int, int] = {} + own = None + for index, (height, advance) in enumerate(metrics): + y = placed[-1][0] + placed[-1][2] if placed else top + if obj is not None and index == anchor: + own = _cell_band(measure, obj, y - (prev if index == 0 else 0), width) + stays = own if empty and index == 0 and obj is not None \ + and obj.find(f"{HP}pos").get("allowOverlap") == "0" else None + around = [*bands, *(() if own is None else (own,))] + moved = True + while moved: + moved = False + for band in around: + if band is not stays and band[2] is None and y < band[1] and y + height > band[0]: + y, moved = band[1], True + beside = [band[2] for band in around if band[2] is not None and y < band[1] and y + height > band[0]] + if beside: + narrow[index] = _BothSides(min(beside)) if any(isinstance(room, _BothSides) for room in beside) else min(beside) + placed.append((y, height, advance)) + return placed, narrow, own + + +def _placed_top_and_bottom(obj: Any) -> bool: + """An object placed top and bottom from its paragraph's top, not set as a character.""" + + pos = obj.find(f"{HP}pos") + return pos is not None and pos.get("treatAsChar") != "1" and obj.get("textWrap") == "TOP_AND_BOTTOM" \ + and pos.get("vertRelTo") == "PARA" and pos.get("vertAlign", "TOP") == "TOP" + + +def _placed_from(paragraph: Any) -> bool: + """Whether *paragraph* holds an object placed from it in the text's flow: not set as a character, nor in + front of or behind the text.""" + + return any(_local(child) in _OBJECTS and child.find(f"{HP}pos") is not None + and child.find(f"{HP}pos").get("treatAsChar") != "1" and not _floating(child) + for run in paragraph.findall(f"{HP}run") for child in run) + + +def _object_before_text(runs: list[Any], headed: bool = False) -> Any: + """The object placed top and bottom from its paragraph's top (a table, picture or drawing) that is all the + runs hold but text after it -- a space is text, and so is the bullet or number of a *headed* paragraph or + an object in front of or behind the text beside it (see :func:`_beside_floating`) -- or ``None``.""" + + objects = [child for run in runs for child in run if _local(child) in _OBJECTS and not _floating(child)] + if len(objects) != 1 or not _placed_top_and_bottom(objects[0]) \ + or not (_run_text(runs) or headed or _beside_floating(runs)): + return None + for child in (child for run in runs for child in run): + if child is objects[0]: + return child + if _local(child) == "t" and _t_text(child).strip(): # text before it + return None + return None + + +def _beside_floating(runs: list[Any]) -> bool: + """Whether the runs hold an object in front of or behind the text: beside an object placed top and bottom + from the paragraph's top in a paragraph of no text, it sends the paragraph's empty line below that object, + as the whole width, as a space or a label does.""" + + return any(_local(child) in _OBJECTS and _floating(child) for run in runs for child in run) + + +def _table_on_its_own(paragraph: Any) -> bool: + """Whether a cell paragraph holds no text, not even a space, and nothing but one table placed top and + bottom from its top (Hancom sets the empty line below two of them, not beside them, and so with an object + in front of or behind the text beside it).""" + + runs = paragraph.findall(f"{HP}run") + objects = [child for run in runs for child in run if _local(child) in _OBJECTS] + return not _run_text(runs) and len(objects) == 1 and _local(objects[0]) == "tbl" \ + and _placed_top_and_bottom(objects[0]) + + +def _table_before_text(runs: list[Any]) -> Any: + """The table placed top and bottom from its paragraph's top that is all the runs hold but text after it + (text, a space being enough, or an object in front of or behind the text beside it), or ``None``.""" + + objects = [child for run in runs for child in run if _local(child) in _OBJECTS and not _floating(child)] + if len(objects) != 1 or _local(objects[0]) != "tbl" or not _placed_top_and_bottom(objects[0]) \ + or not (_run_text(runs) or _beside_floating(runs)): + return None + for child in (child for run in runs for child in run): + if child is objects[0]: + return child + if _local(child) == "t" and _t_text(child).strip(): # text before it + return None + return None + + +def _placed_objects(runs: list[Any]) -> list[Any]: + """The objects of the runs.""" + + objects = [child for run in runs for child in run if _local(child) in _OBJECTS] + for obj in objects: + if obj.find(f"{HP}pos") is None or obj.find(f"{HP}sz") is None: + raise _Unsupported(f"{_local(obj)} without a position") + return [obj for obj in objects if not _floating(obj) and not _on_paper(obj)] + + +def _marks(runs: list[Any]) -> bool: + """Whether the runs hold composed characters or ruby text.""" + + return any(_local(child) in _MARKS for run in runs for child in run) + + +def _check_ruby_spacing(runs: list[Any], shape: _Shape) -> None: + """A line holding ruby text is spaced from its height in percent: other line spacing is not followed.""" + + if shape.kind != "PERCENT" and any(_local(child) == "dutmal" for run in runs for child in run): + raise _Unsupported("ruby text in a paragraph with line spacing other than percent") + + +def _mark_extent(mark: Any, size: int, style: Any) -> tuple[int, int]: + """(width, height) a composed character or ruby text takes as a character of *size* and *style*. A + composed one is as wide as a Hangul syllable when framed or spread, else as its widest character, + and no taller than the text. Ruby text is as wide as its text, however long the ruby, and as tall as + the text with the ruby above it, or below it over the text's foot, in 1/1800 inch.""" + + points = size / 100 + if _local(mark) == "compose": + text = mark.get("composeText", "") + if mark.get("circleType", "CHAR") != "CHAR" or mark.get("composeType") == "SPREAD" or not text: + return round(char_advance("\uac00", points, style)), size + return round(max(char_advance(ch, points, style) for ch in text)), size + position = mark.get("posType", "TOP") + if position not in ("TOP", "BOTTOM"): + raise _Unsupported(f"ruby text placed {position}") + main = mark.find(f"{HP}mainText") + width = round(sum(char_advance(ch, points, style) for ch in (main.text or "" if main is not None else ""))) + em, ruby = size // 4, size * (int(mark.get("szRatio") or 0) or 50) // 100 // 4 + return width, 4 * (em + ruby if position == "TOP" else em * 91 // 100 + ruby) + + +def _on_paper(obj: Any) -> bool: + """A top-and-bottom object placed from the top or the bottom of the paper or of the page, or centred on it, + not set as a character: it takes no room in its paragraph but keeps every line of its page out of its band. + One wrapped square there counts as well (see :func:`_paper_band`).""" + + pos = obj.find(f"{HP}pos") + return (pos is not None and pos.get("treatAsChar") != "1" and obj.get("textWrap") in ("TOP_AND_BOTTOM", "SQUARE") + and pos.get("vertRelTo") in ("PAPER", "PAGE") + and pos.get("vertAlign", "TOP") in ("TOP", "CENTER", "BOTTOM")) + + +def _floating(obj: Any) -> bool: + """An object in front of or behind the text, not set as a character: the text flows as if it were not + there.""" + + pos = obj.find(f"{HP}pos") + return obj.get("textWrap") in _FLOATING and (pos is None or pos.get("treatAsChar") != "1") + + +def _text_size(measure: _Measure, runs: list[Any], paragraph: Any = None) -> tuple[int, list[Any], list[int]]: + """The paragraph's character size (its smallest), the character shapes of its runs holding text + (the style comes from the first), and each character's size. An empty run takes no room; a paragraph + without text is as tall as the largest of its runs holding controls or objects and its last run, and, + given the *paragraph*, as the number label Hancom draws for it (in its own character shape; a bullet's + takes the paragraph's end's, see :meth:`_Measure.label_size`).""" + + lengths = [sum(len(_t_text(text)) for text in run.findall(f"{HP}t")) for run in runs] + refs = [run.get("charPrIDRef") for run, length in zip(runs, lengths) if length] + refs = refs or [run.get("charPrIDRef") for run in runs if run.find(f"{HP}t") is not None] + refs = refs or [run.get("charPrIDRef") for run in runs] or ["0"] + sizes: list[int] = [] + for run, length in zip(runs, lengths): + sizes += [measure.char_height(run.get("charPrIDRef"))] * length + if not sizes and runs: # no text: as tall as its runs holding controls or objects, and its end (the last run) + held = [run.get("charPrIDRef") for run in runs[:-1] if any(child.tag != f"{HP}t" for child in run)] + tall = max(measure.char_height(ref) for ref in [*held, runs[-1].get("charPrIDRef")]) + if paragraph is not None and measure.headed(paragraph): + tall = max(tall, measure.label_size(paragraph.get("paraPrIDRef"), runs[-1].get("charPrIDRef"))) + return tall, refs, sizes + return min(sizes or [measure.char_height(ref) for ref in refs]), refs, sizes + + +def _end_size(measure: _Measure, runs: list[Any], sizes: list[int]) -> int: + """The size the paragraph's end gives its last line: an empty run ending a paragraph with text makes that + line as tall as itself when it is larger than the line's text, whatever the lines before it hold (an empty + run before the text does not); 0 when it is no larger than any character.""" + + if not runs or not sizes or any(len(child) or child.tag != f"{HP}t" or child.text for child in runs[-1]): + return 0 + size = measure.char_box(runs[-1].get("charPrIDRef")) + if _run_text(runs).endswith("\n"): # after a line break the empty last line is the run alone: as tall as + return size if size != sizes[-1] else 0 # itself, smaller or larger (see _line_metrics) + return size if size > min(sizes) else 0 + + +def _end_ref(paragraph: Any) -> Any: + """The character shape of a paragraph's end: its last run's, or None without runs.""" + + runs = paragraph.findall(f"{HP}run") + return runs[-1].get("charPrIDRef") if runs else None + + +def _head_size(measure: _Measure, paragraph: Any, sizes: list[int]) -> int: + """The size a bullet or number label (in its own character shape, or without one in that of the + paragraph's end), or a run holding nothing but controls before the text (a section's or columns' + definition, a page number: an empty run takes no room) or an object not set as a character, gives its + paragraph's first line: a character of that size there (it counts when it is larger than the smallest + character); 0 when not.""" + + if not sizes: + return 0 + size = measure.label_size(paragraph.get("paraPrIDRef"), _end_ref(paragraph)) + for run in paragraph.findall(f"{HP}run"): + if any(child.text or len(child) for child in run.findall(f"{HP}t")): # the text starts + break + if run.find(f"{HP}ctrl") is not None or run.find(f"{HP}secPr") is not None or any( + _local(child) in _OBJECTS and (child.find(f"{HP}pos") is None + or child.find(f"{HP}pos").get("treatAsChar") != "1") + for child in run): + size = max(size, measure.char_height(run.get("charPrIDRef"))) + return size if size > min(sizes) else 0 + + +def _held_sizes(measure: _Measure, runs: list[Any], sizes: list[int]) -> dict[int, int]: + """Where in the text a run holding a control shown on a line (see :func:`_shown_control`; not a note) or an + object not set as a character stands after the first character -> that run's size, when it is larger than the + smallest character: Hancom sets it as a character of no width, the line it falls on as tall as its run's + characters (those before the text, see :func:`_head_size`). Each character whose shape draws a border above + or below it is held too, its line as tall as the character and the border (see :meth:`_Measure.char_box`).""" + + if not sizes: + return {} + place, held = 0, {} + for run in runs: + box = measure.char_box(run.get("charPrIDRef")) + boxed = box > measure.char_height(run.get("charPrIDRef")) # a border above or below its characters + for child in run: + name = _local(child) + if name == "t": + for offset in range(len(_t_text(child))) if boxed else (): + held[place + offset + 1] = max(held.get(place + offset + 1, 0), box) + place += len(_t_text(child)) + elif place and (_shown_control(child) and not any(_local(kind) in ("footNote", "endNote") for kind in child) + or name in _OBJECTS and (child.find(f"{HP}pos") is None + or child.find(f"{HP}pos").get("treatAsChar") != "1")): + size = measure.char_height(run.get("charPrIDRef")) + if size > min(sizes): + held[place] = max(held.get(place, 0), size) + return held + + +def _char_styles(measure: _Measure, paragraph: Any, runs: list[Any]) -> list[Any] | None: + """Each character's style from its own run when the runs holding text differ in face, 장평 or 자간; + ``None`` when they do not.""" + + para_pr = paragraph.get("paraPrIDRef") + looks: list[Any] = [] + for run in runs: + length = sum(len(_t_text(text)) for text in run.findall(f"{HP}t")) + if length: + looks += [measure.style(para_pr, [run.get("charPrIDRef")])] * length + return looks if len(set(looks)) > 1 else None + + +def _line_sizes(measure: _Measure, sizes: list[int], style: Any, styles: list[Any] | None, shape: _Shape) -> list[int]: + """Each character's size as its line's height counts it: the size, or in a paragraph taking its line height + from the font (``fontLineHeight``) the height the character's face gives a line of that size.""" + + if not shape.font_line: + return sizes + return [measure.font_line(size, styles[index] if styles else style) for index, size in enumerate(sizes)] + + +def _metric_starts(measure: _Measure, text: str, widths: list[float], sizes: list[int], style: Any, + objects: dict[int, tuple[int, int]], styles: list[Any] | None = None, + marks: dict[int, int] | None = None) -> list[int]: + """Where each line :func:`_line_metrics` lays out starts in *text*.""" + + advances = {**{index: width for index, (width, _) in objects.items()}, **(marks or {})} or None + return measure.line_starts(text, widths, min(sizes), style, sizes if len(set(sizes)) > 1 else None, styles, + advances, set(objects)) + + +def _line_metrics(measure: _Measure, text: str, widths: list[float], sizes: list[int], style: Any, + shape: _Shape, objects: dict[int, tuple[int, int]], styles: list[Any] | None = None, + marks: dict[int, int] | None = None, end: int = 0, head: int = 0, + held: dict[int, int] | None = None) -> tuple[tuple[int, int], ...]: + """(height, advance) of each line FormFit breaks *text* into, every character at its own size: a line + is as tall as its largest character, its line spacing reckoned from that size. An object set as a + character (*objects*: its place in *text* -> its width and height) takes its width on its line and + makes the line at least as tall as itself; its run's size counts for the line spacing alone, not for the + line's height (Hancom: as tall as its characters and objects, spaced from its largest size); a fixed line spacing + keeps the next line that far down. A composed character or ruby text (*marks*: its place -> its + width) is a character of its size in *sizes*. The last line is at least as tall as the paragraph's + end (*end*, see :func:`_end_size`), and the first as its label (*head*, see :func:`_head_size`); a control or + an object not set as a character after the first character (*held*: its place -> its run's size, see + :func:`_held_sizes`) makes the line it falls on as tall as a character of that size. In a + paragraph taking its line height from the font each of them counts as tall as its face makes a line + (:func:`_line_sizes`).""" + + starts = _metric_starts(measure, text, widths, sizes, style, objects, styles, marks) + heights = _line_sizes(measure, sizes, style, styles, shape) + if shape.font_line: + end, head = measure.font_line(end, style), measure.font_line(head, style) + held = {place: measure.font_line(tall, style) for place, tall in (held or {}).items()} + metrics = [] + broken = text.endswith("\n") and starts[-1] == len(text) # an empty last line after a line break + for number, (start, stop) in enumerate(zip(starts, [*starts[1:], len(text)])): + last = number == len(starts) - 1 + span = range(start, stop) if stop > start else range(len(text) - 1, len(text)) + if last and broken and end: # the empty line is the paragraph's end alone + span = range(0) + edges = ([end] if last else []) + ([head] if start == 0 else []) + [tall for place, tall in (held or {}).items() if start < place <= stop] + size = max([heights[index] for index in span] + edges) + glyphs = [heights[index] for index in span if index not in objects] + edges + height = max([max(glyphs) if glyphs else size] + [objects[index][1] for index in span if index in objects]) + advance = _pitch(shape.kind, shape.value, size) + metrics.append((height, advance if shape.kind == "FIXED" else height + advance - size)) + return tuple(metrics) + + +def _drawn_height(obj: Any, measure: _Measure) -> int: + """How tall Hancom draws *obj*: a drawing holding a text box (hp:drawText) as tall as the box's text and + its margins when that is taller than hp:sz -- Hancom grows the drawing to hold them, writing the grown size + to hp:curSz alone (negative for a drawing scaled upside down), at times one less, which makes that a lower + bound within a unit or two; a grown size further off was written for other fonts or text, and Hancom lays the + text out anew. When the text cannot be laid out, the grown size stands. Any other object (a table too) as + hp:sz.""" + + height = int(obj.find(f"{HP}sz").get("height", 0)) + box = obj.find(f"{HP}drawText") + if box is None: + return height + current = obj.find(f"{HP}curSz") + grown = 0 if current is None else int(current.get("height", 0)) + if grown >= 1 << 31: # negative, kept unsigned: as tall upside down + grown = (1 << 32) - grown + if grown >= 1 << 30: + grown = 0 + paragraphs = box.findall(f"{HP}subList/{HP}p") + if not paragraphs: + return max(height, grown) + margin = box.find(f"{HP}textMargin") + left, right, top, bottom = (0, 0, 0, 0) if margin is None else ( + int(margin.get(side, 0)) for side in ("left", "right", "top", "bottom")) + width = int(box.get("lastWidth", 0)) or int(obj.find(f"{HP}sz").get("width", 0)) + try: # its first line below the first paragraph's spacing before, as in a cell + content = measure.shape(paragraphs[0].get("paraPrIDRef")).prev \ + + measure.stack(paragraphs, width - left - right, caches=True)[0] + except _Unsupported: + return max(height, grown) + laid = top + content + bottom + # Hancom lays the box's text out anew: a grown size written for other fonts or text does not hold + return max(height, laid, grown if abs(grown - laid) <= 2 else 0) + + +#: How far each parallel shadow moves from its object before its own offset: Hancom draws a bottom shadow +#: ``offsetY + 600`` down and a top one ``offsetY - 600`` (down positive), whatever the object's size or line. +_SHADOW_DISTANCE = 600 + + +def _shadow_drop(obj: Any) -> int: + """How far the parallel shadow of *obj* (``hp:shadow``) is moved up or down from it: an object set as a + character is that much taller (drawn lower when the shadow goes up). 0 without one; other shadows are not + followed.""" + + shadow = obj.find(f"{HP}shadow") + kind = "" if shadow is None else shadow.get("type", "NONE") + if not kind.startswith(("PARELLEL_", "PARALLEL_")): + return 0 + offset = int(shadow.get("offsetY", 0)) # written as signed text, as Hancom reads it + if not -(1 << 31) <= offset < 1 << 31: + raise _Unsupported("a shadow offset past 32 bits") + return abs(offset + _SHADOW_DISTANCE if kind.endswith("BOTTOM") else offset - _SHADOW_DISTANCE) + + +#: A picture's shadow spreads in whole pixels at 96 per inch (75 HWPUNIT): a radius of 400 spreads as 450. +_SHADOW_BLUR_STEP = 75 + + +def _effect_room(obj: Any, width: int, height: int) -> tuple[int, int, int, int]: + """(left, right, top, bottom): how much farther than its *width* x *height* a picture's effects + (``hp:effects``) reach, which Hancom lays it out with: a glow its ``radius`` on each side, and an outer + shadow the picture (with its glow) moved ``distance`` in its ``direction`` (degrees clockwise on the page + from the right) and spread by its ``radius`` on each side, rounded up to whole pixels (see + :data:`_SHADOW_BLUR_STEP`); each reach is cut to a whole HWPUNIT. An inner shadow and a soft edge take no room. + A reflection reaches below about its ``pos`` share of the picture (with its glow, and a pixel on each side) + less a pixel, and its ``distance``: within about a pixel of Hancom's, the extra not followed.""" + + effects = obj.find(f"{HP}effects") + if effects is None or len(effects) == 0: + return 0, 0, 0, 0 + glow = effects.find(f"{HP}glow") + reach = 0 if glow is None else max(0, int(float(glow.get("radius", 0)))) + left, top, right, bottom = -reach, -reach, width + reach, height + reach + shadow = effects.find(f"{HP}shadow") + if shadow is not None and shadow.get("style", "OUTSIDE") != "INSIDE": + angle = math.radians(float(shadow.get("direction", 0))) + distance, blur = float(shadow.get("distance", 0)), max(0.0, float(shadow.get("radius", 0))) + blur = math.ceil(blur / _SHADOW_BLUR_STEP) * _SHADOW_BLUR_STEP # in whole pixels, as Hancom spreads it + dx, dy = round(distance * math.cos(angle), 9), round(distance * math.sin(angle), 9) # 0 at 90, 180 ... + left, right = min(left, left + dx - blur), max(right, right + dx + blur) + top, bottom = min(top, top + dy - blur), max(bottom, bottom + dy + blur) + room = [math.floor(-left), math.floor(right - width), math.floor(-top), math.floor(bottom - height)] + reflection = effects.find(f"{HP}reflection") + share = None if reflection is None else reflection.find(f"{HP}pos") + size = 0.0 if share is None else float(share.get("end", 0)) - float(share.get("start", 0)) + if reflection is not None and size > 0: # about that much of the picture (with its glow, a pixel round it) + below = (size * (height + 2 * reach + 2 * _SHADOW_BLUR_STEP) - _SHADOW_BLUR_STEP + + max(0.0, float(reflection.get("distance", 0)))) + room[3] = max(room[3], math.floor(below) - room[2]) + return room[0], room[1], room[2], room[3] + + +def _object_extent(obj: Any, measure: _Measure) -> tuple[int, int]: + """(width, height) an object set as a character takes, its outer margins included; a table as tall + as its rows, a drawing with its shadow's move (see :func:`_shadow_drop`), a picture with the room its + effects take (see :func:`_effect_room`). Set as a character, any object's caption takes room as a + table's does: above or below it, its lines and its gap in the height (see :func:`_caption`); beside it, its + width and its gap in the width, the height staying the object's however tall the caption runs.""" + + size = obj.find(f"{HP}sz") + margin = obj.find(f"{HP}outMargin") + extra = (0, 0, 0, 0) if margin is None else tuple(_margin(margin, side) for side in ("left", "right", "top", "bottom")) + tac = obj.find(f"{HP}pos").get("treatAsChar") == "1" + height = _inline_table_height(measure, obj) + sum(_caption(measure, obj)) if _local(obj) == "tbl" \ + else _drawn_height(obj, measure) + (_shadow_drop(obj) if tac else 0) + width = int(size.get("width", 0)) + left, right, top, bottom = _effect_room(obj, width, height) if tac else (0, 0, 0, 0) + if tac and _local(obj) != "tbl": + height += sum(_caption(measure, obj)) + width += _caption_beside(obj) + return width + extra[0] + extra[1] + left + right, height + extra[2] + extra[3] + top + bottom + + +def _caption_beside(obj: Any) -> int: + """How much wider an object set as a character is for its caption beside it: the caption's width and its + gap (none for a caption above or below it).""" + + caption = obj.find(f"{HP}caption") + if caption is None or caption.get("side", "LEFT") not in ("LEFT", "RIGHT"): + return 0 + return int(caption.get("width", 0)) + int(caption.get("gap", 0)) + + +def _inline_content(measure: _Measure, paragraph: Any, runs: list[Any], anchored: Any = None, + placed: tuple[Any, ...] = ()) -> tuple[ + str, list[int], list[Any], dict[int, tuple[int, int]], dict[int, int]]: + """The paragraph's text with each object set as a character, composed character and ruby text in its + place (U+FFFC), each character's size and style (ruby text's is the height of its line), each + object's place -> its width and height, and each composed character's or ruby text's place -> its + width. A control shown on a line (see :func:`_shown_control`) after the first character is an object of no + width as tall as its run's characters (those before it stand on the first line, see :func:`_head_size`). + Objects placed otherwise (but *anchored* and *placed*, laid out apart), and line spacing between + lines or at least with an object among text, are not followed.""" + + shape = measure.shape(paragraph.get("paraPrIDRef")) + text: list[str] = [] + sizes: list[int] = [] + looks: list[Any] = [] + objects: dict[int, tuple[int, int]] = {} + marks: dict[int, int] = {} + for run in runs: + ref = run.get("charPrIDRef") + height, look = measure.char_height(ref), measure.style(paragraph.get("paraPrIDRef"), [ref]) + for child in run: + name = _local(child) + if name in _OBJECTS and (_floating(child) or _on_paper(child) or child is anchored + or any(child is obj for obj in placed)): + continue + if name in _OBJECTS: + if child.find(f"{HP}pos").get("treatAsChar") != "1" or shape.kind not in ("PERCENT", "FIXED"): + raise _Unsupported("an object with text or other objects in its paragraph") + objects[len(text)] = _object_extent(child, measure) + part = "\ufffc" + elif name in _MARKS: + marks[len(text)], tall = _mark_extent(child, height, look) + text.append("\ufffc") + sizes.append(tall) + looks.append(look) + continue + elif name == "t": + part = _t_text(child) + elif text and _shown_control(child): # a character of no width as tall as its run's, on the line it + objects[len(text)] = (0, height) # falls on: an object's that fits, the next past one wider than it + part = "" + else: + continue + text += part + sizes += [height] * len(part) + looks += [look] * len(part) + return "".join(text), sizes, looks, objects, marks + + +def _shown_control(child: Any) -> bool: + """Whether *child* of a run is a control Hancom sets on a line as a character (a page number, a field, a + bookmark and so on -- not a column or section definition).""" + + return _local(child) == "ctrl" and any(_local(kind) not in ("colPr",) for kind in child) + + +def _anchor_line(measure: _Measure, paragraph: Any, runs: list[Any], text: str, obj: Any, widths: list[float], + size: int, style: Any, cached: tuple[tuple[int, int], ...], count: int) -> int: + """The line *obj*'s place in the text falls on: in a line cache, where Hancom counts every object and + control as eight characters, the last line starting at or before it; otherwise the line holding the + character before it.""" + + place = objects = 0 + for child in (child for run in runs for child in run): + if child is obj: + break + if _local(child) == "t": + place += len(_t_text(child)) + elif _local(child) in _OBJECTS or _local(child) == "ctrl": # every object and control takes eight + objects += 1 + segments = paragraph.findall(f"{HP}linesegarray/{HP}lineseg") if cached else [] + if segments: # lines Hancom laid out (not ones laid out here) + starts = [int(segment.get("textpos", 0)) for segment in segments] + place += 8 * objects # its own place in the cache, before its own eight + else: + starts = measure.line_starts(text, widths, size, style) + return max((index for index, start in enumerate(starts[:count]) if start < place), default=0) + return max((index for index, start in enumerate(starts[:count]) if start <= place), default=0) + + +def _extent(obj: Any, side: str, measure: _Measure | None = None) -> int: + """An object's width or height (*side*), its outer margins included; given *measure*, the height as Hancom + draws it (:func:`_drawn_height`).""" + + margin = obj.find(f"{HP}outMargin") + ends = ("left", "right") if side == "width" else ("top", "bottom") + extra = 0 if margin is None else sum(_margin(margin, end) for end in ends) + if side == "height" and measure is not None: + return _drawn_height(obj, measure) + extra + return int(obj.find(f"{HP}sz").get(side, 0)) + extra + + +def _wraps_top_and_bottom(obj: Any, column: int) -> bool: + """Top and bottom, or square with no line's room beside it: an object as wide as the column, or one + placed from the column's or its paragraph's left or right that leaves less than 1440 of it on either + side (the text going to either side, or to the wider), pushes the text below it either way.""" + + wrap = obj.get("textWrap") + if wrap == "TOP_AND_BOTTOM": + return True + width = _extent(obj, "width") + if wrap != "SQUARE" or width >= column: + return wrap == "SQUARE" + pos = obj.find(f"{HP}pos") + if pos is None or pos.get("horzRelTo") not in ("COLUMN", "PARA") or pos.get("horzAlign") not in ("LEFT", "RIGHT") \ + or obj.get("textFlow", "BOTH_SIDES") not in ("BOTH_SIDES", "LARGEST_ONLY"): + return False + offset = _pos_offset(pos, "horzOffset") + if offset >= 1 << 31: # kept unsigned: one placed out past the edge + offset -= 1 << 32 + start = offset if pos.get("horzAlign") == "LEFT" else column - width - offset + return start < _MIN_SIDE and column - start - width < _MIN_SIDE + + +def _wrapped_widths(measure: _Measure, text: str, widths: list[float], size: int, style: Any, shape: _Shape, + wrap: _Wrap, sizes: list[int] | None, looks: list[Any] | None) -> tuple[list[float], set[int]]: + """Each FormFit line's width with the lines whose top is in *wrap*'s band cut narrower, or split in two + pieces at one height beside an object with text on both sides, and the FormFit lines that are such a + line's first piece (FormFit breaks the lines, and which lines are in the band follows from their + heights; repeated until it settles).""" + + narrow: set[int] = set() # lines in the band, as the lines Hancom draws + for _ in range(8): + lines: list[float] = [] + firsts: set[int] = set() + for index in range(max(narrow, default=0) + 2): + full = widths[min(index, 1)] + if index in narrow and wrap.column: + pieces = wrap.pieces(full, shape.right) + if len(pieces) > 1: + firsts.add(len(lines)) + lines += pieces + elif index in narrow and wrap.split: + firsts.add(len(lines)) + lines += [wrap.split, full - wrap.cut - wrap.split] + else: + lines.append(full - (wrap.cut if index in narrow else 0)) + starts = measure.line_starts(text, lines, size, style, sizes, looks) + top, found, index, piece = 0, set(), 0, 0 + while piece < len(starts): + pieces = 2 if piece in firsts and piece + 1 < len(starts) else 1 + start, end = starts[piece], starts[piece + pieces] if piece + pieces < len(starts) else len(text) + height = max((sizes or [size])[start:end] or [size]) if sizes else size + if shape.font_line: + height = measure.font_line(height, style) + if top < wrap.bottom and top + height > wrap.top: + found.add(index) + top += _pitch(shape.kind, shape.value, height) + index, piece = index + 1, piece + pieces + if found == narrow: + return lines, firsts + narrow = found + raise _Unsupported("lines beside a square-wrapped object that do not settle") + + +def _at_one_height(metrics: tuple[tuple[int, int], ...], firsts: set[int]) -> tuple[tuple[int, int], ...]: + """*metrics* with each line of two pieces (*firsts*: its first piece) as tall as its taller piece, the + second piece at the first's height. When the text ends in a line's first piece, Hancom writes the second + one empty, at that height.""" + + lines = list(metrics) + for first in sorted(firsts): + if first + 1 < len(lines): + (height, advance), (other, after) = lines[first], lines[first + 1] + lines[first], lines[first + 1] = (max(height, other), 0), (max(height, other), max(advance, after)) + elif first == len(lines) - 1: # the text ends in it: an empty second piece + height, advance = lines[first] + lines[first:] = [(height, 0), (height, advance)] + return tuple(lines) + + +# -- laying the paragraphs out --------------------------------------------------------------------- + + +def _lines_of(para: _Para, first: int, count: int, *, prev: int, after: int) -> _Para: + """Lines *first* .. *first* + *count* of *para* as a paragraph of their own.""" + + cached = para.cached[first:first + count] if para.cached else () + return replace(para, lines=count, prev=prev, next=after, cached=cached, notes={}, anchor=None, + keep_next=False if after == 0 else para.keep_next) + + +def _repeated_header(table: _FlowTable) -> int: + return sum(row.height for row in table.rows if row.header) if table.repeat_header else 0 + + +def _spare_cut(table: Any) -> int: + return _SPARE_CUT_FIXED if table.get("noAdjust") == "1" else _SPARE_CUT + + +def _starts_later(table: _FlowTable, y: int, body: int) -> bool: + """Whether a table moved row by row (TABLE) has no room for its first row from *y*, one set not to + split (NONE) no room for all its rows, one split cell by cell (CELL) room for none of its first row's + lines, or one moved row by row or split cell by cell no room for the header rows it repeats, so it starts + on the next page. At the top of a page it is drawn anyway.""" + + if table.mode not in ("TABLE", "NONE", "CELL") or not table.rows: + return False + if _header_moves(table, y, body - table.margins[1]): + return True + if table.mode == "CELL": # its first row goes on whole + top = _repeated_header(table) + table.margins[0] + row = table.rows[0] + return not row.joined and y != top \ + and _flow_row("CELL", row, 0, y, body - table.margins[1], top, table.cut) == (1, top + row.height) + first = sum(row.height for row in table.rows) if table.mode == "NONE" else table.rows[0].height + return y + first > body - table.margins[1] - table.cut \ + and y != _repeated_header(table) + table.margins[0] + + +def _header_moves(table: _FlowTable, y: int, body: int) -> bool: + """Whether a table moved row by row or split cell by cell (TABLE, CELL) has no room from *y* above + *body* for the header rows it repeats on every page: Hancom does not split them, so the table starts on + the next page, the header rows at its top. At a page's top they are drawn anyway.""" + + header = _repeated_header(table) + return table.mode in ("TABLE", "CELL") and bool(header) and y + header > body - table.cut \ + and y > table.margins[0] + + +def _flow_table(table: _FlowTable, frame: int, y: int, body: int) -> tuple[int, int]: + """Lay the rows out from vertical position *y*; the frame and position where the table ends.""" + + body -= table.margins[1] # the rows keep the table's bottom margin above the page end + header = _repeated_header(table) + table.margins[0] # and go on below its top margin on the next page + foot = body - table.cut + # split between cell lines, it keeps the room of a caption below it at the foot of every page it goes on from + room = body - table.caption[1] if table.mode == "CELL" else body + if _header_moves(table, y, body): # its repeated header rows start the next page (drawn there once) + frame, y = frame + 1, table.margins[0] + if table.mode == "NONE": # set not to split: its rows move as one, drawn anyway at a page's top + height = sum(row.height for row in table.rows) + if y + height > foot and y != header: + frame, y = frame + 1, header + return frame, y + height + rows, index = table.rows, 0 + while index < len(rows): + end = index + while rows[end].joined and end + 1 < len(rows): + end += 1 + if table.mode == "TABLE" and end > index: # rows joined by merged cells move as one + height = sum(row.height for row in rows[index:end + 1]) + if y + height > foot and y != header: + if index == 0: + raise _Unsupported("a table whose first rows, merged together, have no room under its anchor") + frame, y = frame + 1, header + if y + height > foot: + raise _Unsupported("rows merged together taller than a page") + y, index = y + height, end + 1 + continue + if table.mode == "CELL" and end > index and table.cells \ + and y + sum(row.height for row in rows[index:end + 1]) > foot: # split cell by cell + frame, y = _split_block(table, index, end, frame, y, room, header) + index = end + 1 + continue + before, start = frame, y + above = index == len(rows) - 1 and table.caption[1] and table.mode == "CELL" and rows[index].spare \ + and not rows[index].nested # a caption below keeps its room: the row's room to spare is cut above it + frame, y = _flow_row(table.mode, rows[index], frame, y, + body - (table.caption[1] if above else 0) if index == len(rows) - 1 else room, header, + table.cut) + if rows[index].merged and frame != before: + raise _Unsupported("a page break among rows merged in a flowing table") + if index == len(rows) - 1 and table.caption[1] and not above and frame == before and start != header \ + and y + table.caption[1] > foot: # a caption below goes on with the last row + frame, y = frame + 1, header + rows[index].height + index += 1 + return frame, y + + +def _split_block(table: _FlowTable, first: int, last: int, frame: int, y: int, body: int, + header: int) -> tuple[int, int]: + """Rows *first*..*last*, joined by merged cells and starting at *y*, in a table split between cell + lines when the page end falls among them: each page keeps the lines that fit, and what is left goes on + below the next page's *header*, split again at that page's end until it fits. The frame and position + where they end.""" + + foot, before = body - table.cut, None + while True: + cut, heights, cells = _block_rest(table, first, last, y, body) + rest = sum(heights.values()) + if not rest: # every cell done above the page end, what it declares below dropped: they end there + return frame, body + if header + rest <= foot: + return frame + 1, header + rest + if before is not None and rest >= before: # nothing of it fits a page + raise _Unsupported("rows merged together taller than a page") + rows = list(table.rows) + for index, height in heights.items(): + rows[index] = replace(rows[index], height=height) + table, first, frame, y, before = replace(table, rows=rows, cells=tuple(cells)), cut, frame + 1, header, rest + + +def _block_rest(table: _FlowTable, first: int, last: int, top: int, + body: int) -> tuple[int, dict[int, int], list[tuple[int, int, _Row]]]: + """What goes on to the next page of rows *first*..*last*, joined by merged cells, when the page end + falls among them in a table split between cell lines: every cell keeps the lines that fit above + the page end and the rest go on. From the row the page end falls in, each row is as tall as the + rest of its cells of one row (the rows after it whole), then each merged cell's rest, the one + ending first first, adds what its rows lack to the last of them. The row the page end falls in, + each row's height from it on, and the cells that go on, each as tall as its rest with the lines + it has left.""" + + rows, tops, y, foot = table.rows, {}, top, body - table.cut + for index in range(first, last + 1): + tops[index] = y + y += rows[index].height + cut = next(index for index in range(first, last + 1) if tops[index] + rows[index].height > foot) + heights = dict.fromkeys(range(cut, last + 1), 0) + rests: list[tuple[int, int, int]] = [] + cells: list[tuple[int, int, _Row]] = [] + # a cell of the row the page end falls in keeping none of its lines above it sends the row's cells on whole + whole = any(_cell_rest(cell, tops[cut], foot) == (cell.height, cell.lines) and cell.lines and not cell.spare + for start, span, cell in table.cells if start == cut and span == 1) + for start, span, cell in table.cells: + end = start + span - 1 + if start < first or start > last or end < cut: + continue # another row, or done above the page end + part = (cell.height, cell.lines) if start > cut or whole and start == cut and span == 1 \ + else _cell_rest(cell, tops[start], foot) + if part is None: + continue + rest, begin = part[0], max(start, cut) + left = part[1] # the lines it has left are its last ones + # Once a line was consumed, a uniform paragraph no longer starts below its original spacing before. + cells.append((begin, end - begin + 1, replace(cell, height=rest, lines=left, **( + {"metrics": cell.metrics[len(cell.metrics) - left:], "leads": cell.leads[len(cell.leads) - left:]} + if _lists_lines(cell) else {"first": cell.size if left < cell.lines else cell.first})))) + if span == 1: + heights[start] = max(heights[start], rest) + else: + rests.append((begin, end, rest)) + for start, end, rest in sorted(rests, key=lambda item: (item[1], item[0])): + lacking = rest - sum(heights[index] for index in range(start, end + 1)) + heights[end] += max(lacking, 0) + return cut, heights, cells + + +def _lists_lines(cell: _Row) -> bool: + """Whether *cell* lists the (height, advance) of each of its lines (``_Row.metrics``): one of several + paragraphs, which may differ in size, holding no table.""" + + return bool(cell.metrics) and len(cell.metrics) == cell.lines and not cell.nested and not cell.pieces + + +def _cell_rest(cell: _Row, top: int, foot: int) -> tuple[int, int] | None: + """How tall the part of a cell starting at *top* that goes on past the page end *foot* is, and how many + lines it holds; ``None`` when nothing of it goes on. Each line takes its own height and advance where the + cell lists them (a line of a larger character size among others), else the cell's.""" + + lines = cell.metrics if _lists_lines(cell) else ((cell.size, cell.pitch),) * cell.lines + # the room above each line when a part of the cell starts with it: its paragraph's spacing before where the + # cell lists its lines, else above its first line what that line takes beyond the character size (its first + # paragraph's spacing before, or a taller first line) + leads = cell.leads if _lists_lines(cell) and len(cell.leads) == cell.lines \ + else (max(cell.first - cell.size, 0),) + (0,) * (cell.lines - 1) if cell.lines else () + fitting, y = 0, top + cell.margins + (leads[0] if leads else 0) + while fitting < cell.lines and y + lines[fitting][0] <= foot: + y += lines[fitting][1] + fitting += 1 + left = lines[fitting:] + height = cell.margins + (leads[fitting] if leads and left else 0) \ + + sum(advance for _, advance in left[:-1]) + left[-1][0] if left else 0 + if cell.spare and (fitting or not cell.lines): # its text (or what is left: none) starts above the page end: + # the declared room is cut like a row's, and the lines that do not fit go on with it, which is then + # at least as tall as they are with the cell's margins + rest = top + cell.height - foot + if left: + return max(rest, height), len(left) + return (rest, 0) if rest > _SPARE_DROPPED else None + if cell.spare: # none of it fits: it goes on whole + return cell.height, cell.lines + if not left: + return None + return height, len(left) + + +def _flow_row(mode: str, row: _Row, frame: int, y: int, body: int, header: int, + cut: int = _SPARE_CUT) -> tuple[int, int]: + """A row that does not fit even a fresh page is drawn there anyway, cut at the paper's edge; + CELL breaks a row between its lines, or a row taller than its text just above the page's foot.""" + + remaining, height, metrics, nested, leads = row.lines, row.height, row.metrics, row.nested, row.leads + cuts, blocks = row.cuts, row.blocks + foot = body - cut + consumed = 0 # how far down the cell's lines the part on this page starts + while True: + if y + height <= foot: + return frame, y + height + fresh = y == header + if mode == "CELL" and row.reaches and row.spare: + raise _Unsupported("a page end in a row declared taller than its text holding a table among its text") + if mode == "CELL" and nested and not row.pieces and row.spare: # declared taller than its text: cut + # like any such row (a row whose tables split goes on below as any cell's) + if y + row.margins + (metrics[0][0] if metrics else row.size) <= foot: # once its first line fits + rest = height - (foot - y) + fitting = _lines_fitting(metrics, leads, y + row.margins, foot) if metrics else 1 + if fitting < len(metrics): # its lines do not all fit: those that do not go on, at least + rest = max(rest, row.margins + _lines_height(metrics[fitting:], leads[fitting:])) + elif rest <= _SPARE_DROPPED: + return frame, body + frame, y, nested = frame + 1, header, False + remaining, height = 1, rest + continue + if fresh: + return frame, y + height + frame, y = frame + 1, header + continue + if mode == "CELL" and nested and not row.pieces: # between its lines, each as tall as it is (a table + # is one) + if not metrics: + if consumed or y + row.margins + row.first <= foot: + raise _Unsupported("a page break in a flowing table row holding a table") + if fresh: # no cell's first line fits (the table one stands on): the row goes on whole + return frame, y + height + frame, y = frame + 1, header + continue + fitting, top = 0, y + row.margins + (leads[0] if leads else 0) # a part starts below its first + # paragraph's spacing before, as any cell's + while fitting < len(metrics) and top + metrics[fitting][0] <= foot: + top += metrics[fitting][1] + fitting += 1 + cut = consumed + sum(advance for _, advance in metrics[:fitting]) # where the line not fitting stands + found = _reached(row, cut, top, foot, metrics[fitting], metrics[fitting + 1] if fitting + 1 < len(metrics) + else None) if row.reaches and fitting < len(metrics) else None + if found is not None: # a table among the text splits or goes on alone: what of it goes on, and that line + piece, consumed = found + metrics = (piece,) + metrics[fitting + 1:] + leads = (0,) + leads[fitting + 1:] if leads else () + height = row.margins + _lines_height(metrics, leads) + frame, y = frame + 1, header + continue + consumed = cut + if fitting == len(metrics): # every line fits, the cell's bottom margin not: cut like a row's + rest = height - (foot - y) + if rest <= _SPARE_DROPPED: + return frame, body + frame, y, nested = frame + 1, header, False + remaining, height, metrics, leads = 1, rest, (), () + continue + if fitting: + metrics, leads = metrics[fitting:], leads[fitting:] + height = row.margins + _lines_height(metrics, leads) + elif fresh: + return frame, y + height + frame, y = frame + 1, header + continue + if mode == "CELL": + lines = metrics or ((row.size, row.pitch),) * remaining + fitting = _lines_fitting(lines, leads, y + row.margins, foot, cuts) + if fitting and len(lines) == row.lines and y + row.margins + row.first > foot: + fitting = 0 # every cell's first line must fit, or the row goes on whole + split = _split_joined(lines, leads, cuts, blocks, fitting, y + row.margins, foot) \ + if blocks and fitting < len(lines) else None + if split is not None: # among a table's rows joined by merged cells: they split cell by cell + metrics, leads, cuts, blocks = split + remaining, height = len(metrics), row.margins + _lines_height(metrics, leads) + frame, y = frame + 1, header + continue + if fitting and (row.spare or fitting == len(lines)): # room under its lines: cut like a row's + rest = height - (foot - y) + if fitting < len(lines) and y + height - row.spare > foot: # its text does not all fit: + rest = max(rest, row.margins + _lines_height(lines[fitting:], leads[fitting:])) # it goes on + elif rest <= _SPARE_DROPPED: + return frame, body + frame, y = frame + 1, header + remaining, height, metrics, leads, cuts, blocks = 1, rest, (), (), (), () + continue + if fitting: + metrics, leads, cuts = lines[fitting:], leads[fitting:], cuts[fitting:] + blocks = tuple((start - fitting, *block) for start, *block in blocks if start >= fitting) + remaining, height = len(metrics), row.margins + _lines_height(metrics, leads) + elif fresh: + return frame, y + height + elif fresh: + return frame, y + height + frame, y = frame + 1, header + + +def _reached(row: _Row, cut: int, top: int, foot: int, line: tuple[int, int], + after: tuple[int, int] | None) -> tuple[tuple[int, int], int] | None: + """Check a page end before the row's *line* (height, advance), which stands *cut* below the top of the + cell's lines (and would stand at *top* on the page), against the tables among its text (see + :class:`_Reach`; *after*: the line after it, if any). Hancom moves such a table on to the next page with the + line its control falls on when that line does not fit and the table would fit (a table that may split: + its rows ending a table's cut, 101, above the foot with room for a caption below it), or would start past + the page's foot. When the first line it pushes below it does not fit and the table would not, the table + splits into its pieces (see :func:`_split_rows`): those so ending (a row going on with room for its bottom + margin too) stay, the rest go on at the next page's top below the table's top margin again (a row going on + below its own top margin again too) and + that line below them. When no piece stays, the table goes on alone to the next page's top (whatever its offset): the line + its control falls on stays where it is, and so does the line it pushes when that is the same, which then + fits, the next line going below the table on the next page (if it does not fit either, the table goes on + with it, as Hancom does from the line's top). Returned then: what of that line goes on, and where it starts + in the cell's lines. A page end through a table or between it and the line it pushes, past a table on this + page reaching the foot (with the cell's margins), before lines that would + fit on this page once the table has gone on alone (Hancom keeps them there, as if the table were not + there), or anything else about a table that may not split (or is not a table pushing the lines below it) + is not followed.""" + + found = None + height, advance = line + for reach in row.reaches: + if reach.line < cut and cut != reach.unit and (cut < reach.foot or top - cut + reach.foot > foot): + raise _Unsupported("a page end through a table among the text of a cell") + start = top + reach.top - cut # where the table would stand on this page + if cut not in (reach.line, reach.unit) or start >= foot or ( + start + reach.above + sum(piece[1] for piece in reach.rows[:-1]) + reach.rows[-1][0] + <= foot - _SPARE_CUT - reach.below + if reach.rows else start + reach.foot - reach.top <= foot): + continue # it fits, or starts past the foot: it goes on with the line + if cut != reach.unit or found is not None: + raise _Unsupported("a page end through a table among the text of a cell") + if not reach.rows: # a table that may not split goes on with the line from the line's top + if start + reach.first <= foot or top + reach.text <= foot or reach.top != cut: + raise _Unsupported("a page end through a table among the text of a cell") + continue + y, kept = start + reach.above, 0 + while kept < len(reach.rows) and y + reach.rows[kept][0] + reach.rows[kept][2] \ + <= foot - _SPARE_CUT - reach.below: + y += reach.rows[kept][1] + kept += 1 + joined = _joined_stays(reach, kept, start, foot) + if joined: # among rows joined by merged cells, split cell by cell: what of them stays, the rest + stays = reach.top - cut + joined - reach.above # going on below the table's top margin again + found = (height - stays, advance - stays), cut + stays + continue + if not kept and reach.line < cut and top + reach.text <= foot: # the lines would fit without it + raise _Unsupported("a page end past a table among the text of a cell going on alone") + if kept or reach.line < cut: # the rest goes on, the line below it + stays = reach.top - cut + (sum(piece[1] for piece in reach.rows[:kept]) # the rest below the table's + - reach.rows[kept][3] if kept else 0) # top margin again + found = (height - stays, advance - stays), cut + stays + elif top + reach.text <= foot: # the line stays, the table goes on alone, the next line below it + if after is not None and top + advance - (reach.foot - cut) + after[0] <= foot: # that one would fit + raise _Unsupported("a page end past a table among the text of a cell going on alone") + tall = reach.foot - reach.top + found = (tall, tall), cut + advance - tall + elif reach.top != cut: + raise _Unsupported("a page end through a table among the text of a cell") + return found + + +def _joined_stays(reach: _Reach, kept: int, start: int, foot: int) -> int: + """How far below its top the part of a table pushing a cell's lines below it (see :func:`_reached`), + standing at *start*, that stays above the page end *foot* reaches when that falls among rows joined by + merged cells (piece *kept* the first not fitting): each of their cells keeps the lines that fit, a table's + cut and the table's bottom margin above *foot* (see :func:`_block_rest`); 0 when it falls elsewhere or + nothing of those rows stays.""" + + for begin, first, last in reach.blocks: + if begin <= kept <= begin + last - first: + break + else: + return 0 + assert reach.table is not None + rows = reach.table.rows + top = reach.above + sum(piece[1] for piece in reach.rows[:begin]) + cut, heights, _ = _block_rest(reach.table, first, last, start + top, foot) + if cut == first and all(heights[index] == rows[index].height for index in range(first, last + 1)): + return 0 + return top + sum(row.height for row in rows[first:last + 1]) - sum(heights.values()) + + +def _split_joined(lines: tuple[tuple[int, int], ...], leads: tuple[int, ...], cuts: tuple[int, ...], + blocks: tuple[tuple[int, _FlowTable, int, int], ...], fitting: int, top: int, + foot: int) -> tuple[tuple[tuple[int, int], ...], tuple[int, ...], tuple[int, ...], + tuple[tuple[int, _FlowTable, int, int], ...]] | None: + """A page end before line *fitting* of a cell's *lines* (from *top* down to *foot*) falling among a table's + rows joined by merged cells (see :attr:`_Row.blocks`): each of their cells keeps the lines that fit above + the page end, a table's cut (101) and the table's bottom margin above *foot* (see :func:`_line_cuts`), the + rest going on (see :func:`_block_rest`). The lines, leads, cuts and blocks of what goes on to the next + page; ``None`` when the page end falls elsewhere or nothing of those rows stays.""" + + for start, table, first, last in blocks: + if start <= fitting <= start + last - first: + break + else: + return None + y = top + (leads[0] if leads else 0) + sum(advance for _, advance in lines[:start]) \ + + (table.above if first == 0 else 0) + cut, heights, _ = _block_rest(replace(table, cut=_SPARE_CUT + table.below), first, last, y, foot) + if cut == first and all(heights[index] == table.rows[index].height for index in range(first, last + 1)): + return None + after = start + last - first + 1 + rest = [(heights[index], heights[index]) for index in range(cut, last + 1)] + kept = [_SPARE_CUT + table.below] * len(rest) + if last == len(table.rows) - 1: # the table's last: its bottom margin, and the spacing after its paragraph + height, advance = lines[after - 1] + rest[-1] = (rest[-1][0] + table.below, rest[-1][0] + table.below + advance - height) + kept[-1] = _SPARE_CUT + return (tuple(rest) + lines[after:], + ((table.margins[0] + _repeated_header(table),) * len(rest) + leads[after:]) if leads else (), + tuple(kept) + cuts[after:], + tuple((other - after + len(rest), *block) for other, *block in blocks if other >= after)) + + +def _lines_fitting(lines: tuple[tuple[int, int], ...], leads: tuple[int, ...], top: int, foot: int, + cuts: tuple[int, ...] = ()) -> int: + """How many of *lines* ((height, advance) each; *leads*: the room above each when it starts a part; *cuts*: + the room each needs below it) fit from *top* above *foot*.""" + + fitting, y = 0, top + (leads[0] if leads else 0) + while fitting < len(lines) and y + lines[fitting][0] + (cuts[fitting] if cuts else 0) <= foot: + y += lines[fitting][1] + fitting += 1 + return fitting + + +def _lines_height(lines: tuple[tuple[int, int], ...], leads: tuple[int, ...]) -> int: + """How tall *lines* are as a part of their cell: the room above the first, then down to the last's foot.""" + + return (leads[0] if leads else 0) + sum(advance for _, advance in lines[:-1]) + lines[-1][0] diff --git a/src/hwpx/layout/pages.py b/src/hwpx/layout/pages.py index fc488bed..c7e0d520 100644 --- a/src/hwpx/layout/pages.py +++ b/src/hwpx/layout/pages.py @@ -200,58 +200,52 @@ from __future__ import annotations import copy -import math +import math # noqa: F401 import os -from collections.abc import Collection -from dataclasses import dataclass, field, replace +from collections.abc import Collection # noqa: F401 +from dataclasses import dataclass, field, replace # noqa: F401 from typing import TYPE_CHECKING, Any from lxml import etree -from ..form_fit.measure import (_DEFAULT_TAB_STOP, _GLYPH_SPACE, _TYPED_NO_BREAK_SPACE, char_advance, +from ..form_fit.measure import (_DEFAULT_TAB_STOP, _GLYPH_SPACE, _TYPED_NO_BREAK_SPACE, char_advance, # noqa: F401 font_line_height, hancom_line_starts, in_char_units, indented_widths, margins_doubled, paragraph_label, text_style_from_refs) -from ..oxml._document_primitives import _remove_stale_paragraph_layout_cache +from ..oxml._document_primitives import _remove_stale_paragraph_layout_cache # noqa: F401 from ..oxml.namespaces import HH, HP -from ..oxml.paragraph_heading import paragraph_heading -from ..oxml.section import _remove_short_paragraph_layout_cache -from ..oxml.header_part import HwpxOxmlHeader +from ..oxml.paragraph_heading import paragraph_heading # noqa: F401 +from ..oxml.section import _remove_short_paragraph_layout_cache # noqa: F401 +from ..oxml.header_part import HwpxOxmlHeader # noqa: F401 from ..oxml.section_format import COLUMN_SHARES, _drawn_page_size, _page_margin -from ..oxml.table_sizes import cell_margins_of, grid_widths_of +from ..oxml.table_sizes import cell_margins_of, grid_widths_of # noqa: F401 + +# The imports above are as they were before the split, used below or not: a name they bring stays reachable +# as hwpx.layout.pages.. +# The lower half of the model (see its description). Every name it defines is imported here, used below or +# not: hwpx.layout.pages stays the one namespace the estimate is reached through. +from ._page_measure import ( # noqa: F401 + _OBJECTS, _FLOATING, _MARKS, _SPARE_CUT, _SPARE_CUT_FIXED, _SPARE_DROPPED, _MIN_LINE_WIDTH, _MERGED_ROW_LEAST, + _NO_WRAP, _MIN_SIDE, _Unsupported, _local, _child, _char_unit_height, _Shape, _para_shape, _pitch, _object_pitch, + _on, _t_text, _indented, _line_widths, _drawn_labels, _run_text, _cache_lines, _cached_metrics, _Lookups, + _Measure, _Reach, _Row, _FlowTable, _rows, _table_rows, _cell_spacing, _table_ends, _row_span, _object_alone, + _objects_among, _table_alone, _size_protected, _cell_height, _margin, _extent_margins, _drawn_lines, _holds_table, + _pos_offset, _down, _vertical, _page_break, _split_before_text, _uncached, _cell_row, _table_first, _split_rows, + _pushed_reaches, _line_leads, _line_cuts, _line_blocks, _table_pieces, _Wrap, _Anchor, _Band, _Stacked, _Para, + _Reflow, _caption, _inline_table_height, _rows_height, _objects_reach, _floating_reach, _wraps_in_cell, + _cell_extent, _control_place, _cell_band, _BothSides, _beside_one_side, _clear_of, _placed_top_and_bottom, + _placed_from, _object_before_text, _beside_floating, _table_on_its_own, _table_before_text, _placed_objects, + _marks, _check_ruby_spacing, _mark_extent, _on_paper, _floating, _text_size, _end_size, _end_ref, _head_size, + _held_sizes, _char_styles, _line_sizes, _metric_starts, _line_metrics, _drawn_height, _SHADOW_DISTANCE, + _shadow_drop, _SHADOW_BLUR_STEP, _effect_room, _object_extent, _caption_beside, _inline_content, _shown_control, + _anchor_line, _extent, _wraps_top_and_bottom, _wrapped_widths, _at_one_height, _lines_of, _repeated_header, + _spare_cut, _starts_later, _header_moves, _flow_table, _split_block, _block_rest, _lists_lines, _cell_rest, + _flow_row, _reached, _joined_stays, _split_joined, _lines_fitting, _lines_height, +) if TYPE_CHECKING: from ..document import HwpxDocument __all__ = ["EstimatedLine", "PageEstimate", "estimate_pages"] -#: Objects in a run, placed by their ``hp:pos``. -_OBJECTS = frozenset({ - "tbl", "pic", "rect", "ellipse", "line", "arc", "polygon", "curve", "connectLine", "textart", - "container", "ole", "equation", "video", "chart", "checkBtn", "radioBtn", "btn", "button", - "comboBox", "edit", "listBox", "scrollBar", -}) -#: How an object in front of or behind the text wraps it: it takes no room from the text. -_FLOATING = frozenset({"IN_FRONT_OF_TEXT", "BEHIND_TEXT"}) -#: Run content that takes its place in the text like a character: composed characters and ruby text. -_MARKS = frozenset({"compose", "dutmal"}) -#: A flowing table's rows use the body only down to this far above its foot: a row, or a cell line of -#: a row split between its lines, ending lower goes on to the next page, and a row whose declared -#: height leaves room under its text (CELL) is cut there. What is left of such a row goes on to the -#: next page unless it is _SPARE_DROPPED or less, which is dropped (the row ends at the page's foot). -#: Both in HWPUNIT, as Hancom lays such rows out whatever the cells' margins, vertical alignment and -#: character size. A table set not to be adjusted (hp:tbl@noAdjust) uses _SPARE_CUT_FIXED instead. -_SPARE_CUT = 101 -_SPARE_CUT_FIXED = 2 -_SPARE_DROPPED = 1282 -#: The narrowest line FormFit breaks at, in HWPUNIT. -_MIN_LINE_WIDTH = 1440 -#: How tall Hancom makes a table's row that only cells merged over rows cover at least, unless the table is set -#: not to adjust its cells (``hp:tbl@noAdjust``): it starts the merged cells' heights from that. -_MERGED_ROW_LEAST = 100 -#: the room a cell that never breaks its text into lines (``hp:subList@lineWrap`` SQUEEZE or KEEP) gives a line -_NO_WRAP = 1 << 40 -#: The narrowest side of a square-wrapped object text goes to (1/5 inch): Hancom leaves a narrower one empty. -_MIN_SIDE = 1440 - @dataclass(frozen=True) class EstimatedLine: @@ -278,10 +272,6 @@ class PageEstimate: unsupported: tuple[str, ...] -class _Unsupported(Exception): - """Something the estimate does not follow.""" - - class _BandMoves(Exception): """A square-wrapped object flowing with the text, anchored in paragraph *index* without a layout cache, passed the body's foot: the section is laid out again with it at the next page's top.""" @@ -379,1725 +369,6 @@ def _open(document: Any) -> Any: return HwpxDocument.open(os.fspath(document)) -# -- the paragraph model ------------------------------------------------------------------------ - - -def _local(element: Any) -> str: - tag = element.tag - return tag.rsplit("}", 1)[-1] if isinstance(tag, str) else "" - - -def _child(element: Any, name: str) -> Any: - return next((child for child in element if _local(child) == name), None) - - -def _char_unit_height(header: Any) -> int: - """The character size of the first paragraph style (바탕글), which margins in ``unit="CHAR"`` count in.""" - - style = next((el for el in header.iter(f"{HH}style") if el.get("id") == "0"), None) - ref = style.get("charPrIDRef") if style is not None else None - shape = next((el for el in header.iter(f"{HH}charPr") if el.get("id") == ref), None) if ref is not None else None - return int(shape.get("height", 1000)) if shape is not None else 1000 - - -@dataclass(frozen=True) -class _Shape: - """What the estimate reads from a paragraph shape (``hh:paraPr``).""" - - kind: str - value: int - prev: int - next: int - left: int - right: int - indent: int - flags: dict[str, str] - font_line: bool = False # its lines as tall as the font makes them (fontLineHeight) - snap: bool = True # its lines on the section's line grid (snapToGrid) - - -def _para_shape(header: Any, para_pr_id: str, doubled: bool = False) -> _Shape: - """The paragraph shape *para_pr_id*. With *doubled* (a document an older Hancom saved, see - :func:`~hwpx.form_fit.measure.margins_doubled`), margins and a line spacing in HWPUNIT outside - ``hp:switch`` hold twice the values Hancom lays out with, as ``hp:default`` does.""" - - shape = next((el for el in header.iter(f"{HH}paraPr") if el.get("id") == para_pr_id), None) - if shape is None: - raise _Unsupported(f"paragraph shape {para_pr_id} is missing") - # The hp:case holding margin and lineSpacing: outline levels 8-10 put hh:heading in an earlier switch. - case = next((c for c in shape.iter(f"{HP}case") if _child(c, "lineSpacing") is not None), None) - holder = case if case is not None else shape - spacing = _child(holder, "lineSpacing") - margin = _child(holder, "margin") - half = 2 if doubled and case is None else 1 - - def value(name: str) -> int: - element = _child(margin, name) if margin is not None else None - if element is None: - return 0 - if element.get("unit") == "CHAR": # two-hundredths of 바탕글's character size - return in_char_units(int(element.get("value", 0)), _char_unit_height(header)) // half - return int(element.get("value", 0)) // half - - breaks = shape.find(f"{HH}breakSetting") - kind, amount = ("PERCENT", 160) - if spacing is not None: - kind, amount = spacing.get("type", "PERCENT"), int(spacing.get("value", 160)) - if kind != "PERCENT" and spacing.get("unit") == "CHAR": # as a margin in that unit - amount = in_char_units(amount, _char_unit_height(header)) - elif kind != "PERCENT": - amount //= half - return _Shape(kind, amount, value("prev"), value("next"), value("left"), value("right"), value("intent"), - dict(breaks.attrib) if breaks is not None else {}, shape.get("fontLineHeight") in ("1", "true"), - shape.get("snapToGrid", "1") not in ("0", "false")) - - -def _pitch(kind: str, value: int, size: int) -> int: - """The distance from one line's top to the next line's top in a paragraph.""" - - if kind == "FIXED": - return value - if kind == "BETWEEN_LINES": - return size + value - if kind == "AT_LEAST": - return max(size, value) - # PERCENT: the spacing over the size is counted in 1/1800 inch from the em (height // 4), rounded. - extra = (size // 4) * (value - 100) / 100 - units = int(abs(extra) + 0.5) - return size + 4 * (units if extra >= 0 else -units) - - -def _object_pitch(shape: _Shape, obj: Any, tall: int, size: int) -> int: - """The distance from the top of a line *tall* tall holding only *obj*, an object set as a character, to the - next line's top in a paragraph of *shape* whose characters are *size*: a percentage spacing is the - characters' unless the object is set to affect the line spacing (``hp:pos@affectLSpacing``), when it is the - line's, as any other spacing is -- a fixed one keeps the next line that far down even below a taller object, - an at-least one at the line's height when that is more.""" - - if shape.kind == "PERCENT" and obj.find(f"{HP}pos").get("affectLSpacing") != "1": - return tall + _pitch(shape.kind, shape.value, size) - size - return _pitch(shape.kind, shape.value, tall) - - -def _on(flags: dict[str, str], name: str) -> bool: - return flags.get(name) in ("1", "true") - - -def _t_text(text_element: Any) -> str: - """The text of one ``hp:t``, with ``hp:lineBreak`` as a newline, ``hp:tab`` as a tab, ``hp:nbSpace`` as a - no-break space (U+00A0) and ``hp:fwSpace`` as a fixed-width one (U+3000), as python-hwpx reads them; an - ideographic space typed in the text is FormFit's ``_GLYPH_SPACE``, so it is not taken for a fixed-width one, and - a no-break space typed in it ``_TYPED_NO_BREAK_SPACE``, which Hancom lays out at the font's own width. - A table-of-contents mark (``hp:titleMark``) is a character of no width (U+200D): Hancom lays its line out as - tall as the mark's run and spaces it from that size.""" - - parts = [text_element.text or ""] - for child in text_element: - name = _local(child) - parts.append({"lineBreak": "\n", "tab": "\t", "nbSpace": "\u00a0", "fwSpace": "\u3000", - "titleMark": "\u200d"}.get(name, "")) - parts.append(child.tail or "") - return "".join(part.replace("\u3000", _GLYPH_SPACE).replace("\u00a0", _TYPED_NO_BREAK_SPACE) if index % 2 == 0 - else part for index, part in enumerate(parts)) - - -def _indented(line: float, shape: _Shape, style: Any) -> list[float]: - """The first line's and the other lines' room of a paragraph of *shape* *line* wide inside its margins: less - its first-line indent (a hanging one narrows the other lines) and its bullet or number label's room - (``style.head``, see :func:`hwpx.form_fit.measure.indented_widths`). Hancom drops an indent that leaves its - line less room than its narrowest line (:data:`_MIN_LINE_WIDTH`): every line is *line* wide then. A - paragraph whose shape squeezes it (``lineWrap`` SQUEEZE) is never broken into lines: Hancom presses it onto one.""" - - if style is not None and getattr(style, "line_wrap", "BREAK") == "SQUEEZE": - return [_NO_WRAP, _NO_WRAP] - if style is not None and style.head: - return list(indented_widths(line, replace(style, indent=shape.indent))) - rooms = [line - max(shape.indent, 0), line - max(-shape.indent, 0)] - return [line, line] if min(rooms) < _MIN_LINE_WIDTH else rooms - - -def _line_widths(shape: _Shape, width: int, style: Any = None) -> list[float]: - """The first line's and the other lines' widths of a paragraph of *shape* in *width*: less its margins, - its first-line indent (a hanging one narrows the other lines) and its label's room.""" - - return [max(room, _MIN_LINE_WIDTH) for room in _indented(width - shape.left - shape.right, shape, style)] - - -def _drawn_labels(root: Any) -> dict[Any, str]: - """The label Hancom draws for each numbered, outline and bullet paragraph, counted in reading order: the body's - paragraphs, each followed by those of the tables, text boxes and captions placed in it.""" - - from ..tools.exporter import _ListLabels, _paragraph_pieces, _text_box_paragraphs - - labels = _ListLabels(root.headers[0].element if root.headers else None) - drawn: dict[Any, str] = {} - - def visit(paragraph: Any) -> None: - label = labels.label(paragraph) - if label: - drawn[paragraph] = label - for piece in _paragraph_pieces(paragraph): - if isinstance(piece, str): - continue - if piece.tag == f"{HP}tbl": - for cell in piece.findall(f"{HP}tr/{HP}tc"): - for inner in cell.findall(f"{HP}subList/{HP}p"): - visit(inner) - else: - for inner in _text_box_paragraphs(piece): - visit(inner) - - for section in root.sections: - labels.start_section(section.element) - for paragraph in section.element.findall(f"{HP}p"): - visit(paragraph) - return drawn - - -def _run_text(runs: list[Any]) -> str: - return "".join(_t_text(t) for run in runs for t in run.findall(f"{HP}t")) - - -def _cache_lines(paragraph: Any) -> int: - """How many lines the paragraph's own layout cache holds; 0 when it has none or the save path - would drop it as not matching the text.""" - - segments = paragraph.findall(f"{HP}linesegarray/{HP}lineseg") - if not segments: - return 0 - probe = copy.deepcopy(paragraph) - if _remove_stale_paragraph_layout_cache(probe) or _remove_short_paragraph_layout_cache(probe): - return 0 - return len(segments) - - -def _cached_metrics(paragraph: Any) -> tuple[tuple[int, int], ...]: - """(height, advance) of each line of the paragraph's own valid layout cache: the next line of a - paragraph starts the line's text height plus its spacing lower (``vertsize`` can be larger, for a - line an object set as a character follows). Empty without a valid cache.""" - - if not _cache_lines(paragraph): - return () - metrics = [] - segments = paragraph.findall(f"{HP}linesegarray/{HP}lineseg") - for segment, following in zip(segments, [*segments[1:], None]): - height = int(segment.get("textheight", segment.get("vertsize", 0))) - if height <= 0: # a cache of empty lines is none - return () - beside = following is not None and following.get("vertpos") == segment.get("vertpos") \ - and int(following.get("horzpos", 0)) > int(segment.get("horzpos", 0)) # two pieces of one line - metrics.append((height, 0 if beside else height + int(segment.get("spacing", 0)))) - return tuple(metrics) - - -class _Lookups: - """The shape lookups FormFit's text style reads, with the paragraph shapes and tab definitions read once: - the document reads them from the header again on every lookup. (No ``_root`` attribute, so FormFit - uses this object and not the document behind it.)""" - - def __init__(self, root: Any) -> None: - self._document = root - self.headers = root.headers - self.version = root.version # how the paragraph shapes' margins outside hp:switch read - self.sections = root.sections # the outline numbering of a paragraph's label - self._paragraph_shapes: dict[str, Any] | None = None - self._tab_definitions: dict[str, Any] | None = None - - def char_property(self, char_pr_id: Any) -> Any: - return self._document.char_property(char_pr_id) - - def paragraph_property(self, para_pr_id: Any) -> Any: - if self._paragraph_shapes is None: - self._paragraph_shapes = self._document.paragraph_properties - return HwpxOxmlHeader._lookup_by_id(self._paragraph_shapes, para_pr_id) - - def tab_property(self, tab_pr_id: Any) -> Any: - if self._tab_definitions is None: - self._tab_definitions = self._document.tab_properties - return HwpxOxmlHeader._lookup_by_id(self._tab_definitions, tab_pr_id) - - -class _Measure: - """Shapes and line breaking of one document.""" - - def __init__(self, root: Any) -> None: - self._root = root - self._lookups = _Lookups(root) - self._header = root.headers[0].element - self._doubled = margins_doubled(root) - self._shapes: dict[str, _Shape] = {} - self._styles: dict[tuple[str, tuple[str, ...], str | None], Any] = {} - self._drawn: dict[Any, str] | None = None - self._numbered: dict[str, bool] = {} - self._label_sizes: dict[str, int] = {} - self._pictured: dict[str, bool] = {} - self._boxes: dict[str, int] = {} - self._edges: dict[str, int] | None = None - #: how far apart the default tab stops of the section at hand are (see :func:`_tab_stop`) - self.tab_stop = _DEFAULT_TAB_STOP - - def shape(self, para_pr_id: Any) -> _Shape: - key = str(para_pr_id) - if key not in self._shapes: - self._shapes[key] = _para_shape(self._header, key, self._doubled) - return self._shapes[key] - - def char_height(self, char_pr_id: Any) -> int: - style = self._root.char_property(char_pr_id) - return int(style.attributes.get("height", 1000)) if style is not None else 1000 - - def char_box(self, char_pr_id: Any) -> int: - """How tall a character of *char_pr_id* makes its line: its height, and the width of a border its shape - draws above and below it (Hancom: the line that much taller, spaced from that height).""" - - if self._edges is None: # each border fill's width above and below, read once from the header - self._edges = {} - for fill in self._header.iter(f"{HH}borderFill"): - self._edges[fill.get("id")] = sum( - round(float(rule.get("width", "0 mm").split()[0]) * 7200 / 25.4) - for rule in (fill.find(f"{HH}topBorder"), fill.find(f"{HH}bottomBorder")) - if rule is not None and rule.get("type", "NONE") != "NONE") - key = str(char_pr_id) - if key not in self._boxes: - style = self._root.char_property(char_pr_id) - fill = style.attributes.get("borderFillIDRef") if style is not None else None - self._boxes[key] = self.char_height(char_pr_id) + self._edges.get(fill, 0) - return self._boxes[key] - - def font_line(self, size: int, style: Any) -> int: - """How tall a line of characters *size* tall in *style* is in a paragraph taking its line height from - the font (see :func:`~hwpx.form_fit.measure.font_line_height`); *size* for a face the glyph table does - not list.""" - - tall = font_line_height(getattr(style, "hangul_face", None), size) - return size if tall is None else tall - - def headed(self, paragraph: Any) -> bool: - """Whether Hancom heads *paragraph* with a bullet or number label.""" - - if self._drawn is None: - self._drawn = _drawn_labels(self._root) - return bool(self._drawn.get(paragraph)) - - def style(self, para_pr_id: Any, char_pr_ids: list[Any], paragraph: Any = None) -> Any: - """FormFit's text style of a paragraph shape and its characters; with *paragraph*, a number's label - takes the room of the label Hancom draws for that paragraph, and a label without a character shape of - its own that of the paragraph's end.""" - - drawn = None - if paragraph is not None and self.numbered(para_pr_id): - if self._drawn is None: - self._drawn = _drawn_labels(self._root) - drawn = self._drawn.get(paragraph) - end = _end_ref(paragraph) if paragraph is not None else None - key = (str(para_pr_id), tuple(str(ref) for ref in char_pr_ids), drawn, end, self.tab_stop) - if key not in self._styles: - style = text_style_from_refs(self._lookups, para_pr_id, char_pr_ids, drawn, end) - if style is not None and style.tab_stop != self.tab_stop: - style = replace(style, tab_stop=self.tab_stop) - self._styles[key] = style - return self._styles[key] - - def label_size(self, para_pr_id: Any, end: Any = None) -> int: - """The character size of a paragraph shape's bullet or number label: in its own character shape - (``hh:paraHead@charPrIDRef``), or without one in that of the paragraph's end (*end*); 0 when it has - none, or no shape of its own and no *end*.""" - - key = str(para_pr_id) - if key not in self._label_sizes: - label = paragraph_label(self._root, para_pr_id) - ref = label[1].get("charPrIDRef") if label is not None else None - own = ref is not None and ref != "4294967295" and self._root.char_property(ref) is not None - self._label_sizes[key] = self.char_height(ref) if own else -1 if label is not None else 0 - size = self._label_sizes[key] - return size if size >= 0 else self.char_height(end) if end is not None else 0 - - def copied(self, copies: dict[Any, Any]) -> None: - """Give each copied paragraph in *copies* (copy -> original) the label Hancom draws for its original.""" - - if self._drawn is None: - self._drawn = _drawn_labels(self._root) - self._drawn.update({copy: self._drawn[original] for copy, original in copies.items() - if original in self._drawn}) - - def pictured(self, para_pr_id: Any) -> bool: - """Whether a paragraph shape heads its paragraphs with a picture bullet sized by its picture - (``hh:paraHead@useInstWidth``), whose room was not measured: FormFit gives it none.""" - - key = str(para_pr_id) - if key not in self._pictured: - shape = next((el for el in self._header.iter(f"{HH}paraPr") if el.get("id") == key), None) - heading = paragraph_heading(shape) if shape is not None else None - bullet = next((el for el in self._header.iter(f"{HH}bullet") if el.get("id") == heading.get("idRef")), - None) if heading is not None and heading.get("type") == "BULLET" else None - head = bullet.find(f"{HH}paraHead") if bullet is not None else None - self._pictured[key] = bullet is not None and bullet.get("useImage") in {"1", "true"} \ - and head is not None and head.get("useInstWidth") in {"1", "true"} - return self._pictured[key] - - def numbered(self, para_pr_id: Any) -> bool: - """Whether a paragraph shape heads its paragraphs with a number (``NUMBER`` or ``OUTLINE``).""" - - key = str(para_pr_id) - if key not in self._numbered: - shape = next((el for el in self._header.iter(f"{HH}paraPr") if el.get("id") == key), None) - heading = paragraph_heading(shape) if shape is not None else None - self._numbered[key] = heading is not None and heading.get("type") in {"NUMBER", "OUTLINE"} - return self._numbered[key] - - def lines(self, text: str, widths: list[float], size: int, style: Any) -> int: - """How many lines FormFit breaks *text* into (a newline starts a line).""" - - if not text: - return 1 - return sum(len(hancom_line_starts(line, widths if not index else widths[1:] or widths, size / 100, style, - continued=bool(index))) if line else 1 - for index, line in enumerate(text.split("\n"))) # the lines after a line break are no first line - - def line_starts(self, text: str, widths: list[float], size: int, style: Any, - sizes: list[int] | None = None, styles: list[Any] | None = None, - advances: dict[int, int] | None = None, objects: Collection[int] = ()) -> list[int]: - """Where each line starts, as offsets into *text*; *sizes* and *styles* are each character's size - and style when the text mixes them, *advances* the width of each object set as a character (or - mark), *objects* the places of the objects.""" - - starts: list[int] = [] - base = 0 - for number, line in enumerate(text.split("\n")): - points = None if sizes is None else [height / 100 for height in sizes[base:base + len(line)]] - looks = None if styles is None else styles[base:base + len(line)] - fixed = None if advances is None else { - index - base: width for index, width in advances.items() if base <= index < base + len(line)} - placed = {index - base for index in objects if base <= index < base + len(line)} - room = widths if not number else widths[1:] or widths # the lines after a line break are no first line - starts += [base + start for start in (hancom_line_starts(line, room, size / 100, style, points, looks, - fixed, placed, continued=bool(number)) - if line else [0])] - base += len(line) + 1 - return starts - - def stack(self, paragraphs: list[Any], width: int, caches: bool, - floating: bool = False, lead: int = 0) -> tuple[int, int, int, int]: - """(height, lines, pitch, size) of *paragraphs* laid out one under another at *width*; pitch - and size are the last paragraph's. With *caches* a paragraph keeps the lines of its cache. With - *floating* (a cell's paragraphs) the height reaches down to the foot of any object in front of or - behind the text placed from a paragraph's top (see :func:`_floating_reach`). *lead* is room above - the first paragraph's lines (a cell's first paragraph's spacing before): Hancom places an object - from that paragraph's top above it.""" - - height, lines, pitch, size, pending, far = lead, 0, 0, 0, None, 0 - for paragraph in paragraphs: - runs = paragraph.findall(f"{HP}run") - size, refs, _ = _text_size(self, runs, paragraph) # an empty run takes no room, as in the body - shape = self.shape(paragraph.get("paraPrIDRef")) - pitch = _pitch(shape.kind, shape.value, size) - table = _table_alone(runs) - alone = None if table is not None or caches and _cached_metrics(paragraph) else _object_alone(runs) - spread = self.spread_lines(paragraph, runs, width, caches=caches) \ - if table is not None or alone is not None else () - if spread: # spaces besides it, some of which go on to the next line - table = alone = None - if table is not None: # one line as tall as the table, spaced like the text - tall = _inline_table_height(self, table) + _extent_margins(table) + sum(_caption(self, table)) - count, size, pitch = 1, tall, _object_pitch(shape, table, tall, size) - elif alone is not None: # so with another object set as a character - tall = _object_extent(alone, self)[1] - count, size, pitch = 1, tall, _object_pitch(shape, alone, tall, size) - else: - cached = spread or (_cached_metrics(paragraph) if caches else ()) - cached = cached or self.pushed_lines(paragraph, runs, width) \ - or self.marked_lines(paragraph, runs, width) or self.mixed_lines(paragraph, runs, shape, width) - if cached: # the lines Hancom laid out, each as tall as it drew it - anchor = height - lead if pending is None else height + pending + shape.prev - above = lead if pending is None else shape.prev # its spacing before, above its line - if pending is not None: - height += pending + shape.prev - top = height - far = max(far, anchor + _floating_reach(runs, self)) if floating else far - height += sum(advance for _, advance in cached[:-1]) + cached[-1][0] - size, pitch = cached[-1] - pending = pitch - size + shape.next - if top + _objects_reach(runs, self, above) > height: # an object placed from it reaches lower - height, pending = top + _objects_reach(runs, self, above), shape.next - lines += len(cached) - continue - style = self.style(paragraph.get("paraPrIDRef"), refs, paragraph) - count = (_cache_lines(paragraph) if caches else 0) or self.lines( - _run_text(runs), _line_widths(shape, width, style), size, style - ) - # an empty line keeps the character size: Hancom makes only a line of characters as tall as - # its font makes it - anchor = height - lead if pending is None else height + pending + shape.prev - above = lead if pending is None else shape.prev # its spacing before, above its line - if pending is not None: - height += pending + shape.prev - top = height - far = max(far, anchor + _floating_reach(runs, self)) if floating else far - height += (count - 1) * pitch + size - pending = pitch - size + shape.next - if top + _objects_reach(runs, self, above) > height: # an object placed from the paragraph reaches lower - height, pending = top + _objects_reach(runs, self, above), shape.next - lines += count - return max(height, far), lines, pitch, size - - def mixed_lines(self, paragraph: Any, runs: list[Any], shape: _Shape, width: int) -> tuple[tuple[int, int], ...]: - """(height, advance) of each line of a paragraph whose characters differ in size or style, or that takes - its line height from the font, laid out at *width* as in the body; empty for any other paragraph.""" - - _, refs, sizes = _text_size(self, runs) - looks = _char_styles(self, paragraph, runs) - end = _end_size(self, runs, sizes) - head = _head_size(self, paragraph, sizes) - held = _held_sizes(self, runs, sizes) - if len(set(sizes)) < 2 and looks is None and not end and not head and not held and not (shape.font_line and sizes): - return () - style = self.style(paragraph.get("paraPrIDRef"), refs, paragraph) - return _line_metrics(self, _run_text(runs), _line_widths(shape, width, style), sizes, style, shape, {}, looks, - end=end, head=head, held=held) - - def stack_lines(self, paragraphs: list[Any], width: int, caches: bool, - pieces: bool = False) -> tuple[tuple[int, int], ...]: - """(height, advance to the next line's top) of every line of *paragraphs* laid out as in - :meth:`stack`, a table set as a character alone in its paragraph as one line; with *pieces*, a table - that splits on its own in a paragraph as its pieces (see :func:`_table_pieces`).""" - - metrics: list[tuple[int, int]] = [] - for paragraph in paragraphs: - shape = self.shape(paragraph.get("paraPrIDRef")) - if metrics: # the gap between the paragraphs - last_height, last_advance = metrics[-1] - metrics[-1] = (last_height, last_advance + shape.prev) - runs = paragraph.findall(f"{HP}run") - split = _table_pieces(self, paragraph) if pieces else None - if split is not None: # a table placed top and bottom on its own: its rows (or their lines) - lines = split[0] - metrics += list(lines[:-1]) + [(lines[-1][0], lines[-1][1] + shape.next)] - continue - cached = () if _table_alone(runs) is not None or not caches else _cached_metrics(paragraph) - cached = cached or self.spread_lines(paragraph, runs, width, caches=caches) - if not cached and _table_alone(runs) is None: # each line as tall as stack makes it - cached = self.pushed_lines(paragraph, runs, width) or self.marked_lines(paragraph, runs, width) \ - or self.mixed_lines(paragraph, runs, shape, width) - if cached: - metrics += list(cached[:-1]) + [(cached[-1][0], cached[-1][1] + shape.next)] - continue - height, count, pitch, size = self.stack([paragraph], width, caches) - last = height - (count - 1) * pitch # down to the foot of an object placed from it: the next below - metrics += [(size, pitch)] * (count - 1) + [(last, (last if last > size else pitch) + shape.next)] - return tuple(metrics) - - def spread_lines(self, paragraph: Any, runs: list[Any], width: int, end: int = 0, head: int = 0, - caches: bool = False) -> tuple[tuple[int, int], ...]: - """(height, advance) of each line of a paragraph holding one object set as a character and, besides it, - only spaces or line breaks, when Hancom lays it out on several lines: a space before the object is text - (the object goes on to the next line when it does not fit after it), the two spaces right after it hang - past the margin and a further one starting there begins the next line, and a line break begins one (an - empty line before the object goes down as a line of text); empty for any other paragraph, or one of a - line. With *caches* a paragraph with a valid layout cache keeps Hancom's lines.""" - - objects = _placed_objects(runs) - text = _run_text(runs) - if len(objects) != 1 or not text or text.strip() or objects[0].find(f"{HP}pos").get("treatAsChar") != "1": - return () - own = _cached_metrics(paragraph) if caches else () - if own: - return own if len(own) > 1 else () - shape = self.shape(paragraph.get("paraPrIDRef")) - if shape.kind not in ("PERCENT", "FIXED"): - return () - inline, sizes, looks, placed, marked = _inline_content(self, paragraph, runs) - style = self.style(paragraph.get("paraPrIDRef"), [run.get("charPrIDRef") for run in runs] or ["0"], paragraph) - lines = _line_metrics(self, inline, _line_widths(shape, width, style), sizes, style, shape, placed, - looks if len(set(looks)) > 1 else None, marked, end, head) - return lines if len(lines) > 1 else () - - def pushed_lines(self, paragraph: Any, runs: list[Any], width: int) -> tuple[tuple[int, int], ...]: - """(height, advance) of each line of a cell paragraph without a layout cache whose text follows a table - placed top and bottom from its top: the first line reaching the table (with a caption above or below - it) and the lines after it go below it, and the paragraph reaches down to the table's foot at least; - empty for any other paragraph.""" - - obj = _object_before_text(runs, self.headed(paragraph)) - if obj is None or _local(obj) != "tbl" and obj.find(f"{HP}pos").get("flowWithText") == "0": - return () # a picture or drawing that stays put pushes no line aside in a cell - top = _down(obj.find(f"{HP}pos")) - foot = top + (_cell_extent(self, obj) if _local(obj) == "tbl" else _extent(obj, "height", self)) - shape = self.shape(paragraph.get("paraPrIDRef")) - lines = list(self.marked_lines(paragraph, runs, width) or self.mixed_lines(paragraph, runs, shape, width)) - if not lines: - size, refs, _ = _text_size(self, runs, paragraph) - style = self.style(paragraph.get("paraPrIDRef"), refs, paragraph) - count = max(1, self.lines(_run_text(runs), _line_widths(shape, width, style), size, style)) - lines = [(size, _pitch(shape.kind, shape.value, size))] * count # an empty line keeps its size - y = 0 - for index, (height, advance) in enumerate(lines): - if y < foot and y + height > top: # it reaches the table: below it, and the lines after it; it takes - lines[index] = (height + foot - y, advance + foot - y) # the room above it (and goes on to a next - break # page with the table) - y += advance - above = sum(advance for _, advance in lines[:-1]) - if above + lines[-1][0] < foot: # every line above the table: the paragraph holds it - lines[-1] = (foot - above, foot - above) - return tuple(lines) - - def wrapped_lines(self, paragraphs: list[Any], width: int, tables: bool = False - ) -> tuple[tuple[tuple[int, int], ...], tuple[int, ...], tuple[_Reach, ...]]: - """(height, advance) of every line of a cell's *paragraphs*, and the room above each when a part of the - cell starts with it (a paragraph's spacing before at its first line), when one of them holds a picture - or drawing placed top and bottom or square from its top that moves with the text (see - :func:`_wraps_in_cell`; with *tables*, a table so placed, or in front of or behind the text, too); - empty for any other cell. Hancom stands such an object its offset below the - top of the line its control falls on (the paragraph laid out the cell's whole width), or of the - paragraph, above its spacing before, when that is the first line (an offset up counts as none), and - lays every line from there on, of that paragraph and the next ones, clear of it (see :func:`_clear_of`). - The cell reaches down to the lowest object's foot, and to that of any object in front of or behind - the text placed from a paragraph's top (see :func:`_floating_reach`; such a table stands from the top - of the line its control falls on, as an object wrapped does, and pushes no line aside). A paragraph - with a valid layout cache keeps its lines. With *tables*, also where each object stands among the lines - (see :class:`_Reach`).""" - - owned = [[obj for run in paragraph.findall(f"{HP}run") for obj in run if _wraps_in_cell(obj, tables)] - for paragraph in paragraphs] - floats = [[obj for run in paragraph.findall(f"{HP}run") for obj in run - if tables and _local(obj) == "tbl" and _floating(obj)] for paragraph in paragraphs] - if not any(owned) and not any(floats) or any(len(objects) + len(over) > 1 - for objects, over in zip(owned, floats)): - return (), (), () # several in a paragraph: Hancom stacks them, which is not followed here (they - # count as before) - for table in (obj for over in floats for obj in over): - pos = table.find(f"{HP}pos") - if pos.get("flowWithText") == "0" or pos.get("vertRelTo") != "PARA" or pos.get("vertAlign", "TOP") != "TOP": - raise _Unsupported("a table in front of or behind the text in a cell placed otherwise than from " - "its paragraph's top, moving with the text") - bands: list[tuple[int, int, int | None]] = [] # top, foot and room beside it (None: the lines go below) - tops: list[int] = [] - heights: list[int] = [] - leads: list[int] = [] - reaches: list[_Reach] = [] - after = 0 # where the next paragraph's first line stands, above its spacing before - far = 0 # the foot of the lowest object in front of or behind the text - for paragraph, objects, over in zip(paragraphs, owned, floats): - obj = objects[0] if objects else None - shape = self.shape(paragraph.get("paraPrIDRef")) - runs = paragraph.findall(f"{HP}run") - text = _run_text(runs) - empty = not text and not self.headed(paragraph) # a label is text - if obj is not None and _local(obj) == "tbl" and empty and obj.find(f"{HP}pos").get("allowOverlap") != "0": - raise _Unsupported("a table that may overlap the text placed top and bottom or square in an empty " - "cell paragraph") - top = after + shape.prev if tops else 0 - far = max(far, top + _floating_reach(runs, self)) - place = 0 if obj is None and not over else _control_place(runs, obj if obj is not None else over[0]) - fixed = list(_cached_metrics(paragraph)) # Hancom keeps the lines of a valid cache - simple = not fixed and _table_alone(runs) is None and not self.spread_lines(paragraph, runs, width) \ - and not self.marked_lines(paragraph, runs, width) \ - and not self.mixed_lines(paragraph, runs, shape, width) - anchor = 0 - mixed: tuple[tuple[int, int], ...] = () - if not fixed and not simple: - if obj is not None and obj.get("textWrap") == "TOP_AND_BOTTOM": - mixed = self.mixed_lines(paragraph, runs, shape, width) - if obj is not None and not mixed: - raise _Unsupported("an object placed top and bottom or square beside text laid out otherwise " - "in a cell") - # one placed top and bottom narrows no line: the lines of characters differing in size or style - # stand as they are, those up to the one its control falls on above it and the rest below - fixed = list(mixed) if mixed else list(self.stack_lines([paragraph], width, caches=True)) - if mixed and place: - size, refs, sizes = _text_size(self, runs, paragraph) - style = self.style(paragraph.get("paraPrIDRef"), refs, paragraph) - starts = self.line_starts(text, _line_widths(shape, width, style), size, style, sizes, - _char_styles(self, paragraph, runs)) - if len(starts) != len(fixed): - raise _Unsupported("an object placed top and bottom among text laid out otherwise in a cell") - anchor = sum(1 for start in starts[1:] if start < place) - if mixed: - fixed[-1] = (fixed[-1][0], fixed[-1][1] + shape.next) - elif fixed: - fixed[-1] = (fixed[-1][0], fixed[-1][1] + shape.next) - if fixed: - if place and not mixed: - raise _Unsupported("an object placed top and bottom or square after the text of a paragraph " - "with a layout cache in a cell") - lines, narrow, own = _clear_of(self, fixed, top, shape.prev, anchor, obj, bands, empty, width) - _beside_one_side(narrow, empty) - if narrow and not _cache_lines(paragraph): - raise _Unsupported("text laid out otherwise beside a square-wrapped object in a cell") - else: - size, refs, _ = _text_size(self, runs, paragraph) - style = self.style(paragraph.get("paraPrIDRef"), refs, paragraph) - pitch = _pitch(shape.kind, shape.value, size) # an empty line keeps the character size - full = _line_widths(shape, width, style) - starts = self.line_starts(text, full, size, style) if text else [0] - anchor = sum(1 for start in starts[1:] if start < place) - narrow = {} - for _ in range(10): # FormFit breaks the lines, and which are beside an object follows from them - rooms = [(_line_widths(shape, narrow[index], style) if index in narrow else full)[min(index, 1)] - for index in range(max(narrow, default=0) + 2)] - count = len(self.line_starts(text, rooms, size, style)) if text else 1 - metrics = [(size, pitch)] * (count - 1) + [(size, pitch + shape.next)] - lines, found, own = _clear_of(self, metrics, top, shape.prev, anchor, obj, bands, empty, width) - if found == narrow: - break - narrow = found - else: - raise _Unsupported("lines beside a square-wrapped object in a cell that do not settle") - _beside_one_side(narrow, empty) - if narrow and ("\n" in text or style.head): - raise _Unsupported("a paragraph with margins, a label or line breaks beside a square-wrapped " - "object in a cell") - if obj is not None and own is None: - raise _Unsupported("an object placed top and bottom or square past its paragraph's lines in a cell") - if own is not None: - bands.append(own) - anchor = min(anchor, len(lines) - 1) - line = top if anchor == 0 else lines[anchor - 1][0] + lines[anchor - 1][2] # where it would stand - if own is not None and tables: - if own[2] is None: # it pushes the lines below it: the first of them, where it would stand - pushed = next(((index, top if index == 0 else lines[index - 1][0] + lines[index - 1][2]) - for index in range(anchor, len(lines)) - if lines[index][0] > (top if index == 0 else lines[index - 1][0] + lines[index - 1][2])), - None) - reaches.append(_Reach(line, own[0], own[1], _table_first(self, obj), - None if pushed is None else pushed[1], - 0 if pushed is None else lines[pushed[0]][1], *_split_rows(self, obj))) - else: - reaches.append(_Reach(line, own[0], own[1])) - for table in over: # from the top of the line its control falls on, where that line would follow the - # one before (of the paragraph, above its spacing before, on its first line) - up = (top - shape.prev if anchor == 0 else line) + _down(table.find(f"{HP}pos")) - far = max(far, up + _cell_extent(self, table)) - reaches.append(_Reach(line, up, up + _cell_extent(self, table))) - for index, (line_top, height, advance) in enumerate(lines): - if index == 0 and line_top > top: # below an object: the line takes the room above it - height, line_top = height + line_top - top, top - elif index and tables and line_top > lines[index - 1][0] + lines[index - 1][2]: # so a later - # line (a table goes on over a page end with it) - follow = lines[index - 1][0] + lines[index - 1][2] - height, line_top = height + line_top - follow, follow - tops.append(line_top) - heights.append(height) - leads.append(shape.prev if index == 0 else 0) - after = lines[-1][0] + lines[-1][2] - heights[-1] = max(heights[-1], max((foot for _, foot, _ in bands), default=0) - tops[-1], far - tops[-1]) - if any(later < earlier for earlier, later in zip(tops, tops[1:])): - raise _Unsupported("lines in a cell placed up past an object placed top and bottom or square") - return tuple((height, (nxt - line_top) if nxt is not None else height) - for height, line_top, nxt in zip(heights, tops, [*tops[1:], None])), tuple(leads), tuple(reaches) - - def marked_lines(self, paragraph: Any, runs: list[Any], width: int) -> tuple[tuple[int, int], ...]: - """(height, advance) of each line of a paragraph holding composed characters, ruby text, or objects - set as characters among its text or several of them, laid out at *width* as in the body; empty for - a paragraph holding none of them.""" - - if not _marks(runs) and not _objects_among(runs): - return () - shape = self.shape(paragraph.get("paraPrIDRef")) - _check_ruby_spacing(runs, shape) - text, sizes, looks, placed, marked = _inline_content(self, paragraph, runs) - style = self.style(paragraph.get("paraPrIDRef"), [run.get("charPrIDRef") for run in runs] or ["0"], paragraph) - end = _end_size(self, runs, _text_size(self, runs)[2]) # an empty run ending it, as in the body - return _line_metrics(self, text, _line_widths(shape, width, style), sizes, style, shape, placed, - looks if len(set(looks)) > 1 else None, marked, end) - - -@dataclass(frozen=True) -class _Reach: - """Where an object placed from a cell paragraph stands among the cell's lines, from the top of its first line: - where the line its control falls on would stand (``line``), the object's top and foot, and, for a table - pushing the lines below it, how far below its top its first row ends (``first``; 0 for anything else), where - the first line it pushes below it would stand (``unit``; ``line`` when it pushes that very line) and how - tall that line is (``text``), and, for one that may split between its rows, the room above its first row, - the pieces it splits into and the room below its last row (``above``, ``rows``, ``below``; see - :func:`_split_rows`), with the table and its rows joined by merged cells, one piece each (where the - first's piece stands among the pieces, its first and last row), which a page end splits cell by cell.""" - - line: int - top: int - foot: int - first: int = 0 - unit: int | None = None - text: int = 0 - above: int = 0 - rows: tuple[tuple[int, int, int, int], ...] = () - below: int = 0 - table: _FlowTable | None = None - blocks: tuple[tuple[int, int, int], ...] = () - - -@dataclass(frozen=True) -class _Row: - height: int # the row's full height - lines: int # lines of its tallest cell, for splitting between them - pitch: int - size: int - margins: int # top + bottom cell margins - header: bool - merged: bool = False # under a cell merged over rows: no page break in or around it - joined: bool = False # a cell merged over rows joins it to the next row - spare: int = 0 # room the row's declared height leaves under its text - nested: bool = False # a cell holds a table - #: (height, advance) of each line of the row's tallest cell when it holds a table or several paragraphs - metrics: tuple[tuple[int, int], ...] = () - first: int = 0 # the tallest first line of any of its cells - #: the room above each of those lines when a part of the cell starts with it (a paragraph's spacing - #: before its first line, none before the others) - leads: tuple[int, ...] = () - #: its tables are placed top and bottom on their own and split (see :func:`_table_pieces`): its lines - #: (those tables' pieces among them) split as any cell's - pieces: bool = False - #: the room each of those lines needs below it to stay above a page end: a table's piece a table's cut - #: (101) more than a line of text - cuts: tuple[int, ...] = () - #: rows of those tables joined by merged cells, one piece each: (where the first's piece stands among the - #: lines, the table, its first and last row); a page end among them splits them cell by cell - blocks: tuple[tuple[int, _FlowTable, int, int], ...] = () - #: the tables among its tallest cell's text placed top and bottom, square, or in front of or behind it - #: (laid out by :meth:`_Measure.wrapped_lines`): a page end is not followed through them - reaches: tuple[_Reach, ...] = () - - -@dataclass(frozen=True) -class _FlowTable: - rows: list[_Row] - mode: str # hp:tbl@pageBreak: CELL, TABLE or NONE - repeat_header: bool - margins: tuple[int, int] # hp:outMargin top, bottom: kept above and below the table - #: every cell as (the position of its first row in ``rows``, rows it spans, the cell as a row) - cells: tuple[tuple[int, int, _Row], ...] = () - offset: int = 0 # alone in its paragraph: how far below the paragraph's line it starts - caption: tuple[int, int] = (0, 0) # a caption above it, below it: its lines and its gap - cut: int = _SPARE_CUT # how far above the body's foot its rows end at most - - @property - def above(self) -> int: - """Room above the first row: the top margin and a caption above.""" - - return self.margins[0] + self.caption[0] - - @property - def below(self) -> int: - """Room below the last row: a caption below and the bottom margin.""" - - return self.margins[1] + self.caption[1] - - -def _rows(measure: _Measure, table: Any) -> list[_Row]: - """Each row as its tallest cell of one row: the cell's declared height or its content with its - margins (a row with no cell of its own starts at 0). Then each cell merged over rows, the one - ending first first, adds what its rows lack to the last of them.""" - - return _table_rows(measure, table)[0] - - -def _table_rows(measure: _Measure, table: Any) -> tuple[list[_Row], list[tuple[int, int, _Row]]]: - """The rows (see :func:`_rows`) and every cell as (its first row's position, rows spanned, the cell - as a row). A table's cell spacing (``hp:tbl@cellSpacing``) stands above each row: every cell is that much - taller (a cell merged over rows spans the spacings between them), and the spacing below the last row is - the table's (see :func:`_table_ends`).""" - - if any(int(cols.get("colCount", "1")) > 1 for cols in table.iter(f"{HP}colPr")): - raise _Unsupported("columns in a table cell") # Hancom lays the cell's text out in them - rows: dict[int, _Row] = {} - merged: list[tuple[int, int, _Row]] = [] # (first row, rows spanned, the cell as a row) - cells: list[tuple[int, int, _Row]] = [] - nested: set[int] = set() # rows with a cell holding a table - headers: set[int] = set() # rows with a header cell of their own - reached: set[int] = set() # rows with a table among a cell's text (see _Reach) - firsts: dict[int, int] = {} # each row's tallest first line of a cell of its own - tallest: dict[int, int] = {} # each row's tallest cell of its own, and the most any fills with its text - filled: dict[int, int] = {} - widths = grid_widths_of(table) - spacing = _cell_spacing(table) - for tc in (tc for tr in table.findall(f"{HP}tr") for tc in tr.findall(f"{HP}tc")): - row, span = _cell_row(measure, table, tc, widths.get(tc)), _row_span(tc) - if spacing: # the cell spacing above it, kept with its lines when it goes on over a page end - row = replace(row, height=row.height + spacing, margins=row.margins + spacing) - address = tc.find(f"{HP}cellAddr") - first = int(address.get("rowAddr", 0)) if address is not None else len(rows) - cells.append((first, span, row)) - if row.nested: - nested.update(range(first, first + span)) - if row.header and span == 1: - headers.add(first) - if span == 1: - firsts[first] = max(firsts.get(first, 0), row.first) - tallest[first] = max(tallest.get(first, 0), row.height) - filled[first] = max(filled.get(first, 0), row.height - row.spare) - if span > 1 and row.reaches: - raise _Unsupported("a table among the text of a cell merged over rows") - if row.reaches: - reached.add(first) - if span > 1: - merged.append((first, span, row)) - elif first not in rows or (row.height - row.spare, row.height, row.lines) > (rows[first].height - rows[first].spare, rows[first].height, rows[first].lines): - rows[first] = row # the cell its text fills most: its lines split the row over a page end - for first in reached: # one among the text of a cell that is not the tallest: no page end followed - if not rows[first].reaches: - rows[first] = replace(rows[first], reaches=(_Reach(-1, 0, 1 << 62),)) - for first in headers: # a header row whatever cell is the tallest - rows[first] = replace(rows[first], header=True) - for first, line in firsts.items(): - rows[first] = replace(rows[first], first=line) - for first, height in tallest.items(): # as tall as its tallest cell, with room to spare under the text - rows[first] = replace(rows[first], height=height, spare=height - filled[first]) # filling one most - least = 0 if _on(dict(table.attrib), "noAdjust") else _MERGED_ROW_LEAST - for first, span, cell in merged: - for index in range(first, first + span): - if index not in rows: # every cell over it is merged over rows - rows[index] = replace(cell, height=least, lines=1, margins=0, spare=0) - for first, span, cell in sorted(merged, key=lambda cell: (cell[0] + cell[1], cell[0])): - spanned = range(first, first + span) - for index in spanned: - rows[index] = replace(rows[index], merged=True, joined=rows[index].joined or index < first + span - 1) - last = rows[first + span - 1] - lacking = cell.height - sum(rows[index].height for index in spanned) - rows[first + span - 1] = replace(last, height=last.height + max(lacking, 0)) - order = sorted(rows) # a row address no cell covers is skipped - place = {address: position for position, address in enumerate(order)} - return ([replace(rows[address], nested=address in nested) for address in order], - [(place[first], span, cell) for first, span, cell in cells]) - - -def _cell_spacing(table: Any) -> int: - """The room Hancom keeps between a table's cells and around them (``hp:tbl@cellSpacing``).""" - - spacing = int(table.get("cellSpacing", 0) or 0) - return spacing if 0 < spacing < 1 << 31 else 0 - - -def _table_ends(table: Any) -> tuple[int, int]: - """The room a table that flows with the text keeps above its rows and below them on each page it goes on: - its outer margins (``hp:outMargin`` top and bottom), and below the rows its cell spacing too.""" - - margin = table.find(f"{HP}outMargin") - top, bottom = (0, 0) if margin is None else (_margin(margin, "top"), _margin(margin, "bottom")) - return top, bottom + _cell_spacing(table) - - -def _row_span(cell: Any) -> int: - span = cell.find(f"{HP}cellSpan") - return 1 if span is None else int(span.get("rowSpan", 1)) - - -def _object_alone(runs: list[Any]) -> Any: - """The object set as a character, not a table, that is all a paragraph holds (but objects in front of or - behind the text), or ``None``.""" - - objects = _placed_objects(runs) - if len(objects) != 1 or _local(objects[0]) == "tbl" or _run_text(runs).strip(): - return None - return objects[0] if objects[0].find(f"{HP}pos").get("treatAsChar") == "1" else None - - -def _objects_among(runs: list[Any]) -> bool: - """Whether the runs hold objects set as characters, and nothing else placed, among text or several.""" - - objects = _placed_objects(runs) - return bool(objects) and (len(objects) > 1 or bool(_run_text(runs).strip())) and all( - obj.find(f"{HP}pos").get("treatAsChar") == "1" for obj in objects) - - -def _table_alone(runs: list[Any]) -> Any: - """The table set as a character that is all a paragraph holds (but objects in front of or behind the text, - which take no room), or ``None``.""" - - children = [child for run in runs for child in run if _local(child) not in ("t", "secPr", "ctrl") - and not (_local(child) in _OBJECTS and _floating(child))] - if len(children) != 1 or _local(children[0]) != "tbl" or _run_text(runs).strip(): - return None - pos = children[0].find(f"{HP}pos") - return children[0] if pos is not None and pos.get("treatAsChar") == "1" else None - - -def _size_protected(table: Any) -> bool: - """Whether *table* is set not to change size (``hp:sz@protect``): Hancom keeps its rows as declared, however - tall their text.""" - - size = table.find(f"{HP}sz") - return size is not None and size.get("protect") == "1" - - -def _cell_height(size: Any) -> int: - """A cell's stored height (hp:cellSz): a negative one, which the file keeps as an unsigned 32-bit number, - counts as none -- Hancom gives that cell its top and bottom margins and grows it to fit its text.""" - - height = int(size.get("height", 0)) if size is not None else 0 - return 0 if height >= 1 << 31 else height - - -def _margin(margin: Any, side: str) -> int: - """One side of an object's outer margins (hp:outMargin): a negative one, which the file keeps as an - unsigned 32-bit number, counts as none, as Hancom lays it out (and saves it).""" - - value = int(margin.get(side, 0)) - return 0 if value < 0 or value >= 1 << 31 else value - - -def _extent_margins(obj: Any) -> int: - margin = obj.find(f"{HP}outMargin") - return 0 if margin is None else _margin(margin, "top") + _margin(margin, "bottom") - - -def _drawn_lines(measure: _Measure, paragraphs: list[Any], width: int | None = None, cell: int | None = None - ) -> tuple[tuple[tuple[int, int], ...], tuple[_Reach, ...]]: - """(height, advance) of every line of *paragraphs* as Hancom placed them, when every paragraph keeps a - valid layout cache; the last line reaches down to the foot of any top-and-bottom or square-wrapped - object placed from its paragraph that moves with the text. A picture or drawing stands from the top of - the line its control falls on (see :meth:`_Measure.wrapped_lines`): in a cell *width* wide, the line - laid out at the whole width, which is the first one narrower than that when the lines beside the object - broke again (for a table, so in a cell *cell* wide too). A table, with a caption above or below it, stands - from its paragraph's top (where the first line would stand without it) on the first line, and from the top - of the line its control falls on, where that line would follow the one before, on a later one; so does one - in front of or behind the text moving with it (from the paragraph's top above its spacing before on the - first line), which pushes no line but makes the cell reach its foot. - A row that went on over a page end has its cell's lines start over at the top of the next page: a - line above where it would follow the one before (that one's height and spacing below it, or the - paragraph's top for a paragraph's first line, the part starting at that top) stands where it would - in the unsplit cell, and so does a line that starts the part below a table placed top and bottom on it - (the table went on with it). A paragraph's first line below an object placed from its top takes the room - above it, and so does a later line below a table placed top and bottom on it. Empty otherwise; not followed - when a table on a later line, or in front of or behind the text, is not as tall as its rows (Hancom split - it over a page end). Also where those tables stand among the lines (see :class:`_Reach`).""" - - if not paragraphs or not all(_cached_metrics(paragraph) for paragraph in paragraphs): - return (), () - tops: list[int] = [] - heights: list[int] = [] - reaches: list[_Reach] = [] - foot, after, base = 0, 0, 0 # after: where the next paragraph's first line would stand - for paragraph in paragraphs: - shape = measure.shape(paragraph.get("paraPrIDRef")) - start = after if tops else 0 # the paragraph's top, above its spacing before - top = start + shape.prev if tops else 0 - first = len(tops) # the paragraph's first line's index - segments = paragraph.findall(f"{HP}linesegarray/{HP}lineseg") - runs = paragraph.findall(f"{HP}run") - objects = [] - floats = [] # tables in front of or behind the text - for obj in (child for run in runs for child in run if _local(child) in _OBJECTS): - pos = obj.find(f"{HP}pos") - if pos is None or pos.get("treatAsChar") == "1": - continue - if _floating(obj): - if _local(obj) == "tbl": - if pos.get("flowWithText") == "0" or pos.get("vertRelTo") != "PARA" \ - or pos.get("vertAlign", "TOP") != "TOP": - return (), () - floats.append(obj) - continue - if obj.get("textWrap") not in ("TOP_AND_BOTTOM", "SQUARE") or pos.get("vertRelTo") != "PARA": - return (), () - if _local(obj) != "tbl" and pos.get("flowWithText") == "0": # stays put: pushes no line, the row - continue # as it is - objects.append(obj) - lines = {id(obj): _anchor_line(measure, paragraph, runs, "", obj, [], 0, None, ((0, 0),), len(segments)) - for obj in (*objects, *floats) if _local(obj) == "tbl"} - whole = width if width is not None else cell - if whole is not None: # the lines beside a table Hancom broke anew, narrower: it stands from the line it - full = whole - shape.left - shape.right # fell on at the cell's whole width, the first of them - lines = {key: next((index for index, segment in enumerate(segments[:line]) - if int(segment.get("horzsize", 0)) < full - (abs(shape.indent) if index == 0 else 0)), - line) for key, line in lines.items()} - pushing: dict[int, Any] = {} # a later line: the table placed top and bottom on it (or so wrapped square) - for obj in (*objects, *floats): - if _local(obj) != "tbl" or not lines[id(obj)] and obj not in floats: - continue - if int(obj.find(f"{HP}sz").get("height", 0)) != _inline_table_height(measure, obj): - raise _Unsupported("a table in a cell not as tall as its rows (split over a page end)") - if obj in objects and (obj.get("textWrap") == "TOP_AND_BOTTOM" - or whole is not None and _wraps_top_and_bottom(obj, whole)): - pushing[lines[id(obj)]] = obj - follows: list[int] = [] # where each line would follow the one before - moved: set[int] = set() # the lines below a table on a later line - below = top # where the paragraph's next line would stand - for index, segment in enumerate(segments): - vertpos = int(segment.get("vertpos", 0)) - if index and vertpos == int(segments[index - 1].get("vertpos", 0)) \ - and int(segment.get("horzpos", 0)) > int(segments[index - 1].get("horzpos", 0)): - follows.append(follows[-1]) # a line's second piece beside an object with text on both sides: at - tops.append(tops[-1]) # the first's height - heights.append(int(segment.get("textheight", segment.get("vertsize", 0)))) - continue - follows.append(below) - table = pushing.get(index) - if table is not None and vertpos == _cell_extent(measure, table) + _down(table.find(f"{HP}pos")) \ - and base < below: # the next page's part of a split row, starting below the table that went - base = below # on with the line - elif tops and vertpos + base < below: # the next page's part of a split row: the lines start over - base = (top if index == 0 else below) - (0 if index == 0 else vertpos) - tops.append(vertpos + base) - heights.append(int(segment.get("textheight", segment.get("vertsize", 0)))) - below = tops[-1] + int(segment.get("vertsize", 0)) + int(segment.get("spacing", 0)) - if index == 0 and tops[-1] > top: # below an object placed from the paragraph's top: the line - heights[-1] += tops[-1] - top # takes the room above it, and goes on to a next page with it - tops[-1] = top - elif table is not None and tops[-1] > follows[-1]: # so below a table on a later line - heights[-1] += tops[-1] - follows[-1] - tops[-1] = follows[-1] - moved.add(index) - for obj in (*objects, *floats): - if _local(obj) == "tbl": - line = lines[id(obj)] - if not line and obj not in floats: # from the paragraph's top - foot = max(foot, top + _down(obj.find(f"{HP}pos")) + _extent(obj, "height", measure) - + sum(_caption(measure, obj))) - continue - up = (start if line == 0 else follows[line]) + _down(obj.find(f"{HP}pos")) - foot = max(foot, up + _cell_extent(measure, obj)) - if pushing.get(line) is obj: # it pushes that very line - reaches.append(_Reach(follows[line], up, up + _cell_extent(measure, obj), _table_first(measure, obj), - follows[line] if line in moved else None, - int(segments[line].get("textheight", 0)), *_split_rows(measure, obj))) - else: - reaches.append(_Reach(follows[line] if line else top, up, up + _cell_extent(measure, obj))) - continue - # a picture or drawing stands its offset below the top of the line its control falls on, where - # that line would follow the one before (Hancom then moves it clear), or of the paragraph, above - # its spacing before, on its first line - line = _anchor_line(measure, paragraph, paragraph.findall(f"{HP}run"), "", obj, [], 0, None, - ((0, 0),), len(segments)) - if width is not None: # the lines beside it Hancom broke anew, narrower: it stands from the line - full = width - shape.left - shape.right # it fell on at the cell's whole width, the first of them - line = next((index for index, segment in enumerate(segments[:line]) - if int(segment.get("horzsize", 0)) < full - (abs(shape.indent) if index == 0 else 0)), - line) - up = start if line == 0 else \ - tops[first + line - 1] + heights[first + line - 1] + int(segments[line - 1].get("spacing", 0)) - foot = max(foot, up + _down(obj.find(f"{HP}pos")) + _extent(obj, "height", measure)) - last = segments[-1] - after = int(last.get("vertpos", 0)) + base + int(last.get("textheight", 0)) + int(last.get("spacing", 0)) \ - + shape.next - if any(later < earlier for earlier, later in zip(tops, tops[1:])): - return (), () - heights[-1] = max(heights[-1], foot - tops[-1]) - return tuple((height, (nxt - top) if nxt is not None else height) - for height, top, nxt in zip(heights, tops, [*tops[1:], None])), tuple(reaches) - - -def _holds_table(element: Any) -> bool: - """Whether *element* (a cell, a paragraph or a table) holds a table laid out in its text: one in a header, - footer or note control placed in it is laid out with that, elsewhere.""" - - for table in element.iter(f"{HP}tbl"): - if table is element: - continue - for up in table.iterancestors(): - if up is element: - return True - if _local(up) == "ctrl": - break - return False - - -def _pos_offset(pos: Any, name: str) -> int: - """An object's ``vertOffset`` or ``horzOffset`` as Hancom reads it: the file keeps an offset up or left as - an unsigned 32-bit number; one written with a minus sign Hancom reads as 0 (and saves so).""" - - value = pos.get(name, "0").strip() - return 0 if value.startswith("-") else int(value) - - -def _down(pos: Any) -> int: - """How far below its paragraph's top an object placed from there stands: one offset up (a negative - offset, which the file keeps as an unsigned 32-bit number) stands at the paragraph's top.""" - - offset = _pos_offset(pos, "vertOffset") - return 0 if offset >= 1 << 31 else offset - - -def _vertical(cell: Any) -> bool: - """Whether *cell* holds vertical text (``hp:subList@textDirection``): Hancom lays its lines down the - cell's height, side by side across it, cuts what does not fit and never makes its row taller.""" - - sub_list = cell.find(f"{HP}subList") - return sub_list is not None and sub_list.get("textDirection", "HORIZONTAL") != "HORIZONTAL" - - -def _page_break(table: Any) -> str: - """How a flowing table goes over a page end (``hp:tbl@pageBreak``): one holding a cell of vertical text - does not split, as if set not to (NONE): it moves to the next page whole.""" - - if any(_vertical(cell) for row in table.findall(f"{HP}tr") for cell in row.findall(f"{HP}tc")): - return "NONE" - return table.get("pageBreak", "CELL") - - -def _split_before_text(paragraphs: list[Any]) -> bool: - """Whether a cell's paragraphs hold a table placed top and bottom from its paragraph's top before its text - where Hancom split the cell over a page end: their layout caches start over at the top of the next page at - that paragraph or the next. Its declared height, as those caches, holds a part of it.""" - - tops = [int(cache.get("vertpos", 0)) if cache is not None else None - for cache in (paragraph.find(f"{HP}linesegarray/{HP}lineseg") for paragraph in paragraphs)] - for index, paragraph in enumerate(paragraphs): - table = _table_before_text(paragraph.findall(f"{HP}run")) - if table is None or _local(table) != "tbl": - continue - for at in (index, index + 1): - if 0 < at < len(tops) and tops[at] is not None and tops[at - 1] is not None and tops[at] < tops[at - 1]: - return True - return False - - -def _uncached(paragraph: Any) -> Any: - """A copy of *paragraph* without its layout caches, its cells' paragraphs' among them.""" - - copied = copy.deepcopy(paragraph) - for cache in list(copied.iter(f"{HP}linesegarray")): - cache.getparent().remove(cache) - return copied - - -def _cell_row(measure: _Measure, table: Any, cell: Any, width: int | None = None) -> _Row: - if _vertical(cell) or _size_protected(table) and _cell_height(cell.find(f"{HP}cellSz")): # its lines go across - # it, or its table is set not to change size (its text cut off below): the row as declared, one block, not split - margins = cell_margins_of(cell, table) - vertical = margins.top + margins.bottom - height = max(_cell_height(cell.find(f"{HP}cellSz")), vertical) - return _Row(height, 1, height - vertical, height - vertical, vertical, cell.get("header") == "1", - first=height - vertical) - paragraphs = cell.findall(f"{HP}subList/{HP}p") - if _split_before_text(paragraphs): # the lines as Hancom drew them hold the parts: laid out anew - paragraphs = [_uncached(paragraph) for paragraph in paragraphs] - nested = _holds_table(cell) - drawn: tuple[tuple[int, int], ...] = () - placed = [paragraph for paragraph in paragraphs if _placed_from(paragraph) - or _holds_table(paragraph) and _table_alone(paragraph.findall(f"{HP}run")) is None] - pieces = nested and bool(placed) and all(_table_pieces(measure, paragraph) is not None for paragraph in placed) - size = cell.find(f"{HP}cellSz") - margins = cell_margins_of(cell, table) - inner = (int(size.get("width", 0)) if width is None else width) - margins.left - margins.right - sub_list = cell.find(f"{HP}subList") - squeezed = sub_list is not None and sub_list.get("lineWrap") in ("SQUEEZE", "KEEP") - wrapped: tuple[tuple[int, int], ...] = () - wrapped_leads: tuple[int, ...] = () - reaches: tuple[_Reach, ...] = () - if nested and not pieces and any(_holds_table(paragraph) and _table_alone(paragraph.findall(f"{HP}run")) is None - for paragraph in paragraphs): - drawn, reaches = _drawn_lines(measure, paragraphs, cell=inner) # among text, or not set as a character: - # as Hancom drew it - if not drawn and not all(_table_on_its_own(paragraph) - or _table_before_text(paragraph.findall(f"{HP}run")) is not None - or _objects_among(paragraph.findall(f"{HP}run")) # laid out as in the body - for paragraph in paragraphs - if _holds_table(paragraph) - and _table_alone(paragraph.findall(f"{HP}run")) is None): - # placed top and bottom or square among or after the text, or in front of or behind it: clear of - # it, as a picture so placed - wrapped, wrapped_leads, reaches = ((), (), ()) if squeezed \ - else measure.wrapped_lines(paragraphs, inner, tables=True) - if not wrapped: - raise _Unsupported("a nested table") - elif not pieces and any(_placed_from(paragraph) for paragraph in paragraphs): # an object placed from a - drawn = _drawn_lines(measure, paragraphs, inner)[0] # paragraph: the lines as Hancom drew them, below it or - # beside it - if squeezed: # never broken into lines: - inner = _NO_WRAP # each paragraph one line but for its line breaks, pressed into the cell when drawn - # an object placed top and bottom or square from a paragraph without a layout cache: the lines clear of it - if not (wrapped or drawn or nested or pieces or inner == _NO_WRAP): - wrapped, wrapped_leads, _ = measure.wrapped_lines(paragraphs, inner) - # Hancom starts the cell's first line below its first paragraph's spacing before (the lines as drawn - # take that room already) - before = 0 if drawn or not paragraphs else measure.shape(paragraphs[0].get("paraPrIDRef")).prev - content, lines, pitch, char_size = measure.stack(paragraphs, inner, caches=True, floating=True, lead=before) - if drawn: - content, lines = sum(advance for _, advance in drawn[:-1]) + drawn[-1][0], len(drawn) - elif wrapped: - content, lines = before + sum(advance for _, advance in wrapped[:-1]) + wrapped[-1][0], len(wrapped) - vertical = margins.top + margins.bottom - height = max(_cell_height(size), vertical + content) - first = drawn[0][0] if drawn else before + wrapped[0][0] if wrapped else \ - before + (measure.stack_lines(paragraphs[:1], inner, caches=True, pieces=pieces) or ((0, 0),))[0][0] - several = not nested and len(paragraphs) > 1 # its lines split at their own places, spacing included - metrics = (drawn or wrapped or measure.stack_lines(paragraphs, inner, caches=True, pieces=pieces)) \ - if nested or several else () - if nested and not (drawn or wrapped or pieces): - reaches = _pushed_reaches(measure, paragraphs, inner, metrics) - # its paragraphs, a table's among them, spaced apart (lines drawn as Hancom did hold their spacing already) - spaced = several or nested and len(paragraphs) > 1 and not drawn - leads = wrapped_leads if wrapped else _line_leads(measure, paragraphs, inner, pieces) \ - if spaced or before or pieces else () - if pieces and metrics: # as tall as its lines and its tables' pieces: the caches of a cell Hancom split over a - content = max(content, _lines_height(metrics, leads)) # page end hold its parts, each from the top - height = max(height, vertical + content) - return _Row(height, len(metrics) if pieces else lines, pitch, char_size, vertical, - cell.get("header") == "1", spare=height - vertical - content, nested=nested, metrics=metrics, - first=first, leads=leads if spaced or before or pieces else (), pieces=pieces, reaches=reaches, - cuts=_line_cuts(measure, paragraphs, inner) if pieces else (), - blocks=_line_blocks(measure, paragraphs, inner) if pieces else ()) - - -def _table_first(measure: _Measure, obj: Any) -> int: - """How far below its top a table's first row ends, its top outer margin and a caption above it included; 0 for - an object that is not a table.""" - - if _local(obj) != "tbl": - return 0 - margin = obj.find(f"{HP}outMargin") - rows = _rows(measure, obj) - return (0 if margin is None else _margin(margin, "top")) + _caption(measure, obj)[0] + (rows[0].height if rows else 0) - - -def _split_rows(measure: _Measure, obj: Any) \ - -> tuple[int, tuple[tuple[int, int, int, int], ...], int, _FlowTable | None, tuple[tuple[int, int, int], ...]]: - """How a table placed top and bottom in a cell may split over a page end: the room above its first row (its - top outer margin and a caption above it), the pieces it splits into, and the room below its last row (a - caption below it and its bottom outer margin). A piece is a row, or, split between lines (CELL), each - line of a row of several, the first with the row's top cell margin, the last with its bottom one: its - height, advance, the room it needs below it when a page ends after it (the bottom margin of a row going on) - and the room above it when a page starts with it (the top margin of a row going on); rows joined by merged - cells are a piece each, split cell by cell (see :func:`_block_rest`): last, the table and those rows (where - the first's piece stands, the first and the last). No pieces for a table set not to split or not to be - adjusted (``noAdjust``), with rows holding tables, or header rows it repeats, which is not followed.""" - - margin = obj.find(f"{HP}outMargin") - if _local(obj) != "tbl" or _page_break(obj) not in ("CELL", "TABLE") or obj.get("noAdjust") == "1": - return 0, (), 0, None, () - rows, merged = _table_rows(measure, obj) - if not rows or any(row.nested or row.header and obj.get("repeatHeader") == "1" for row in rows): - return 0, (), 0, None, () - above, below = _caption(measure, obj) - above += 0 if margin is None else _margin(margin, "top") - below += 0 if margin is None else _margin(margin, "bottom") - pieces: list[tuple[int, int, int, int]] = [] - blocks: list[tuple[int, int, int]] = [] - cells = [tr.find(f"{HP}tc") for tr in obj.findall(f"{HP}tr")] - for index, (row, cell) in enumerate(zip(rows, cells)): - if row.joined and not (index and rows[index - 1].joined): # the first of rows joined by merged cells - last = index - while rows[last].joined and last + 1 < len(rows): - last += 1 - blocks.append((len(pieces), index, last)) - joined = row.joined or index and rows[index - 1].joined - lines = (row.metrics or ((row.size, row.pitch),) * row.lines) \ - if _page_break(obj) == "CELL" and not joined else () - if len(lines) < 2 or cell is None: - pieces.append((row.height - (row.spare if index < len(rows) - 1 else 0), row.height, 0, 0)) # its text - # fitting, the room it declares to spare under it is cut at the page end, as a flowing table's row's - continue - top = cell_margins_of(cell, obj).top - bottom = row.margins - top - last = row.height - top - sum(advance for _, advance in lines[:-1]) - pieces += [(top + lines[0][0], top + lines[0][1], bottom, 0)] \ - + [(height, advance, bottom, top) for height, advance in lines[1:-1]] + [(last, last, 0, top)] - table = _FlowTable(rows, _page_break(obj), obj.get("repeatHeader") == "1", _table_ends(obj), tuple(merged), - cut=_SPARE_CUT + below) if blocks else None - return above, tuple(pieces), below, table, tuple(blocks) - - -def _pushed_reaches(measure: _Measure, paragraphs: list[Any], width: int, - metrics: tuple[tuple[int, int], ...]) -> tuple[_Reach, ...]: - """Where the tables placed top and bottom before the text of a cell's paragraphs without a layout cache - (see :meth:`_Measure.pushed_lines`) stand among the cell's lines *metrics* (see :class:`_Reach`): from the - top of the paragraph's first line. Only those that may split between their rows (see :func:`_split_rows`): - another goes on to the next page whole with the line below it, which is not checked against Hancom here.""" - - reaches: list[_Reach] = [] - index = 0 - for paragraph in paragraphs: - runs = paragraph.findall(f"{HP}run") - obj = _object_before_text(runs, measure.headed(paragraph)) - if obj is not None and _local(obj) == "tbl" and measure.pushed_lines(paragraph, runs, width): - count = len(measure.stack_lines([paragraph], width, caches=True)) - line = sum(advance for _, advance in metrics[:index]) - up = line + _down(obj.find(f"{HP}pos")) - foot = up + _cell_extent(measure, obj) - unit, text, y = None, 0, line # the first line reaching it, which goes below it taking the room above - for height, advance in metrics[index:index + count]: - if y + height > up and y < foot: - unit, text = y, height - (foot - y) - break - y += advance - split = _split_rows(measure, obj) - if split[1]: # one that may not split goes on whole with its line, as it did before - reaches.append(_Reach(line, up, foot, _table_first(measure, obj), unit, text, *split)) - index += count - continue - index += len(measure.stack_lines([paragraph], width, caches=True)) - return tuple(reaches) - - -def _line_leads(measure: _Measure, paragraphs: list[Any], width: int, pieces: bool = False) -> tuple[int, ...]: - """The room above each line of *paragraphs* (as :meth:`_Measure.stack_lines` lays them out) when a part - of their cell starts with it: a paragraph's spacing before at its first line, none at the others.""" - - leads: list[int] = [] - for paragraph in paragraphs: - prev = measure.shape(paragraph.get("paraPrIDRef")).prev - split = _table_pieces(measure, paragraph) if pieces else None - if split is not None: # a table's: the room above each (a repeated header, a row's top margin) - leads += [prev + split[1][0]] + list(split[1][1:]) - continue - count = len(measure.stack_lines([paragraph], width, caches=True)) - leads += [prev] + [0] * (count - 1) - return tuple(leads) - - -def _line_cuts(measure: _Measure, paragraphs: list[Any], width: int) -> tuple[int, ...]: - """The room each line of *paragraphs* (as :meth:`_Measure.stack_lines` lays them out with tables' pieces) - needs below it to stay above a page end: none for a line of text, a table's cut (101) for a piece of a - table and its bottom margin under it but for the last (which holds it), as Hancom keeps a table's rows - among a cell's text.""" - - cuts: list[int] = [] - for paragraph in paragraphs: - split = _table_pieces(measure, paragraph) - if split is None: - cuts += [0] * len(measure.stack_lines([paragraph], width, caches=True)) - continue - table = next(child for run in paragraph.findall(f"{HP}run") for child in run if _local(child) == "tbl") - below = _table_ends(table)[1] - cuts += [_SPARE_CUT + below + room for room in split[3][:-1]] + [_SPARE_CUT] - return tuple(cuts) - - -def _line_blocks(measure: _Measure, paragraphs: list[Any], - width: int) -> tuple[tuple[int, _FlowTable, int, int], ...]: - """The rows joined by merged cells of the tables among the lines of *paragraphs* (as - :meth:`_Measure.stack_lines` lays them out with tables' pieces): where the first's piece stands among those - lines, the table, and its first and last row.""" - - blocks: list[tuple[int, _FlowTable, int, int]] = [] - count = 0 - for paragraph in paragraphs: - split = _table_pieces(measure, paragraph) - if split is None: - count += len(measure.stack_lines([paragraph], width, caches=True)) - continue - table = next(child for run in paragraph.findall(f"{HP}run") for child in run if _local(child) == "tbl") - rows, cells = _table_rows(measure, table) - flowing = _FlowTable(rows, _page_break(table), table.get("repeatHeader") == "1", _table_ends(table), - tuple(cells), cut=_spare_cut(table)) - first = 0 - while first < len(rows): - last = first - while rows[last].joined and last + 1 < len(rows): - last += 1 - if last > first: - blocks.append((count + split[2][first], flowing, first, last)) - first = last + 1 - count += len(split[0]) - return tuple(blocks) - - -def _table_pieces(measure: _Measure, paragraph: Any) \ - -> tuple[tuple[tuple[int, int], ...], tuple[int, ...], tuple[int, ...], tuple[int, ...]] | None: - """How a table placed top and bottom on its own in a cell paragraph, from the paragraph's top, splits with - its row over a page end: (height, advance) of each piece and the room above each when a part of the cell - starts with it. Hancom splits such a table between its rows, one moved row by row (TABLE) as well as one - split between lines (CELL), which splits a row of several lines between them too, the row's cell - margins around each part; its top outer margin and a repeated header go above each part but the first. - ``None`` for any other - paragraph, and for a table set not to split (NONE), offset down, with a caption, or with rows holding - tables that do not split so (a row holding one that does splits between its pieces as between lines, and - one holding tables set as characters between its lines, a table one, as in the body). - Rows joined by merged cells are a piece each (see :func:`_line_blocks`). Third: where each row's first - piece stands among the pieces; fourth: the room each needs below it when a page ends after it (the bottom - margin of a row going on).""" - - if not _table_on_its_own(paragraph): - return None - table = next(child for run in paragraph.findall(f"{HP}run") for child in run if _local(child) == "tbl") - mode = _page_break(table) - if mode not in ("CELL", "TABLE") or _down(table.find(f"{HP}pos")) or table.find(f"{HP}caption") is not None: - return None - rows = _rows(measure, table) - cells = [tr.find(f"{HP}tc") for tr in table.findall(f"{HP}tr")] - if len(rows) != len(cells) or any(row.nested and not (row.pieces or row.metrics and not row.reaches) - for row in rows): - return None - header = sum(row.height for row in rows if row.header) if table.get("repeatHeader") == "1" else 0 - margin = table.find(f"{HP}outMargin") - above, below = (0, 0) if margin is None else (_margin(margin, "top"), _margin(margin, "bottom")) - pieces: list[tuple[int, int]] = [] - leads: list[int] = [] - starts: list[int] = [] - rooms: list[int] = [] - for index, (row, cell) in enumerate(zip(rows, cells)): - starts.append(len(pieces)) - lead = 0 if row.header or not pieces else above + header # a part going on: below its top margin again - joined = row.joined or index and rows[index - 1].joined - lines = (row.metrics or ((row.size, row.pitch),) * row.lines) if mode == "CELL" and not joined else () - if len(lines) < 2: - pieces.append((row.height - (row.spare if index < len(rows) - 1 else 0), row.height)) # room to spare - # under its text cut at the page end (see _split_rows) - leads.append(lead) - rooms.append(0) - continue - margins = cell_margins_of(cell, table) - top = margins.top - last = row.height - top - sum(advance for _, advance in lines[:-1]) # its foot, its room to spare - pieces += [(top + lines[0][0], top + lines[0][1])] + list(lines[1:-1]) + [(last, last)] - leads += [lead] + [lead + top] * (len(lines) - 1) - rooms += [margins.bottom + (row.cuts[line] if row.cuts else 0) # a part of the row ending there: its - for line in range(len(lines) - 1)] # bottom margin under it, and what its own tables keep - rooms.append(0) - continue - pieces[0] = (pieces[0][0] + above, pieces[0][1] + above) - pieces[-1] = (pieces[-1][0] + below, pieces[-1][1] + below) - return tuple(pieces), tuple(leads), tuple(starts), tuple(rooms) - - -@dataclass(frozen=True) -class _Wrap: - """The band a square-wrapped object takes beside the text, from *top* to *bottom* below the top of - the first line of the paragraph at hand; a line in it is *cut* narrower. A top-and-bottom object's - band (*push*) has no room beside it: the first line reaching it goes below it instead.""" - - top: int - bottom: int - cut: int - push: bool = False - #: with text on both sides: the left piece's width (a line in the band is two pieces at one height, - #: the right one the line's width less *cut* and this) - split: int = 0 - #: its object does not flow with the text (pos@flowWithText="0"): it stays on its page past the - #: body's foot, and the band goes no further than that page - stays: bool = False - #: its object is placed on the paper or the page: the band is in the body of its page, and the lines of - #: any paragraph there reaching it go beside it - paper: bool = False - #: such an object's room on its left and on its right in a column *column* wide (see :func:`_square_sides`): - #: a line beside it runs from the paragraph's left margin to the object, or from the object to the - #: paragraph's right margin, the margin on the object's side taking no more (see :meth:`pieces`) - room: tuple[int, int] = (0, 0) - column: int = 0 - - def pieces(self, full: float, right: int) -> list[float]: - """The widths of a line beside an object with *room*, its pieces one on each side with text: a line - *full* wide, its right margin *right*.""" - - end = self.column - right - start = end - full - left, beside = self.room - widths = ([min(end, left) - start] if left else []) + ([end - max(start, self.column - beside)] - if beside else []) - if any(width <= 0 for width in widths): - raise _Unsupported("a paragraph's margin reaching past a square-wrapped object placed on the paper") - return widths - - def lower(self, by: int) -> "_Wrap | None": - """The band seen from *by* further down, or ``None`` once it is above.""" - - return replace(self, top=self.top - by, bottom=self.bottom - by) if self.bottom > by else None - - -@dataclass(frozen=True) -class _Anchor: - """A top-and-bottom object anchored in a paragraph of text: it stands at the top of line *line*, - and that line and the rest of the paragraph come below it.""" - - line: int - table: _FlowTable | None # a table flowing with the text, or - height: int # the height of any other object, its outer margins included - stays: bool = False # that object does not flow with the text (pos@flowWithText="0") - - -@dataclass(frozen=True) -class _Band: - """A table flowing with the text, top and bottom in a paragraph of text and *offset* down from the top - of line *line* (its outer margin above included): it flows from there over the page end, and the - first line reaching it, in that paragraph or the ones after, and the lines after go below its end.""" - - line: int - offset: int - table: _FlowTable - - -@dataclass(frozen=True) -class _Stacked: - """An object placed top and bottom in a paragraph holding nothing else but more such objects: its - offset below the paragraph's top (above its spacing), its span across the column and its height, outer - margins included (a table as tall as its rows), and a table's rows, which split over the pages when - it is taller than a page.""" - - offset: int - left: int - right: int - height: int - table: _FlowTable | None = None - - -@dataclass(frozen=True) -class _Para: - lines: int - size: int - pitch: int - prev: int - next: int - break_before: bool - keep_lines: bool - keep_next: bool - widow_orphan: bool - page_break: bool = False # hp:p@pageBreak - column_break: bool = False # hp:p@columnBreak - table: _FlowTable | None = None - #: line index -> (height of the notes anchored in it, how many, size of the first one's first line) - notes: dict[int, tuple[int, int, int]] = field(default_factory=dict) - #: (height, advance) of each line from the paragraph's valid layout cache, or of each line of a - #: paragraph of several character sizes; empty when every line is ``size`` tall and ``pitch`` apart. - cached: tuple[tuple[int, int], ...] = () - anchor: _Anchor | None = None - #: a square-wrapped object's band starts in this paragraph, this far below its first line's top - wrap_bottom: int = 0 - #: how many of the first lines are beside such a band (they must stay on the band's page) - wrap_lines: int = 0 - #: the paragraph keeps its layout cache and such a band is a square-wrapped object's, which takes no - #: line's height: where the object goes moves none of its lines - wrap_fixed: bool = False - #: the band's object does not flow with the text (pos@flowWithText="0"): past the body's foot it stays - #: on its page, overflowing it, instead of going on to the next - wrap_stays: bool = False - #: beside such a staying band, its lines do not depend on the band (it keeps its layout cache or holds no - #: text): a page break among them puts the rest on the next page, where Hancom lays them out whole - wrap_free: bool = False - #: the line the object laid out around the text (the caller's) stands on - wrap_anchor: int = 0 - band: _Band | None = None - #: for each object anchored here and placed on the paper or the page: (top, bottom) in the body, whether it - #: leaves a line's room beside it, the columns it reaches over and the band the lines beside it are broken - #: in (see :func:`_paper_bands`) - paper: tuple[tuple[int, int, bool, tuple[int, ...], _Wrap | None], ...] = () - #: the top of such a band that pushes the lines below it to the body's foot and that keeps the object on its - #: paragraph's page (pos@holdAnchorAndSO="1"): when the first line with its spacing reaches it there, the - #: paragraph goes on to the next page's top with the object, the lines above staying where they are - held: int | None = None - #: in columns of unequal width, a paragraph without a layout cache: its text, to break again - reflow: _Reflow | None = None - #: holding nothing, in a section hiding a page's first empty lines (see :meth:`_Paginator._paragraph`) - hides: bool = False - #: its lines are Hancom's own, from the paragraph's valid layout cache - kept: bool = False - #: the step of the line grid its lines snap to (see :func:`_on_grid`), 0 for none - grid: int = 0 - #: an object anchored in this paragraph holding nothing else but spaces on one line: a table of it starting - #: on the next page goes there as when the paragraph holds it alone, the paragraph's line staying - spaced: bool = False - #: the top-and-bottom objects stacked in this paragraph, which holds nothing else (see :func:`_stack`) - stack: tuple[_Stacked, ...] = () - #: a square-wrapped object anchored here and flowing with the text went past the body's foot: Hancom sets - #: it at the next page's body top, whatever its offset (this band, from there) - moved: _Wrap | None = None - #: holding no text: its line goes beside such a band as it is - blank: bool = False - #: holding nothing but a top-and-bottom object offset down from it (see :func:`_pushing_object`): its empty - #: line stays where it is beside the object's band, which only the lines after reaching it go below - bare: bool = False - #: a top-and-bottom object offset from this paragraph (not a flowing table) pushes its lines below it: - #: when its band would pass the body's foot, Hancom moves it to the next page's top instead - wrap_push: bool = False - #: how far such an object pushed the paragraph's first line down (its band's foot is measured from where - #: that line stood before) - wrap_shift: int = 0 - #: how far an earlier paragraph's top-and-bottom object pushed this paragraph's first line down (part of - #: :attr:`prev`): going on to the next page, the line drops it and starts at that page's top - lead: int = 0 - #: a table wrapped square anchored here, flowing with the text and allowed to split, that goes on over the - #: page end: it as it flows, how far below the paragraph's first line it starts, and its band beside the - #: text (see :meth:`_Paginator._span_bands`) - spans: tuple[_FlowTable, int, _Wrap] | None = None - #: such an object alone in this empty paragraph, its foot this far below the paragraph's top (the line is - #: as tall as that): past the body's foot it goes on to the next page's top, the empty line staying when - #: it fits there (*own* tall) - moves: int = 0 - own: int = 0 - #: a top-and-bottom object alone in this empty paragraph, its foot this far below the line's top: the next - #: paragraph starts no higher, but its spacing and this one's count only where the empty line's own advance - #: with them reaches lower (Hancom's empty line stays beside the object, which the next line goes below) - floor: int = 0 - #: a top-and-bottom object alone in this empty paragraph placed up from its top: (how far up, as a negative - #: offset, how tall, and the paragraph's own line and advance) -- see :meth:`_Paginator._below_a_rising_object` - rises: tuple[int, int, int, int] | None = None - #: a flowing table alone in this empty paragraph, allowed to overlap and starting on the line: the line goes - #: below it (see :meth:`_Paginator._flow`) - under: bool = False - - def height(self, line: int) -> int: - return self.cached[line][0] if self.cached else self.size - - def advance(self, line: int) -> int: - return self.cached[line][1] if self.cached else self.pitch - - def span(self, first: int, count: int) -> int: - """From the top of line *first* to the top of the line *count* lines further down.""" - - if not self.cached: - return count * self.pitch - return sum(self.cached[line][1] for line in range(first, first + count)) - - -@dataclass(frozen=True) -class _Reflow: - """A paragraph without a layout cache in columns of unequal width, its lines broken at a column - *width* from *offset* in its text on (*starts*: where each of them starts, from *offset*).""" - - measure: _Measure - text: str - sizes: tuple[int, ...] - looks: tuple[Any, ...] | None - style: Any - shape: _Shape - width: int = 0 - offset: int = 0 - starts: tuple[int, ...] = () - end: int = 0 # the paragraph's end (see :func:`_end_size`) - head: int = 0 # its label (see :func:`_head_size`) - wrapped: bool = False # its lines from *offset* on are broken beside a band (see :meth:`banded`) - - def at(self, para: _Para, width: int, line: int) -> _Para: - """*para* with its lines from line *line* on (the lines before it laid out already) broken - again at a column *width* wide: Hancom breaks the text a column holds at that column's width, - the paragraph's first line less its first-line indent, the others less a hanging one.""" - - offset = self.offset + (self.starts[line] if line else 0) - text = self.text[offset:] # empty only after a line break ending the paragraph - sizes = list(self.sizes[offset:] or self.sizes[-1:]) - looks = None if self.looks is None else list(self.looks[offset:] or self.looks[-1:]) - room = width - self.shape.left - self.shape.right - widths: list[float] = [room - max(self.shape.indent, 0), room - max(-self.shape.indent, 0)] - if offset: # the rest: none of its lines is the paragraph's first - widths = widths[1:] - mixed = len(set(sizes)) > 1 - starts = self.measure.line_starts(text, widths, min(sizes), self.style, sizes if mixed else None, looks) - cached = _line_metrics(self.measure, text, widths, sizes, self.style, self.shape, {}, looks) \ - if mixed or looks is not None or self.shape.font_line else () - return replace(para, lines=len(starts), cached=cached, - reflow=replace(self, width=width, offset=offset, starts=tuple(starts), wrapped=False)) - - def banded(self, para: _Para, line: int, wrap: _Wrap) -> _Para: - """*para* with its lines from line *line* on (the lines before it laid out already) broken again - beside *wrap*'s band, as seen from that line's top: a line whose top is above the band's foot is as - wide as the room beside the object, or two pieces at one height with text on both sides; the lines - below are the whole width.""" - - mixed = len(set(self.sizes)) > 1 - widths = _indented(self.width - self.shape.left - self.shape.right, self.shape, self.style) - starts = self.starts - if line and not starts: # where its lines start as laid out so far - starts = tuple(self.measure.line_starts(self.text, widths, min(self.sizes), self.style, - list(self.sizes) if mixed else None, - None if self.looks is None else list(self.looks))) - if len(starts) != para.lines: - raise _Unsupported("lines beside a square-wrapped object moved to the next page") - offset = self.offset + (starts[line] if line else 0) - text = self.text[offset:] - if not text: # only a line break ending the paragraph is left - return para - sizes = list(self.sizes[offset:]) - looks = None if self.looks is None else list(self.looks[offset:]) - if offset: # the rest: none of its lines is the paragraph's first - widths = [widths[1], widths[1]] - several = sizes if len(set(sizes)) > 1 else None - lines, firsts = _wrapped_widths(self.measure, text, widths, min(sizes), self.style, self.shape, wrap, - several, looks) - pieces = self.measure.line_starts(text, lines, min(sizes), self.style, several, looks) - metrics = _at_one_height(_line_metrics(self.measure, text, lines, sizes, self.style, self.shape, {}, looks, - end=self.end, head=0 if offset else self.head), firsts) - return replace(para, lines=len(metrics), cached=metrics, - reflow=replace(self, offset=offset, starts=tuple(pieces), wrapped=True)) - - @dataclass(frozen=True) class _Page: body: int @@ -2187,41 +458,6 @@ def _in_sub_list(element: Any) -> bool: return any(_local(ancestor) == "subList" for ancestor in element.iterancestors()) -def _caption(measure: _Measure, table: Any) -> tuple[int, int]: - """How much room a table's (or another object's) caption takes above it and below it: its first - paragraph's spacing before (Hancom starts the caption's first line below it), its lines and its gap (a - caption beside the object takes none).""" - - caption = table.find(f"{HP}caption") - if caption is None or caption.get("side") not in ("TOP", "BOTTOM"): - return (0, 0) - paragraphs = caption.findall(f"{HP}subList/{HP}p") - width = int(caption.get("lastWidth", 0)) or int(table.find(f"{HP}sz").get("width", 0)) - before = measure.shape(paragraphs[0].get("paraPrIDRef")).prev if paragraphs else 0 - tall = before + measure.stack(paragraphs, width, caches=True)[0] + int(caption.get("gap", 0)) - return (tall, 0) if caption.get("side") == "TOP" else (0, tall) - - -def _inline_table_height(measure: _Measure, table: Any) -> int: - """A table set as a character (or placed top and bottom in a cell): its rows as the estimate measures - them. When the row model does not follow the table (merged rows, a nested table) but every paragraph in - it keeps a valid layout cache, Hancom laid it out as it is, and the height it saved (hp:sz) is the height - it draws.""" - - if _holds_table(table) or any(_row_span(tc) != 1 for tc in table.iter(f"{HP}tc")): - paragraphs = list(table.iter(f"{HP}p")) - if paragraphs and all(_cache_lines(paragraph) for paragraph in paragraphs): - return int(table.find(f"{HP}sz").get("height", 0)) - return _rows_height(measure, table) - - -def _rows_height(measure: _Measure, table: Any) -> int: - """How tall a table's rows make it: the rows (see :func:`_rows`, each with the cell spacing above it) and - the spacing below the last.""" - - return sum(row.height for row in _rows(measure, table)) + _cell_spacing(table) - - @dataclass(frozen=True) class _NoteShape: above: int = 0 # hp:noteSpacing@aboveLine @@ -2392,174 +628,6 @@ def _section_parts(measure: _Measure, section: Any) -> list[Any]: return parts -def _objects_reach(runs: list[Any], measure: _Measure, spacing: int = 0) -> int: - """How far below the top of their paragraph's line in a cell, holding no text, the pictures and drawings - placed from it reach: top and bottom or square, not set as a character, moving with the text, their outer - margins included (the cell holds them, and its row grows to; one that stays put does not count). So do the - tables placed top and bottom from it, as tall as their rows and a caption above or below them (one placed - up stands at the paragraph's top), placed from the paragraph's top above its *spacing* before.""" - - reach = 0 - if _run_text(runs).strip(): # text goes on below such an object: not followed here - return reach - for obj in (child for run in runs for child in run): - name, pos = _local(obj), obj.find(f"{HP}pos") - if name == "tbl" and _placed_top_and_bottom(obj): - reach = max(reach, _down(pos) - spacing + _inline_table_height(measure, obj) + _extent_margins(obj) - + sum(_caption(measure, obj))) - continue - if name not in _OBJECTS or name == "tbl" or pos is None or obj.find(f"{HP}sz") is None \ - or pos.get("treatAsChar") == "1" or obj.get("textWrap") not in ("TOP_AND_BOTTOM", "SQUARE") \ - or pos.get("flowWithText") == "0" or pos.get("vertRelTo") != "PARA" \ - or pos.get("vertAlign", "TOP") != "TOP": - continue - reach = max(reach, _down(pos) + _extent(obj, "height", measure)) # one placed up stands at the top - return reach - - -def _floating_reach(runs: list[Any], measure: _Measure) -> int: - """How far below the top of their paragraph in a cell the pictures and drawings in front of or behind the - text placed from it reach, when they move with the text (pos@flowWithText not "0"), their outer margins - included: they push no line aside, but the cell grows to hold them. One that stays put does not.""" - - reach = 0 - for obj in (child for run in runs for child in run): - pos = obj.find(f"{HP}pos") - if _local(obj) not in _OBJECTS or _local(obj) == "tbl" or pos is None or obj.find(f"{HP}sz") is None or not _floating(obj) or pos.get("flowWithText") == "0" or pos.get("vertRelTo") != "PARA" or pos.get("vertAlign", "TOP") != "TOP": - continue - reach = max(reach, _down(pos) + _extent(obj, "height", measure)) # one placed up stands at the top - return reach - - -def _wraps_in_cell(obj: Any, tables: bool = False) -> bool: - """A picture or drawing (with *tables*, a table too) placed top and bottom or square from the top of its - paragraph, not set as a character, that moves with the text: in a cell, one that stays put - (pos@flowWithText="0") pushes no line aside and leaves the row as it is.""" - - pos = obj.find(f"{HP}pos") - return _local(obj) in _OBJECTS and (tables or _local(obj) != "tbl") and pos is not None \ - and obj.find(f"{HP}sz") is not None \ - and pos.get("treatAsChar") != "1" and obj.get("textWrap") in ("TOP_AND_BOTTOM", "SQUARE") \ - and pos.get("flowWithText") != "0" and pos.get("vertRelTo") == "PARA" and pos.get("vertAlign", "TOP") == "TOP" - - -def _cell_extent(measure: _Measure, obj: Any) -> int: - """How tall an object placed from a cell paragraph stands, its outer margins included: a table as its rows - (see :func:`_inline_table_height`) with a caption above or below it (its lines and its gap; one beside it is - not followed), anything else as Hancom draws it.""" - - if _local(obj) != "tbl": - return _extent(obj, "height", measure) - caption = obj.find(f"{HP}caption") - if caption is not None and caption.get("side") not in ("TOP", "BOTTOM"): - raise _Unsupported("a table in a cell with a caption beside it") - return _inline_table_height(measure, obj) + _extent_margins(obj) + sum(_caption(measure, obj)) - - -def _control_place(runs: list[Any], obj: Any) -> int: - """How many characters of the paragraph's text come before *obj*'s control.""" - - place = 0 - for child in (child for run in runs for child in run): - if child is obj: - break - if _local(child) == "t": - place += len(_t_text(child)) - return place - - -def _cell_band(measure: _Measure, obj: Any, top: int, width: int) -> tuple[int, int, int | None]: - """The band an object wrapped in a cell *width* wide (see :func:`_wraps_in_cell`) placed from *top* takes: - its top and foot, its outer margins included, and the room beside it, ``None`` when it pushes the lines - below it (top and bottom, or less than 1440 beside it). Placed from the paragraph's or the column's left or - right, it stands from the cell's text area's.""" - - pos = obj.find(f"{HP}pos") - up = top + _down(pos) # one placed up stands at that top - foot = up + _cell_extent(measure, obj) - if _wraps_top_and_bottom(obj, width): - return up, foot, None - if pos.get("horzRelTo") not in ("PARA", "COLUMN") or pos.get("horzAlign") not in ("LEFT", "RIGHT") \ - or obj.get("textFlow", "BOTH_SIDES") not in ("BOTH_SIDES", "LARGEST_ONLY", "LEFT_ONLY", "RIGHT_ONLY"): - raise _Unsupported(f"{_local(obj)} wrapped square elsewhere than at a cell's edge") - wide, offset = _extent(obj, "width"), _pos_offset(pos, "horzOffset") - if offset >= 1 << 31: # kept unsigned: one placed out past the edge - offset -= 1 << 32 - start = offset if pos.get("horzAlign") == "LEFT" else width - wide - offset - left, right = start, width - start - wide - flow = obj.get("textFlow", "BOTH_SIDES") - if flow == "LARGEST_ONLY": - flow = "LEFT_ONLY" if left > right else "RIGHT_ONLY" - left = left if left >= _MIN_SIDE and flow != "RIGHT_ONLY" else 0 - right = right if right >= _MIN_SIDE and flow != "LEFT_ONLY" else 0 - if left and right: - return up, foot, _BothSides(min(left, right)) - return up, foot, (left or right) or None - - -class _BothSides(int): - """The room beside an object wrapped square in a cell with text on both sides of it (the narrower side's): an - empty line goes beside it, two empty pieces at one height as tall as the line; text there is not followed.""" - - -def _beside_one_side(narrow: dict[int, int], empty: bool) -> None: - """Text on lines *narrow* beside an object wrapped square in a cell with text on both sides of it (unless - the paragraph is *empty*) is not followed.""" - - if not empty and any(isinstance(room, _BothSides) for room in narrow.values()): - raise _Unsupported("text on both sides of an object wrapped square in a cell") - - -def _clear_of(measure: _Measure, metrics: list[tuple[int, int]], top: int, prev: int, anchor: int, obj: Any, - bands: list[tuple[int, int, int | None]], empty: bool, width: int - ) -> tuple[list[tuple[int, int, int]], dict[int, int], tuple[int, int, int | None] | None]: - """(top, height, advance) of each line of a cell paragraph whose lines are *metrics* (height, advance), its - first line's top *top* below its spacing before *prev*, laid out clear of the *bands* of the objects above - and of the band of its own object *obj* (see :func:`_cell_band`), whose control is on line *anchor*: a - line reaching a band with no room beside it goes below its foot, and one in a square object's band takes - the room beside it (returned by the line's index), as does *obj*'s band. An *empty* paragraph's line stays - beside its own object when that may not overlap the text (pos@allowOverlap="0").""" - - placed: list[tuple[int, int, int]] = [] - narrow: dict[int, int] = {} - own = None - for index, (height, advance) in enumerate(metrics): - y = placed[-1][0] + placed[-1][2] if placed else top - if obj is not None and index == anchor: - own = _cell_band(measure, obj, y - (prev if index == 0 else 0), width) - stays = own if empty and index == 0 and obj is not None \ - and obj.find(f"{HP}pos").get("allowOverlap") == "0" else None - around = [*bands, *(() if own is None else (own,))] - moved = True - while moved: - moved = False - for band in around: - if band is not stays and band[2] is None and y < band[1] and y + height > band[0]: - y, moved = band[1], True - beside = [band[2] for band in around if band[2] is not None and y < band[1] and y + height > band[0]] - if beside: - narrow[index] = _BothSides(min(beside)) if any(isinstance(room, _BothSides) for room in beside) else min(beside) - placed.append((y, height, advance)) - return placed, narrow, own - - -def _placed_top_and_bottom(obj: Any) -> bool: - """An object placed top and bottom from its paragraph's top, not set as a character.""" - - pos = obj.find(f"{HP}pos") - return pos is not None and pos.get("treatAsChar") != "1" and obj.get("textWrap") == "TOP_AND_BOTTOM" \ - and pos.get("vertRelTo") == "PARA" and pos.get("vertAlign", "TOP") == "TOP" - - -def _placed_from(paragraph: Any) -> bool: - """Whether *paragraph* holds an object placed from it in the text's flow: not set as a character, nor in - front of or behind the text.""" - - return any(_local(child) in _OBJECTS and child.find(f"{HP}pos") is not None - and child.find(f"{HP}pos").get("treatAsChar") != "1" and not _floating(child) - for run in paragraph.findall(f"{HP}run") for child in run) - - def _below_the_band(measure: _Measure, runs: list[Any], wrap: _Wrap) -> bool: """Whether every line of a paragraph goes below the band of a square-wrapped object anchored before it (*wrap*, as the paragraph sees it): its one object placed top and bottom from its top before its text, @@ -2578,119 +646,12 @@ def _below_the_band(measure: _Measure, runs: list[Any], wrap: _Wrap) -> bool: return offset + tall >= wrap.bottom -def _object_before_text(runs: list[Any], headed: bool = False) -> Any: - """The object placed top and bottom from its paragraph's top (a table, picture or drawing) that is all the - runs hold but text after it -- a space is text, and so is the bullet or number of a *headed* paragraph or - an object in front of or behind the text beside it (see :func:`_beside_floating`) -- or ``None``.""" - - objects = [child for run in runs for child in run if _local(child) in _OBJECTS and not _floating(child)] - if len(objects) != 1 or not _placed_top_and_bottom(objects[0]) \ - or not (_run_text(runs) or headed or _beside_floating(runs)): - return None - for child in (child for run in runs for child in run): - if child is objects[0]: - return child - if _local(child) == "t" and _t_text(child).strip(): # text before it - return None - return None - - -def _beside_floating(runs: list[Any]) -> bool: - """Whether the runs hold an object in front of or behind the text: beside an object placed top and bottom - from the paragraph's top in a paragraph of no text, it sends the paragraph's empty line below that object, - as the whole width, as a space or a label does.""" - - return any(_local(child) in _OBJECTS and _floating(child) for run in runs for child in run) - - -def _table_on_its_own(paragraph: Any) -> bool: - """Whether a cell paragraph holds no text, not even a space, and nothing but one table placed top and - bottom from its top (Hancom sets the empty line below two of them, not beside them, and so with an object - in front of or behind the text beside it).""" - - runs = paragraph.findall(f"{HP}run") - objects = [child for run in runs for child in run if _local(child) in _OBJECTS] - return not _run_text(runs) and len(objects) == 1 and _local(objects[0]) == "tbl" \ - and _placed_top_and_bottom(objects[0]) - - -def _table_before_text(runs: list[Any]) -> Any: - """The table placed top and bottom from its paragraph's top that is all the runs hold but text after it - (text, a space being enough, or an object in front of or behind the text beside it), or ``None``.""" - - objects = [child for run in runs for child in run if _local(child) in _OBJECTS and not _floating(child)] - if len(objects) != 1 or _local(objects[0]) != "tbl" or not _placed_top_and_bottom(objects[0]) \ - or not (_run_text(runs) or _beside_floating(runs)): - return None - for child in (child for run in runs for child in run): - if child is objects[0]: - return child - if _local(child) == "t" and _t_text(child).strip(): # text before it - return None - return None - - -def _placed_objects(runs: list[Any]) -> list[Any]: - """The objects of the runs.""" - - objects = [child for run in runs for child in run if _local(child) in _OBJECTS] - for obj in objects: - if obj.find(f"{HP}pos") is None or obj.find(f"{HP}sz") is None: - raise _Unsupported(f"{_local(obj)} without a position") - return [obj for obj in objects if not _floating(obj) and not _on_paper(obj)] - - def _holds_nothing(runs: list[Any]) -> bool: """Whether the runs hold no character, object or control at all (a space is a character).""" return all(_local(child) == "t" and not child.text and not len(child) for run in runs for child in run) -def _marks(runs: list[Any]) -> bool: - """Whether the runs hold composed characters or ruby text.""" - - return any(_local(child) in _MARKS for run in runs for child in run) - - -def _check_ruby_spacing(runs: list[Any], shape: _Shape) -> None: - """A line holding ruby text is spaced from its height in percent: other line spacing is not followed.""" - - if shape.kind != "PERCENT" and any(_local(child) == "dutmal" for run in runs for child in run): - raise _Unsupported("ruby text in a paragraph with line spacing other than percent") - - -def _mark_extent(mark: Any, size: int, style: Any) -> tuple[int, int]: - """(width, height) a composed character or ruby text takes as a character of *size* and *style*. A - composed one is as wide as a Hangul syllable when framed or spread, else as its widest character, - and no taller than the text. Ruby text is as wide as its text, however long the ruby, and as tall as - the text with the ruby above it, or below it over the text's foot, in 1/1800 inch.""" - - points = size / 100 - if _local(mark) == "compose": - text = mark.get("composeText", "") - if mark.get("circleType", "CHAR") != "CHAR" or mark.get("composeType") == "SPREAD" or not text: - return round(char_advance("\uac00", points, style)), size - return round(max(char_advance(ch, points, style) for ch in text)), size - position = mark.get("posType", "TOP") - if position not in ("TOP", "BOTTOM"): - raise _Unsupported(f"ruby text placed {position}") - main = mark.find(f"{HP}mainText") - width = round(sum(char_advance(ch, points, style) for ch in (main.text or "" if main is not None else ""))) - em, ruby = size // 4, size * (int(mark.get("szRatio") or 0) or 50) // 100 // 4 - return width, 4 * (em + ruby if position == "TOP" else em * 91 // 100 + ruby) - - -def _on_paper(obj: Any) -> bool: - """A top-and-bottom object placed from the top or the bottom of the paper or of the page, or centred on it, - not set as a character: it takes no room in its paragraph but keeps every line of its page out of its band. - One wrapped square there counts as well (see :func:`_paper_band`).""" - - pos = obj.find(f"{HP}pos") - return (pos is not None and pos.get("treatAsChar") != "1" and obj.get("textWrap") in ("TOP_AND_BOTTOM", "SQUARE") - and pos.get("vertRelTo") in ("PAPER", "PAGE") - and pos.get("vertAlign", "TOP") in ("TOP", "CENTER", "BOTTOM")) - - def _paper_band(measure: _Measure, page: _Page, paragraph: Any) -> tuple[int, int, bool, tuple[int, ...]] | None: """The band of the first object of *paragraph* placed on the paper, if any (see :func:`_paper_bands`).""" @@ -2787,356 +748,6 @@ def _paper_left(obj: Any, page: _Page) -> int | None: "RIGHT": page.paper_width - width - offset}.get(pos.get("horzAlign", "LEFT")) -def _floating(obj: Any) -> bool: - """An object in front of or behind the text, not set as a character: the text flows as if it were not - there.""" - - pos = obj.find(f"{HP}pos") - return obj.get("textWrap") in _FLOATING and (pos is None or pos.get("treatAsChar") != "1") - - -def _text_size(measure: _Measure, runs: list[Any], paragraph: Any = None) -> tuple[int, list[Any], list[int]]: - """The paragraph's character size (its smallest), the character shapes of its runs holding text - (the style comes from the first), and each character's size. An empty run takes no room; a paragraph - without text is as tall as the largest of its runs holding controls or objects and its last run, and, - given the *paragraph*, as the number label Hancom draws for it (in its own character shape; a bullet's - takes the paragraph's end's, see :meth:`_Measure.label_size`).""" - - lengths = [sum(len(_t_text(text)) for text in run.findall(f"{HP}t")) for run in runs] - refs = [run.get("charPrIDRef") for run, length in zip(runs, lengths) if length] - refs = refs or [run.get("charPrIDRef") for run in runs if run.find(f"{HP}t") is not None] - refs = refs or [run.get("charPrIDRef") for run in runs] or ["0"] - sizes: list[int] = [] - for run, length in zip(runs, lengths): - sizes += [measure.char_height(run.get("charPrIDRef"))] * length - if not sizes and runs: # no text: as tall as its runs holding controls or objects, and its end (the last run) - held = [run.get("charPrIDRef") for run in runs[:-1] if any(child.tag != f"{HP}t" for child in run)] - tall = max(measure.char_height(ref) for ref in [*held, runs[-1].get("charPrIDRef")]) - if paragraph is not None and measure.headed(paragraph): - tall = max(tall, measure.label_size(paragraph.get("paraPrIDRef"), runs[-1].get("charPrIDRef"))) - return tall, refs, sizes - return min(sizes or [measure.char_height(ref) for ref in refs]), refs, sizes - - -def _end_size(measure: _Measure, runs: list[Any], sizes: list[int]) -> int: - """The size the paragraph's end gives its last line: an empty run ending a paragraph with text makes that - line as tall as itself when it is larger than the line's text, whatever the lines before it hold (an empty - run before the text does not); 0 when it is no larger than any character.""" - - if not runs or not sizes or any(len(child) or child.tag != f"{HP}t" or child.text for child in runs[-1]): - return 0 - size = measure.char_box(runs[-1].get("charPrIDRef")) - if _run_text(runs).endswith("\n"): # after a line break the empty last line is the run alone: as tall as - return size if size != sizes[-1] else 0 # itself, smaller or larger (see _line_metrics) - return size if size > min(sizes) else 0 - - -def _end_ref(paragraph: Any) -> Any: - """The character shape of a paragraph's end: its last run's, or None without runs.""" - - runs = paragraph.findall(f"{HP}run") - return runs[-1].get("charPrIDRef") if runs else None - - -def _head_size(measure: _Measure, paragraph: Any, sizes: list[int]) -> int: - """The size a bullet or number label (in its own character shape, or without one in that of the - paragraph's end), or a run holding nothing but controls before the text (a section's or columns' - definition, a page number: an empty run takes no room) or an object not set as a character, gives its - paragraph's first line: a character of that size there (it counts when it is larger than the smallest - character); 0 when not.""" - - if not sizes: - return 0 - size = measure.label_size(paragraph.get("paraPrIDRef"), _end_ref(paragraph)) - for run in paragraph.findall(f"{HP}run"): - if any(child.text or len(child) for child in run.findall(f"{HP}t")): # the text starts - break - if run.find(f"{HP}ctrl") is not None or run.find(f"{HP}secPr") is not None or any( - _local(child) in _OBJECTS and (child.find(f"{HP}pos") is None - or child.find(f"{HP}pos").get("treatAsChar") != "1") - for child in run): - size = max(size, measure.char_height(run.get("charPrIDRef"))) - return size if size > min(sizes) else 0 - - -def _held_sizes(measure: _Measure, runs: list[Any], sizes: list[int]) -> dict[int, int]: - """Where in the text a run holding a control shown on a line (see :func:`_shown_control`; not a note) or an - object not set as a character stands after the first character -> that run's size, when it is larger than the - smallest character: Hancom sets it as a character of no width, the line it falls on as tall as its run's - characters (those before the text, see :func:`_head_size`). Each character whose shape draws a border above - or below it is held too, its line as tall as the character and the border (see :meth:`_Measure.char_box`).""" - - if not sizes: - return {} - place, held = 0, {} - for run in runs: - box = measure.char_box(run.get("charPrIDRef")) - boxed = box > measure.char_height(run.get("charPrIDRef")) # a border above or below its characters - for child in run: - name = _local(child) - if name == "t": - for offset in range(len(_t_text(child))) if boxed else (): - held[place + offset + 1] = max(held.get(place + offset + 1, 0), box) - place += len(_t_text(child)) - elif place and (_shown_control(child) and not any(_local(kind) in ("footNote", "endNote") for kind in child) - or name in _OBJECTS and (child.find(f"{HP}pos") is None - or child.find(f"{HP}pos").get("treatAsChar") != "1")): - size = measure.char_height(run.get("charPrIDRef")) - if size > min(sizes): - held[place] = max(held.get(place, 0), size) - return held - - -def _char_styles(measure: _Measure, paragraph: Any, runs: list[Any]) -> list[Any] | None: - """Each character's style from its own run when the runs holding text differ in face, 장평 or 자간; - ``None`` when they do not.""" - - para_pr = paragraph.get("paraPrIDRef") - looks: list[Any] = [] - for run in runs: - length = sum(len(_t_text(text)) for text in run.findall(f"{HP}t")) - if length: - looks += [measure.style(para_pr, [run.get("charPrIDRef")])] * length - return looks if len(set(looks)) > 1 else None - - -def _line_sizes(measure: _Measure, sizes: list[int], style: Any, styles: list[Any] | None, shape: _Shape) -> list[int]: - """Each character's size as its line's height counts it: the size, or in a paragraph taking its line height - from the font (``fontLineHeight``) the height the character's face gives a line of that size.""" - - if not shape.font_line: - return sizes - return [measure.font_line(size, styles[index] if styles else style) for index, size in enumerate(sizes)] - - -def _metric_starts(measure: _Measure, text: str, widths: list[float], sizes: list[int], style: Any, - objects: dict[int, tuple[int, int]], styles: list[Any] | None = None, - marks: dict[int, int] | None = None) -> list[int]: - """Where each line :func:`_line_metrics` lays out starts in *text*.""" - - advances = {**{index: width for index, (width, _) in objects.items()}, **(marks or {})} or None - return measure.line_starts(text, widths, min(sizes), style, sizes if len(set(sizes)) > 1 else None, styles, - advances, set(objects)) - - -def _line_metrics(measure: _Measure, text: str, widths: list[float], sizes: list[int], style: Any, - shape: _Shape, objects: dict[int, tuple[int, int]], styles: list[Any] | None = None, - marks: dict[int, int] | None = None, end: int = 0, head: int = 0, - held: dict[int, int] | None = None) -> tuple[tuple[int, int], ...]: - """(height, advance) of each line FormFit breaks *text* into, every character at its own size: a line - is as tall as its largest character, its line spacing reckoned from that size. An object set as a - character (*objects*: its place in *text* -> its width and height) takes its width on its line and - makes the line at least as tall as itself; its run's size counts for the line spacing alone, not for the - line's height (Hancom: as tall as its characters and objects, spaced from its largest size); a fixed line spacing - keeps the next line that far down. A composed character or ruby text (*marks*: its place -> its - width) is a character of its size in *sizes*. The last line is at least as tall as the paragraph's - end (*end*, see :func:`_end_size`), and the first as its label (*head*, see :func:`_head_size`); a control or - an object not set as a character after the first character (*held*: its place -> its run's size, see - :func:`_held_sizes`) makes the line it falls on as tall as a character of that size. In a - paragraph taking its line height from the font each of them counts as tall as its face makes a line - (:func:`_line_sizes`).""" - - starts = _metric_starts(measure, text, widths, sizes, style, objects, styles, marks) - heights = _line_sizes(measure, sizes, style, styles, shape) - if shape.font_line: - end, head = measure.font_line(end, style), measure.font_line(head, style) - held = {place: measure.font_line(tall, style) for place, tall in (held or {}).items()} - metrics = [] - broken = text.endswith("\n") and starts[-1] == len(text) # an empty last line after a line break - for number, (start, stop) in enumerate(zip(starts, [*starts[1:], len(text)])): - last = number == len(starts) - 1 - span = range(start, stop) if stop > start else range(len(text) - 1, len(text)) - if last and broken and end: # the empty line is the paragraph's end alone - span = range(0) - edges = ([end] if last else []) + ([head] if start == 0 else []) + [tall for place, tall in (held or {}).items() if start < place <= stop] - size = max([heights[index] for index in span] + edges) - glyphs = [heights[index] for index in span if index not in objects] + edges - height = max([max(glyphs) if glyphs else size] + [objects[index][1] for index in span if index in objects]) - advance = _pitch(shape.kind, shape.value, size) - metrics.append((height, advance if shape.kind == "FIXED" else height + advance - size)) - return tuple(metrics) - - -def _drawn_height(obj: Any, measure: _Measure) -> int: - """How tall Hancom draws *obj*: a drawing holding a text box (hp:drawText) as tall as the box's text and - its margins when that is taller than hp:sz -- Hancom grows the drawing to hold them, writing the grown size - to hp:curSz alone (negative for a drawing scaled upside down), at times one less, which makes that a lower - bound within a unit or two; a grown size further off was written for other fonts or text, and Hancom lays the - text out anew. When the text cannot be laid out, the grown size stands. Any other object (a table too) as - hp:sz.""" - - height = int(obj.find(f"{HP}sz").get("height", 0)) - box = obj.find(f"{HP}drawText") - if box is None: - return height - current = obj.find(f"{HP}curSz") - grown = 0 if current is None else int(current.get("height", 0)) - if grown >= 1 << 31: # negative, kept unsigned: as tall upside down - grown = (1 << 32) - grown - if grown >= 1 << 30: - grown = 0 - paragraphs = box.findall(f"{HP}subList/{HP}p") - if not paragraphs: - return max(height, grown) - margin = box.find(f"{HP}textMargin") - left, right, top, bottom = (0, 0, 0, 0) if margin is None else ( - int(margin.get(side, 0)) for side in ("left", "right", "top", "bottom")) - width = int(box.get("lastWidth", 0)) or int(obj.find(f"{HP}sz").get("width", 0)) - try: # its first line below the first paragraph's spacing before, as in a cell - content = measure.shape(paragraphs[0].get("paraPrIDRef")).prev \ - + measure.stack(paragraphs, width - left - right, caches=True)[0] - except _Unsupported: - return max(height, grown) - laid = top + content + bottom - # Hancom lays the box's text out anew: a grown size written for other fonts or text does not hold - return max(height, laid, grown if abs(grown - laid) <= 2 else 0) - - -#: How far each parallel shadow moves from its object before its own offset: Hancom draws a bottom shadow -#: ``offsetY + 600`` down and a top one ``offsetY - 600`` (down positive), whatever the object's size or line. -_SHADOW_DISTANCE = 600 - - -def _shadow_drop(obj: Any) -> int: - """How far the parallel shadow of *obj* (``hp:shadow``) is moved up or down from it: an object set as a - character is that much taller (drawn lower when the shadow goes up). 0 without one; other shadows are not - followed.""" - - shadow = obj.find(f"{HP}shadow") - kind = "" if shadow is None else shadow.get("type", "NONE") - if not kind.startswith(("PARELLEL_", "PARALLEL_")): - return 0 - offset = int(shadow.get("offsetY", 0)) # written as signed text, as Hancom reads it - if not -(1 << 31) <= offset < 1 << 31: - raise _Unsupported("a shadow offset past 32 bits") - return abs(offset + _SHADOW_DISTANCE if kind.endswith("BOTTOM") else offset - _SHADOW_DISTANCE) - - -#: A picture's shadow spreads in whole pixels at 96 per inch (75 HWPUNIT): a radius of 400 spreads as 450. -_SHADOW_BLUR_STEP = 75 - - -def _effect_room(obj: Any, width: int, height: int) -> tuple[int, int, int, int]: - """(left, right, top, bottom): how much farther than its *width* x *height* a picture's effects - (``hp:effects``) reach, which Hancom lays it out with: a glow its ``radius`` on each side, and an outer - shadow the picture (with its glow) moved ``distance`` in its ``direction`` (degrees clockwise on the page - from the right) and spread by its ``radius`` on each side, rounded up to whole pixels (see - :data:`_SHADOW_BLUR_STEP`); each reach is cut to a whole HWPUNIT. An inner shadow and a soft edge take no room. - A reflection reaches below about its ``pos`` share of the picture (with its glow, and a pixel on each side) - less a pixel, and its ``distance``: within about a pixel of Hancom's, the extra not followed.""" - - effects = obj.find(f"{HP}effects") - if effects is None or len(effects) == 0: - return 0, 0, 0, 0 - glow = effects.find(f"{HP}glow") - reach = 0 if glow is None else max(0, int(float(glow.get("radius", 0)))) - left, top, right, bottom = -reach, -reach, width + reach, height + reach - shadow = effects.find(f"{HP}shadow") - if shadow is not None and shadow.get("style", "OUTSIDE") != "INSIDE": - angle = math.radians(float(shadow.get("direction", 0))) - distance, blur = float(shadow.get("distance", 0)), max(0.0, float(shadow.get("radius", 0))) - blur = math.ceil(blur / _SHADOW_BLUR_STEP) * _SHADOW_BLUR_STEP # in whole pixels, as Hancom spreads it - dx, dy = round(distance * math.cos(angle), 9), round(distance * math.sin(angle), 9) # 0 at 90, 180 ... - left, right = min(left, left + dx - blur), max(right, right + dx + blur) - top, bottom = min(top, top + dy - blur), max(bottom, bottom + dy + blur) - room = [math.floor(-left), math.floor(right - width), math.floor(-top), math.floor(bottom - height)] - reflection = effects.find(f"{HP}reflection") - share = None if reflection is None else reflection.find(f"{HP}pos") - size = 0.0 if share is None else float(share.get("end", 0)) - float(share.get("start", 0)) - if reflection is not None and size > 0: # about that much of the picture (with its glow, a pixel round it) - below = (size * (height + 2 * reach + 2 * _SHADOW_BLUR_STEP) - _SHADOW_BLUR_STEP - + max(0.0, float(reflection.get("distance", 0)))) - room[3] = max(room[3], math.floor(below) - room[2]) - return room[0], room[1], room[2], room[3] - - -def _object_extent(obj: Any, measure: _Measure) -> tuple[int, int]: - """(width, height) an object set as a character takes, its outer margins included; a table as tall - as its rows, a drawing with its shadow's move (see :func:`_shadow_drop`), a picture with the room its - effects take (see :func:`_effect_room`). Set as a character, any object's caption takes room as a - table's does: above or below it, its lines and its gap in the height (see :func:`_caption`); beside it, its - width and its gap in the width, the height staying the object's however tall the caption runs.""" - - size = obj.find(f"{HP}sz") - margin = obj.find(f"{HP}outMargin") - extra = (0, 0, 0, 0) if margin is None else tuple(_margin(margin, side) for side in ("left", "right", "top", "bottom")) - tac = obj.find(f"{HP}pos").get("treatAsChar") == "1" - height = _inline_table_height(measure, obj) + sum(_caption(measure, obj)) if _local(obj) == "tbl" \ - else _drawn_height(obj, measure) + (_shadow_drop(obj) if tac else 0) - width = int(size.get("width", 0)) - left, right, top, bottom = _effect_room(obj, width, height) if tac else (0, 0, 0, 0) - if tac and _local(obj) != "tbl": - height += sum(_caption(measure, obj)) - width += _caption_beside(obj) - return width + extra[0] + extra[1] + left + right, height + extra[2] + extra[3] + top + bottom - - -def _caption_beside(obj: Any) -> int: - """How much wider an object set as a character is for its caption beside it: the caption's width and its - gap (none for a caption above or below it).""" - - caption = obj.find(f"{HP}caption") - if caption is None or caption.get("side", "LEFT") not in ("LEFT", "RIGHT"): - return 0 - return int(caption.get("width", 0)) + int(caption.get("gap", 0)) - - -def _inline_content(measure: _Measure, paragraph: Any, runs: list[Any], anchored: Any = None, - placed: tuple[Any, ...] = ()) -> tuple[ - str, list[int], list[Any], dict[int, tuple[int, int]], dict[int, int]]: - """The paragraph's text with each object set as a character, composed character and ruby text in its - place (U+FFFC), each character's size and style (ruby text's is the height of its line), each - object's place -> its width and height, and each composed character's or ruby text's place -> its - width. A control shown on a line (see :func:`_shown_control`) after the first character is an object of no - width as tall as its run's characters (those before it stand on the first line, see :func:`_head_size`). - Objects placed otherwise (but *anchored* and *placed*, laid out apart), and line spacing between - lines or at least with an object among text, are not followed.""" - - shape = measure.shape(paragraph.get("paraPrIDRef")) - text: list[str] = [] - sizes: list[int] = [] - looks: list[Any] = [] - objects: dict[int, tuple[int, int]] = {} - marks: dict[int, int] = {} - for run in runs: - ref = run.get("charPrIDRef") - height, look = measure.char_height(ref), measure.style(paragraph.get("paraPrIDRef"), [ref]) - for child in run: - name = _local(child) - if name in _OBJECTS and (_floating(child) or _on_paper(child) or child is anchored - or any(child is obj for obj in placed)): - continue - if name in _OBJECTS: - if child.find(f"{HP}pos").get("treatAsChar") != "1" or shape.kind not in ("PERCENT", "FIXED"): - raise _Unsupported("an object with text or other objects in its paragraph") - objects[len(text)] = _object_extent(child, measure) - part = "\ufffc" - elif name in _MARKS: - marks[len(text)], tall = _mark_extent(child, height, look) - text.append("\ufffc") - sizes.append(tall) - looks.append(look) - continue - elif name == "t": - part = _t_text(child) - elif text and _shown_control(child): # a character of no width as tall as its run's, on the line it - objects[len(text)] = (0, height) # falls on: an object's that fits, the next past one wider than it - part = "" - else: - continue - text += part - sizes += [height] * len(part) - looks += [look] * len(part) - return "".join(text), sizes, looks, objects, marks - - -def _shown_control(child: Any) -> bool: - """Whether *child* of a run is a control Hancom sets on a line as a character (a page number, a field, a - bookmark and so on -- not a column or section definition).""" - - return _local(child) == "ctrl" and any(_local(kind) not in ("colPr",) for kind in child) - - def _anchored_object(objects: list[Any], text: str, column: int, headed: bool = False) -> Any: """The one object not set as a character of a paragraph of text (a space is text, and so is the bullet or number label of a *headed* paragraph: its line goes below the object; *headed* is also set for an empty @@ -3205,30 +816,6 @@ def wide(index: int) -> bool: return metrics, max((number for number, start in enumerate(starts) if start < place), default=0) -def _anchor_line(measure: _Measure, paragraph: Any, runs: list[Any], text: str, obj: Any, widths: list[float], - size: int, style: Any, cached: tuple[tuple[int, int], ...], count: int) -> int: - """The line *obj*'s place in the text falls on: in a line cache, where Hancom counts every object and - control as eight characters, the last line starting at or before it; otherwise the line holding the - character before it.""" - - place = objects = 0 - for child in (child for run in runs for child in run): - if child is obj: - break - if _local(child) == "t": - place += len(_t_text(child)) - elif _local(child) in _OBJECTS or _local(child) == "ctrl": # every object and control takes eight - objects += 1 - segments = paragraph.findall(f"{HP}linesegarray/{HP}lineseg") if cached else [] - if segments: # lines Hancom laid out (not ones laid out here) - starts = [int(segment.get("textpos", 0)) for segment in segments] - place += 8 * objects # its own place in the cache, before its own eight - else: - starts = measure.line_starts(text, widths, size, style) - return max((index for index, start in enumerate(starts[:count]) if start < place), default=0) - return max((index for index, start in enumerate(starts[:count]) if start <= place), default=0) - - def _anchor(measure: _Measure, paragraph: Any, runs: list[Any], text: str, obj: Any, widths: list[float], size: int, style: Any, cached: tuple[tuple[int, int], ...], count: int, line: int | None = None) -> _Anchor: """Where *obj* stands in the paragraph: at the top of the line its place in the text falls on (*line*).""" @@ -3516,40 +1103,6 @@ def _controls_after_wide(measure: _Measure, runs: list[Any], objects: list[Any], return max(measure.char_height(run.get("charPrIDRef")) for run in beside[2]) -def _extent(obj: Any, side: str, measure: _Measure | None = None) -> int: - """An object's width or height (*side*), its outer margins included; given *measure*, the height as Hancom - draws it (:func:`_drawn_height`).""" - - margin = obj.find(f"{HP}outMargin") - ends = ("left", "right") if side == "width" else ("top", "bottom") - extra = 0 if margin is None else sum(_margin(margin, end) for end in ends) - if side == "height" and measure is not None: - return _drawn_height(obj, measure) + extra - return int(obj.find(f"{HP}sz").get(side, 0)) + extra - - -def _wraps_top_and_bottom(obj: Any, column: int) -> bool: - """Top and bottom, or square with no line's room beside it: an object as wide as the column, or one - placed from the column's or its paragraph's left or right that leaves less than 1440 of it on either - side (the text going to either side, or to the wider), pushes the text below it either way.""" - - wrap = obj.get("textWrap") - if wrap == "TOP_AND_BOTTOM": - return True - width = _extent(obj, "width") - if wrap != "SQUARE" or width >= column: - return wrap == "SQUARE" - pos = obj.find(f"{HP}pos") - if pos is None or pos.get("horzRelTo") not in ("COLUMN", "PARA") or pos.get("horzAlign") not in ("LEFT", "RIGHT") \ - or obj.get("textFlow", "BOTH_SIDES") not in ("BOTH_SIDES", "LARGEST_ONLY"): - return False - offset = _pos_offset(pos, "horzOffset") - if offset >= 1 << 31: # kept unsigned: one placed out past the edge - offset -= 1 << 32 - start = offset if pos.get("horzAlign") == "LEFT" else column - width - offset - return start < _MIN_SIDE and column - start - width < _MIN_SIDE - - def _square_object(objects: list[Any], runs: list[Any], column: int) -> Any: """The one object of a paragraph wrapped square across the column, from the top of the line its control falls on (:func:`_square_anchor_line`), or ``None`` (:func:`_square_sides` says where the text goes beside @@ -3864,47 +1417,6 @@ def _push(para: _Para, band: _Wrap, *, starts: bool) -> tuple[_Para, _Wrap | Non wrap_shift=shifted if starts else 0), rest -def _wrapped_widths(measure: _Measure, text: str, widths: list[float], size: int, style: Any, shape: _Shape, - wrap: _Wrap, sizes: list[int] | None, looks: list[Any] | None) -> tuple[list[float], set[int]]: - """Each FormFit line's width with the lines whose top is in *wrap*'s band cut narrower, or split in two - pieces at one height beside an object with text on both sides, and the FormFit lines that are such a - line's first piece (FormFit breaks the lines, and which lines are in the band follows from their - heights; repeated until it settles).""" - - narrow: set[int] = set() # lines in the band, as the lines Hancom draws - for _ in range(8): - lines: list[float] = [] - firsts: set[int] = set() - for index in range(max(narrow, default=0) + 2): - full = widths[min(index, 1)] - if index in narrow and wrap.column: - pieces = wrap.pieces(full, shape.right) - if len(pieces) > 1: - firsts.add(len(lines)) - lines += pieces - elif index in narrow and wrap.split: - firsts.add(len(lines)) - lines += [wrap.split, full - wrap.cut - wrap.split] - else: - lines.append(full - (wrap.cut if index in narrow else 0)) - starts = measure.line_starts(text, lines, size, style, sizes, looks) - top, found, index, piece = 0, set(), 0, 0 - while piece < len(starts): - pieces = 2 if piece in firsts and piece + 1 < len(starts) else 1 - start, end = starts[piece], starts[piece + pieces] if piece + pieces < len(starts) else len(text) - height = max((sizes or [size])[start:end] or [size]) if sizes else size - if shape.font_line: - height = measure.font_line(height, style) - if top < wrap.bottom and top + height > wrap.top: - found.add(index) - top += _pitch(shape.kind, shape.value, height) - index, piece = index + 1, piece + pieces - if found == narrow: - return lines, firsts - narrow = found - raise _Unsupported("lines beside a square-wrapped object that do not settle") - - def _in_two_pieces(para: _Para) -> _Para: """*para*, one empty line, as Hancom writes it beside an object with text on both sides: two pieces at one height.""" @@ -3912,22 +1424,6 @@ def _in_two_pieces(para: _Para) -> _Para: return replace(para, lines=2, cached=((para.size, 0), (para.size, para.pitch))) -def _at_one_height(metrics: tuple[tuple[int, int], ...], firsts: set[int]) -> tuple[tuple[int, int], ...]: - """*metrics* with each line of two pieces (*firsts*: its first piece) as tall as its taller piece, the - second piece at the first's height. When the text ends in a line's first piece, Hancom writes the second - one empty, at that height.""" - - lines = list(metrics) - for first in sorted(firsts): - if first + 1 < len(lines): - (height, advance), (other, after) = lines[first], lines[first + 1] - lines[first], lines[first + 1] = (max(height, other), 0), (max(height, other), max(advance, after)) - elif first == len(lines) - 1: # the text ends in it: an empty second piece - height, advance = lines[first] - lines[first:] = [(height, 0), (height, advance)] - return tuple(lines) - - def _banded_object_lines(measure: _Measure, text: str, widths: list[float], sizes: list[int], style: Any, shape: _Shape, wrap: _Wrap, objects: dict[int, tuple[int, int]], looks: list[Any] | None, end: int, head: int) -> tuple[tuple[tuple[int, int], ...], int]: @@ -3979,450 +1475,6 @@ def _cached_jumps(paragraph: Any, metrics: tuple[tuple[int, int], ...]) -> tuple return tuple(lines) -# -- laying the paragraphs out --------------------------------------------------------------------- - - -def _lines_of(para: _Para, first: int, count: int, *, prev: int, after: int) -> _Para: - """Lines *first* .. *first* + *count* of *para* as a paragraph of their own.""" - - cached = para.cached[first:first + count] if para.cached else () - return replace(para, lines=count, prev=prev, next=after, cached=cached, notes={}, anchor=None, - keep_next=False if after == 0 else para.keep_next) - - -def _repeated_header(table: _FlowTable) -> int: - return sum(row.height for row in table.rows if row.header) if table.repeat_header else 0 - - -def _spare_cut(table: Any) -> int: - return _SPARE_CUT_FIXED if table.get("noAdjust") == "1" else _SPARE_CUT - - -def _starts_later(table: _FlowTable, y: int, body: int) -> bool: - """Whether a table moved row by row (TABLE) has no room for its first row from *y*, one set not to - split (NONE) no room for all its rows, one split cell by cell (CELL) room for none of its first row's - lines, or one moved row by row or split cell by cell no room for the header rows it repeats, so it starts - on the next page. At the top of a page it is drawn anyway.""" - - if table.mode not in ("TABLE", "NONE", "CELL") or not table.rows: - return False - if _header_moves(table, y, body - table.margins[1]): - return True - if table.mode == "CELL": # its first row goes on whole - top = _repeated_header(table) + table.margins[0] - row = table.rows[0] - return not row.joined and y != top \ - and _flow_row("CELL", row, 0, y, body - table.margins[1], top, table.cut) == (1, top + row.height) - first = sum(row.height for row in table.rows) if table.mode == "NONE" else table.rows[0].height - return y + first > body - table.margins[1] - table.cut \ - and y != _repeated_header(table) + table.margins[0] - - -def _header_moves(table: _FlowTable, y: int, body: int) -> bool: - """Whether a table moved row by row or split cell by cell (TABLE, CELL) has no room from *y* above - *body* for the header rows it repeats on every page: Hancom does not split them, so the table starts on - the next page, the header rows at its top. At a page's top they are drawn anyway.""" - - header = _repeated_header(table) - return table.mode in ("TABLE", "CELL") and bool(header) and y + header > body - table.cut \ - and y > table.margins[0] - - -def _flow_table(table: _FlowTable, frame: int, y: int, body: int) -> tuple[int, int]: - """Lay the rows out from vertical position *y*; the frame and position where the table ends.""" - - body -= table.margins[1] # the rows keep the table's bottom margin above the page end - header = _repeated_header(table) + table.margins[0] # and go on below its top margin on the next page - foot = body - table.cut - # split between cell lines, it keeps the room of a caption below it at the foot of every page it goes on from - room = body - table.caption[1] if table.mode == "CELL" else body - if _header_moves(table, y, body): # its repeated header rows start the next page (drawn there once) - frame, y = frame + 1, table.margins[0] - if table.mode == "NONE": # set not to split: its rows move as one, drawn anyway at a page's top - height = sum(row.height for row in table.rows) - if y + height > foot and y != header: - frame, y = frame + 1, header - return frame, y + height - rows, index = table.rows, 0 - while index < len(rows): - end = index - while rows[end].joined and end + 1 < len(rows): - end += 1 - if table.mode == "TABLE" and end > index: # rows joined by merged cells move as one - height = sum(row.height for row in rows[index:end + 1]) - if y + height > foot and y != header: - if index == 0: - raise _Unsupported("a table whose first rows, merged together, have no room under its anchor") - frame, y = frame + 1, header - if y + height > foot: - raise _Unsupported("rows merged together taller than a page") - y, index = y + height, end + 1 - continue - if table.mode == "CELL" and end > index and table.cells \ - and y + sum(row.height for row in rows[index:end + 1]) > foot: # split cell by cell - frame, y = _split_block(table, index, end, frame, y, room, header) - index = end + 1 - continue - before, start = frame, y - above = index == len(rows) - 1 and table.caption[1] and table.mode == "CELL" and rows[index].spare \ - and not rows[index].nested # a caption below keeps its room: the row's room to spare is cut above it - frame, y = _flow_row(table.mode, rows[index], frame, y, - body - (table.caption[1] if above else 0) if index == len(rows) - 1 else room, header, - table.cut) - if rows[index].merged and frame != before: - raise _Unsupported("a page break among rows merged in a flowing table") - if index == len(rows) - 1 and table.caption[1] and not above and frame == before and start != header \ - and y + table.caption[1] > foot: # a caption below goes on with the last row - frame, y = frame + 1, header + rows[index].height - index += 1 - return frame, y - - -def _split_block(table: _FlowTable, first: int, last: int, frame: int, y: int, body: int, - header: int) -> tuple[int, int]: - """Rows *first*..*last*, joined by merged cells and starting at *y*, in a table split between cell - lines when the page end falls among them: each page keeps the lines that fit, and what is left goes on - below the next page's *header*, split again at that page's end until it fits. The frame and position - where they end.""" - - foot, before = body - table.cut, None - while True: - cut, heights, cells = _block_rest(table, first, last, y, body) - rest = sum(heights.values()) - if not rest: # every cell done above the page end, what it declares below dropped: they end there - return frame, body - if header + rest <= foot: - return frame + 1, header + rest - if before is not None and rest >= before: # nothing of it fits a page - raise _Unsupported("rows merged together taller than a page") - rows = list(table.rows) - for index, height in heights.items(): - rows[index] = replace(rows[index], height=height) - table, first, frame, y, before = replace(table, rows=rows, cells=tuple(cells)), cut, frame + 1, header, rest - - -def _block_rest(table: _FlowTable, first: int, last: int, top: int, - body: int) -> tuple[int, dict[int, int], list[tuple[int, int, _Row]]]: - """What goes on to the next page of rows *first*..*last*, joined by merged cells, when the page end - falls among them in a table split between cell lines: every cell keeps the lines that fit above - the page end and the rest go on. From the row the page end falls in, each row is as tall as the - rest of its cells of one row (the rows after it whole), then each merged cell's rest, the one - ending first first, adds what its rows lack to the last of them. The row the page end falls in, - each row's height from it on, and the cells that go on, each as tall as its rest with the lines - it has left.""" - - rows, tops, y, foot = table.rows, {}, top, body - table.cut - for index in range(first, last + 1): - tops[index] = y - y += rows[index].height - cut = next(index for index in range(first, last + 1) if tops[index] + rows[index].height > foot) - heights = dict.fromkeys(range(cut, last + 1), 0) - rests: list[tuple[int, int, int]] = [] - cells: list[tuple[int, int, _Row]] = [] - # a cell of the row the page end falls in keeping none of its lines above it sends the row's cells on whole - whole = any(_cell_rest(cell, tops[cut], foot) == (cell.height, cell.lines) and cell.lines and not cell.spare - for start, span, cell in table.cells if start == cut and span == 1) - for start, span, cell in table.cells: - end = start + span - 1 - if start < first or start > last or end < cut: - continue # another row, or done above the page end - part = (cell.height, cell.lines) if start > cut or whole and start == cut and span == 1 \ - else _cell_rest(cell, tops[start], foot) - if part is None: - continue - rest, begin = part[0], max(start, cut) - left = part[1] # the lines it has left are its last ones - # Once a line was consumed, a uniform paragraph no longer starts below its original spacing before. - cells.append((begin, end - begin + 1, replace(cell, height=rest, lines=left, **( - {"metrics": cell.metrics[len(cell.metrics) - left:], "leads": cell.leads[len(cell.leads) - left:]} - if _lists_lines(cell) else {"first": cell.size if left < cell.lines else cell.first})))) - if span == 1: - heights[start] = max(heights[start], rest) - else: - rests.append((begin, end, rest)) - for start, end, rest in sorted(rests, key=lambda item: (item[1], item[0])): - lacking = rest - sum(heights[index] for index in range(start, end + 1)) - heights[end] += max(lacking, 0) - return cut, heights, cells - - -def _lists_lines(cell: _Row) -> bool: - """Whether *cell* lists the (height, advance) of each of its lines (``_Row.metrics``): one of several - paragraphs, which may differ in size, holding no table.""" - - return bool(cell.metrics) and len(cell.metrics) == cell.lines and not cell.nested and not cell.pieces - - -def _cell_rest(cell: _Row, top: int, foot: int) -> tuple[int, int] | None: - """How tall the part of a cell starting at *top* that goes on past the page end *foot* is, and how many - lines it holds; ``None`` when nothing of it goes on. Each line takes its own height and advance where the - cell lists them (a line of a larger character size among others), else the cell's.""" - - lines = cell.metrics if _lists_lines(cell) else ((cell.size, cell.pitch),) * cell.lines - # the room above each line when a part of the cell starts with it: its paragraph's spacing before where the - # cell lists its lines, else above its first line what that line takes beyond the character size (its first - # paragraph's spacing before, or a taller first line) - leads = cell.leads if _lists_lines(cell) and len(cell.leads) == cell.lines \ - else (max(cell.first - cell.size, 0),) + (0,) * (cell.lines - 1) if cell.lines else () - fitting, y = 0, top + cell.margins + (leads[0] if leads else 0) - while fitting < cell.lines and y + lines[fitting][0] <= foot: - y += lines[fitting][1] - fitting += 1 - left = lines[fitting:] - height = cell.margins + (leads[fitting] if leads and left else 0) \ - + sum(advance for _, advance in left[:-1]) + left[-1][0] if left else 0 - if cell.spare and (fitting or not cell.lines): # its text (or what is left: none) starts above the page end: - # the declared room is cut like a row's, and the lines that do not fit go on with it, which is then - # at least as tall as they are with the cell's margins - rest = top + cell.height - foot - if left: - return max(rest, height), len(left) - return (rest, 0) if rest > _SPARE_DROPPED else None - if cell.spare: # none of it fits: it goes on whole - return cell.height, cell.lines - if not left: - return None - return height, len(left) - - -def _flow_row(mode: str, row: _Row, frame: int, y: int, body: int, header: int, - cut: int = _SPARE_CUT) -> tuple[int, int]: - """A row that does not fit even a fresh page is drawn there anyway, cut at the paper's edge; - CELL breaks a row between its lines, or a row taller than its text just above the page's foot.""" - - remaining, height, metrics, nested, leads = row.lines, row.height, row.metrics, row.nested, row.leads - cuts, blocks = row.cuts, row.blocks - foot = body - cut - consumed = 0 # how far down the cell's lines the part on this page starts - while True: - if y + height <= foot: - return frame, y + height - fresh = y == header - if mode == "CELL" and row.reaches and row.spare: - raise _Unsupported("a page end in a row declared taller than its text holding a table among its text") - if mode == "CELL" and nested and not row.pieces and row.spare: # declared taller than its text: cut - # like any such row (a row whose tables split goes on below as any cell's) - if y + row.margins + (metrics[0][0] if metrics else row.size) <= foot: # once its first line fits - rest = height - (foot - y) - fitting = _lines_fitting(metrics, leads, y + row.margins, foot) if metrics else 1 - if fitting < len(metrics): # its lines do not all fit: those that do not go on, at least - rest = max(rest, row.margins + _lines_height(metrics[fitting:], leads[fitting:])) - elif rest <= _SPARE_DROPPED: - return frame, body - frame, y, nested = frame + 1, header, False - remaining, height = 1, rest - continue - if fresh: - return frame, y + height - frame, y = frame + 1, header - continue - if mode == "CELL" and nested and not row.pieces: # between its lines, each as tall as it is (a table - # is one) - if not metrics: - if consumed or y + row.margins + row.first <= foot: - raise _Unsupported("a page break in a flowing table row holding a table") - if fresh: # no cell's first line fits (the table one stands on): the row goes on whole - return frame, y + height - frame, y = frame + 1, header - continue - fitting, top = 0, y + row.margins + (leads[0] if leads else 0) # a part starts below its first - # paragraph's spacing before, as any cell's - while fitting < len(metrics) and top + metrics[fitting][0] <= foot: - top += metrics[fitting][1] - fitting += 1 - cut = consumed + sum(advance for _, advance in metrics[:fitting]) # where the line not fitting stands - found = _reached(row, cut, top, foot, metrics[fitting], metrics[fitting + 1] if fitting + 1 < len(metrics) - else None) if row.reaches and fitting < len(metrics) else None - if found is not None: # a table among the text splits or goes on alone: what of it goes on, and that line - piece, consumed = found - metrics = (piece,) + metrics[fitting + 1:] - leads = (0,) + leads[fitting + 1:] if leads else () - height = row.margins + _lines_height(metrics, leads) - frame, y = frame + 1, header - continue - consumed = cut - if fitting == len(metrics): # every line fits, the cell's bottom margin not: cut like a row's - rest = height - (foot - y) - if rest <= _SPARE_DROPPED: - return frame, body - frame, y, nested = frame + 1, header, False - remaining, height, metrics, leads = 1, rest, (), () - continue - if fitting: - metrics, leads = metrics[fitting:], leads[fitting:] - height = row.margins + _lines_height(metrics, leads) - elif fresh: - return frame, y + height - frame, y = frame + 1, header - continue - if mode == "CELL": - lines = metrics or ((row.size, row.pitch),) * remaining - fitting = _lines_fitting(lines, leads, y + row.margins, foot, cuts) - if fitting and len(lines) == row.lines and y + row.margins + row.first > foot: - fitting = 0 # every cell's first line must fit, or the row goes on whole - split = _split_joined(lines, leads, cuts, blocks, fitting, y + row.margins, foot) \ - if blocks and fitting < len(lines) else None - if split is not None: # among a table's rows joined by merged cells: they split cell by cell - metrics, leads, cuts, blocks = split - remaining, height = len(metrics), row.margins + _lines_height(metrics, leads) - frame, y = frame + 1, header - continue - if fitting and (row.spare or fitting == len(lines)): # room under its lines: cut like a row's - rest = height - (foot - y) - if fitting < len(lines) and y + height - row.spare > foot: # its text does not all fit: - rest = max(rest, row.margins + _lines_height(lines[fitting:], leads[fitting:])) # it goes on - elif rest <= _SPARE_DROPPED: - return frame, body - frame, y = frame + 1, header - remaining, height, metrics, leads, cuts, blocks = 1, rest, (), (), (), () - continue - if fitting: - metrics, leads, cuts = lines[fitting:], leads[fitting:], cuts[fitting:] - blocks = tuple((start - fitting, *block) for start, *block in blocks if start >= fitting) - remaining, height = len(metrics), row.margins + _lines_height(metrics, leads) - elif fresh: - return frame, y + height - elif fresh: - return frame, y + height - frame, y = frame + 1, header - - -def _reached(row: _Row, cut: int, top: int, foot: int, line: tuple[int, int], - after: tuple[int, int] | None) -> tuple[tuple[int, int], int] | None: - """Check a page end before the row's *line* (height, advance), which stands *cut* below the top of the - cell's lines (and would stand at *top* on the page), against the tables among its text (see - :class:`_Reach`; *after*: the line after it, if any). Hancom moves such a table on to the next page with the - line its control falls on when that line does not fit and the table would fit (a table that may split: - its rows ending a table's cut, 101, above the foot with room for a caption below it), or would start past - the page's foot. When the first line it pushes below it does not fit and the table would not, the table - splits into its pieces (see :func:`_split_rows`): those so ending (a row going on with room for its bottom - margin too) stay, the rest go on at the next page's top below the table's top margin again (a row going on - below its own top margin again too) and - that line below them. When no piece stays, the table goes on alone to the next page's top (whatever its offset): the line - its control falls on stays where it is, and so does the line it pushes when that is the same, which then - fits, the next line going below the table on the next page (if it does not fit either, the table goes on - with it, as Hancom does from the line's top). Returned then: what of that line goes on, and where it starts - in the cell's lines. A page end through a table or between it and the line it pushes, past a table on this - page reaching the foot (with the cell's margins), before lines that would - fit on this page once the table has gone on alone (Hancom keeps them there, as if the table were not - there), or anything else about a table that may not split (or is not a table pushing the lines below it) - is not followed.""" - - found = None - height, advance = line - for reach in row.reaches: - if reach.line < cut and cut != reach.unit and (cut < reach.foot or top - cut + reach.foot > foot): - raise _Unsupported("a page end through a table among the text of a cell") - start = top + reach.top - cut # where the table would stand on this page - if cut not in (reach.line, reach.unit) or start >= foot or ( - start + reach.above + sum(piece[1] for piece in reach.rows[:-1]) + reach.rows[-1][0] - <= foot - _SPARE_CUT - reach.below - if reach.rows else start + reach.foot - reach.top <= foot): - continue # it fits, or starts past the foot: it goes on with the line - if cut != reach.unit or found is not None: - raise _Unsupported("a page end through a table among the text of a cell") - if not reach.rows: # a table that may not split goes on with the line from the line's top - if start + reach.first <= foot or top + reach.text <= foot or reach.top != cut: - raise _Unsupported("a page end through a table among the text of a cell") - continue - y, kept = start + reach.above, 0 - while kept < len(reach.rows) and y + reach.rows[kept][0] + reach.rows[kept][2] \ - <= foot - _SPARE_CUT - reach.below: - y += reach.rows[kept][1] - kept += 1 - joined = _joined_stays(reach, kept, start, foot) - if joined: # among rows joined by merged cells, split cell by cell: what of them stays, the rest - stays = reach.top - cut + joined - reach.above # going on below the table's top margin again - found = (height - stays, advance - stays), cut + stays - continue - if not kept and reach.line < cut and top + reach.text <= foot: # the lines would fit without it - raise _Unsupported("a page end past a table among the text of a cell going on alone") - if kept or reach.line < cut: # the rest goes on, the line below it - stays = reach.top - cut + (sum(piece[1] for piece in reach.rows[:kept]) # the rest below the table's - - reach.rows[kept][3] if kept else 0) # top margin again - found = (height - stays, advance - stays), cut + stays - elif top + reach.text <= foot: # the line stays, the table goes on alone, the next line below it - if after is not None and top + advance - (reach.foot - cut) + after[0] <= foot: # that one would fit - raise _Unsupported("a page end past a table among the text of a cell going on alone") - tall = reach.foot - reach.top - found = (tall, tall), cut + advance - tall - elif reach.top != cut: - raise _Unsupported("a page end through a table among the text of a cell") - return found - - -def _joined_stays(reach: _Reach, kept: int, start: int, foot: int) -> int: - """How far below its top the part of a table pushing a cell's lines below it (see :func:`_reached`), - standing at *start*, that stays above the page end *foot* reaches when that falls among rows joined by - merged cells (piece *kept* the first not fitting): each of their cells keeps the lines that fit, a table's - cut and the table's bottom margin above *foot* (see :func:`_block_rest`); 0 when it falls elsewhere or - nothing of those rows stays.""" - - for begin, first, last in reach.blocks: - if begin <= kept <= begin + last - first: - break - else: - return 0 - assert reach.table is not None - rows = reach.table.rows - top = reach.above + sum(piece[1] for piece in reach.rows[:begin]) - cut, heights, _ = _block_rest(reach.table, first, last, start + top, foot) - if cut == first and all(heights[index] == rows[index].height for index in range(first, last + 1)): - return 0 - return top + sum(row.height for row in rows[first:last + 1]) - sum(heights.values()) - - -def _split_joined(lines: tuple[tuple[int, int], ...], leads: tuple[int, ...], cuts: tuple[int, ...], - blocks: tuple[tuple[int, _FlowTable, int, int], ...], fitting: int, top: int, - foot: int) -> tuple[tuple[tuple[int, int], ...], tuple[int, ...], tuple[int, ...], - tuple[tuple[int, _FlowTable, int, int], ...]] | None: - """A page end before line *fitting* of a cell's *lines* (from *top* down to *foot*) falling among a table's - rows joined by merged cells (see :attr:`_Row.blocks`): each of their cells keeps the lines that fit above - the page end, a table's cut (101) and the table's bottom margin above *foot* (see :func:`_line_cuts`), the - rest going on (see :func:`_block_rest`). The lines, leads, cuts and blocks of what goes on to the next - page; ``None`` when the page end falls elsewhere or nothing of those rows stays.""" - - for start, table, first, last in blocks: - if start <= fitting <= start + last - first: - break - else: - return None - y = top + (leads[0] if leads else 0) + sum(advance for _, advance in lines[:start]) \ - + (table.above if first == 0 else 0) - cut, heights, _ = _block_rest(replace(table, cut=_SPARE_CUT + table.below), first, last, y, foot) - if cut == first and all(heights[index] == table.rows[index].height for index in range(first, last + 1)): - return None - after = start + last - first + 1 - rest = [(heights[index], heights[index]) for index in range(cut, last + 1)] - kept = [_SPARE_CUT + table.below] * len(rest) - if last == len(table.rows) - 1: # the table's last: its bottom margin, and the spacing after its paragraph - height, advance = lines[after - 1] - rest[-1] = (rest[-1][0] + table.below, rest[-1][0] + table.below + advance - height) - kept[-1] = _SPARE_CUT - return (tuple(rest) + lines[after:], - ((table.margins[0] + _repeated_header(table),) * len(rest) + leads[after:]) if leads else (), - tuple(kept) + cuts[after:], - tuple((other - after + len(rest), *block) for other, *block in blocks if other >= after)) - - -def _lines_fitting(lines: tuple[tuple[int, int], ...], leads: tuple[int, ...], top: int, foot: int, - cuts: tuple[int, ...] = ()) -> int: - """How many of *lines* ((height, advance) each; *leads*: the room above each when it starts a part; *cuts*: - the room each needs below it) fit from *top* above *foot*.""" - - fitting, y = 0, top + (leads[0] if leads else 0) - while fitting < len(lines) and y + lines[fitting][0] + (cuts[fitting] if cuts else 0) <= foot: - y += lines[fitting][1] - fitting += 1 - return fitting - - -def _lines_height(lines: tuple[tuple[int, int], ...], leads: tuple[int, ...]) -> int: - """How tall *lines* are as a part of their cell: the room above the first, then down to the last's foot.""" - - return (leads[0] if leads else 0) + sum(advance for _, advance in lines[:-1]) + lines[-1][0] - - class _Paginator: """Frames (a page's columns, in order) and vertical positions of every line of a section.""" diff --git a/tests/test_distribution_file_sizes.py b/tests/test_distribution_file_sizes.py new file mode 100644 index 00000000..d856123e --- /dev/null +++ b/tests/test_distribution_file_sizes.py @@ -0,0 +1,89 @@ +# SPDX-License-Identifier: Apache-2.0 +"""No file the package ships reaches 256 KiB. + +The Claude plugin carries the released wheel unpacked, and its directory reads at most 256 KiB of one file +(hwpx-plugins ``scripts/vendor_claude_engine.py``, ``MAX_FILE_BYTES``). Two core files passed that in 6.9.0 and +6.10.0 and the plugin's engine stopped at 6.8.0 (hwpx-plugins issue 66); nothing in this repository showed it. + +A file at or over the limit fails. A file over four fifths of it only warns: split it, or move its data out of +the source (as ``form_fit/_glyph_table.json.gz`` was), before it gets there. The plugin directory also reads at +most 512 files, so a split costs a file there: prefer one new module to several. +""" + +from __future__ import annotations + +import subprocess +import sys +import warnings +from pathlib import Path +from zipfile import ZipFile + +import pytest + +ROOT = Path(__file__).resolve().parent.parent +PACKAGE = ROOT / "src" / "hwpx" +#: The most a plugin directory reads of one file. +LIMIT = 256 * 1024 +#: The share of the limit past which a file is reported before it fails. +WARN_SHARE = 0.8 + + +def size_problems(sizes: dict[str, int], limit: int = LIMIT, warn_share: float = WARN_SHARE + ) -> tuple[list[str], list[str]]: + """(files at or over *limit*, files over *warn_share* of it), largest first, each as a line to show.""" + + def line(name: str) -> str: + return f"{name}: {sizes[name]:,} bytes, {sizes[name] / limit:.0%} of {limit:,}" + + largest = sorted(sizes, key=lambda name: (-sizes[name], name)) + over = [line(name) for name in largest if sizes[name] >= limit] + near = [line(name) for name in largest if limit * warn_share < sizes[name] < limit] + return over, near + + +def _check(sizes: dict[str, int], what: str) -> None: + assert sizes, f"no files found in {what}" + over, near = size_problems(sizes) + if near: + warnings.warn( + f"{what}: {len(near)} file(s) over {WARN_SHARE:.0%} of the {LIMIT:,}-byte limit a plugin directory " + "reads of one file; split or move data out before the limit:\n " + "\n ".join(near), + stacklevel=2, + ) + assert not over, ( + f"{what}: file(s) at or over the {LIMIT:,}-byte limit a plugin directory reads of one file " + "(hwpx-plugins issue 66):\n " + "\n ".join(over) + ) + + +def test_no_source_file_of_the_package_reaches_the_limit() -> None: + # As a release build ships them: text with LF line endings, whatever this checkout uses. + sizes = {} + for path in sorted(PACKAGE.rglob("*")): + if not path.is_file() or "__pycache__" in path.parts: + continue + data = path.read_bytes() + sizes[path.relative_to(PACKAGE.parent).as_posix()] = len(data if b"\0" in data else data.replace(b"\r\n", b"\n")) + _check(sizes, "src/hwpx") + + +def test_no_file_of_the_built_wheel_reaches_the_limit(tmp_path: Path) -> None: + pytest.importorskip("build") + subprocess.run([sys.executable, "-m", "build", "--wheel", "--outdir", str(tmp_path)], cwd=ROOT, check=True) + with ZipFile(next(tmp_path.glob("*.whl"))) as wheel: + sizes = {info.filename: info.file_size for info in wheel.infolist() if not info.is_dir()} + assert "hwpx/form_fit/_glyph_table.json.gz" in sizes # the glyph tables ship as data + assert "hwpx/layout/_page_measure.py" in sizes + _check(sizes, "the wheel") + + +def test_the_check_reports_a_file_over_the_limit_and_warns_before_it() -> None: + sizes = {"hwpx/small.py": 10, "hwpx/near.py": 210_000, "hwpx/at.py": LIMIT, "hwpx/over.py": LIMIT + 1, + "hwpx/edge.py": int(LIMIT * WARN_SHARE)} + over, near = size_problems(sizes) + assert [line.split(":")[0] for line in over] == ["hwpx/over.py", "hwpx/at.py"] + assert [line.split(":")[0] for line in near] == ["hwpx/near.py"] + with pytest.warns(UserWarning, match=r"hwpx/near\.py: 210,000 bytes, 80% of 262,144"): + _check({"hwpx/near.py": 210_000}, "test") + with pytest.warns(UserWarning), pytest.raises(AssertionError, match=r"hwpx/over\.py"): + _check(sizes, "test") diff --git a/tests/test_glyph_table_data.py b/tests/test_glyph_table_data.py new file mode 100644 index 00000000..7a4472d9 --- /dev/null +++ b/tests/test_glyph_table_data.py @@ -0,0 +1,58 @@ +# SPDX-License-Identifier: Apache-2.0 +"""The glyph tables the package ships are the readable source's, value for value. + +``hwpx.form_fit._glyph_table`` reads ``_glyph_table.json.gz``; ``scripts/glyph_table_source.py`` is what people +edit and ``scripts/build_glyph_table.py`` writes the one from the other. A table that differs here means the +data file was not rebuilt after an edit: run ``python scripts/build_glyph_table.py``. +""" + +from __future__ import annotations + +import build_glyph_table +import pytest + +from hwpx.form_fit import _glyph_table + +SOURCE = build_glyph_table.load_source() +REBUILD = "run python scripts/build_glyph_table.py" + + +def test_the_module_holds_the_tables_the_source_defines_and_no_others() -> None: + shipped = {name for name in vars(_glyph_table) if name.isupper() and not name.startswith("_")} + assert shipped == set(SOURCE) == set(build_glyph_table.TABLES) + + +@pytest.mark.parametrize("name", list(build_glyph_table.TABLES)) +def test_every_value_of_a_table_is_the_sources(name: str) -> None: + shipped, source = getattr(_glyph_table, name), SOURCE[name] + assert type(shipped) is dict + assert list(shipped) == list(source), f"{name}: faces differ or are in another order; {REBUILD}" + compared = 0 + for face, expected in source.items(): + got = shipped[face] + assert type(got) is type(expected), f"{name}[{face!r}]" + if isinstance(expected, dict): + # Every key and value, in the source's order, with the source's types (an int is not a bool or float). + assert list(got.items()) == list(expected.items()), f"{name}[{face!r}]; {REBUILD}" + assert all(type(k) is int and type(v) is type(expected[k]) for k, v in got.items()), f"{name}[{face!r}]" + compared += len(expected) + else: + assert got == expected, f"{name}[{face!r}]; {REBUILD}" + if isinstance(expected, tuple): + assert [type(item) for item in got] == [type(item) for item in expected], f"{name}[{face!r}]" + compared += 1 + assert compared > 0 + assert shipped == source + + +def test_the_data_file_is_what_the_build_script_writes_from_the_source() -> None: + assert build_glyph_table.stored() == build_glyph_table.encode(SOURCE), REBUILD + assert build_glyph_table.main(["--check"]) == 0 + + +def test_the_build_script_refuses_a_value_the_loader_would_not_give_back(tmp_path) -> None: + for name, face, value in (("UNITS_PER_EM", "바탕", 1024.0), ("VERTICAL_METRICS", "바탕", [879, 145]), + ("ADVANCES", "바탕", {"500": "a"}), ("LINE_HEIGHTS", "바탕", {2600: True})): + broken = {**SOURCE, name: {**SOURCE[name], face: value}} + with pytest.raises(SystemExit): + build_glyph_table.encode(broken) diff --git a/tests/test_layout_pages_split.py b/tests/test_layout_pages_split.py new file mode 100644 index 00000000..3712ee4f --- /dev/null +++ b/tests/test_layout_pages_split.py @@ -0,0 +1,64 @@ +# SPDX-License-Identifier: Apache-2.0 +"""The page estimate is one model in two files, reached through ``hwpx.layout.pages`` as before. + +``layout/pages.py`` passed the size a plugin directory reads of one file, so its lower half lives in +``layout/_page_measure.py`` (see ``tests/test_distribution_file_sizes.py``). The split moves text only. +""" + +from __future__ import annotations + +import ast +import subprocess +import sys +from pathlib import Path + +from hwpx.layout import _page_measure, pages + + +def _defined(module: object) -> list[str]: + """The names *module*'s source defines at its top level (not the ones it imports).""" + + names = [] + for node in ast.parse(Path(module.__file__).read_text(encoding="utf-8")).body: # type: ignore[attr-defined] + if isinstance(node, (ast.FunctionDef, ast.ClassDef)): + names.append(node.name) + elif isinstance(node, ast.Assign): + names.extend(target.id for target in node.targets if isinstance(target, ast.Name)) + elif isinstance(node, ast.AnnAssign) and isinstance(node.target, ast.Name): + names.append(node.target.id) + return names + + +def test_pages_holds_every_name_the_lower_half_defines() -> None: + lower = _defined(_page_measure) + assert len(lower) > 100 + missing = [name for name in lower if getattr(pages, name, None) is not getattr(_page_measure, name)] + assert missing == [], f"add to the import from ._page_measure in layout/pages.py: {missing}" + assert not set(lower) & set(_defined(pages)), "a name is defined in both halves" + + +def test_pages_keeps_the_names_it_imported_before_the_split() -> None: + # Tests and callers reach these as hwpx.layout.pages. (text_style_from_refs, for one). + before = ("Any", "COLUMN_SHARES", "Collection", "HH", "HP", "HwpxOxmlHeader", "_DEFAULT_TAB_STOP", + "_GLYPH_SPACE", "_TYPED_NO_BREAK_SPACE", "_drawn_page_size", "_page_margin", + "_remove_short_paragraph_layout_cache", "_remove_stale_paragraph_layout_cache", "cell_margins_of", + "char_advance", "copy", "dataclass", "etree", "field", "font_line_height", "grid_widths_of", + "hancom_line_starts", "in_char_units", "indented_widths", "margins_doubled", "math", "os", + "paragraph_heading", "paragraph_label", "replace", "text_style_from_refs") + assert [name for name in before if not hasattr(pages, name)] == [] + + +def test_the_public_names_stay_in_pages() -> None: + assert pages.__all__ == ["EstimatedLine", "PageEstimate", "estimate_pages"] + assert {getattr(pages, name).__module__ for name in pages.__all__} == {"hwpx.layout.pages"} + import hwpx + from hwpx import experimental + + assert experimental.estimate_pages is pages.estimate_pages + assert hwpx.PageEstimate is pages.PageEstimate and hwpx.EstimatedLine is pages.EstimatedLine + + +def test_the_lower_half_does_not_refer_to_pages() -> None: + code = ("import sys; import hwpx.layout._page_measure; " + "assert 'hwpx.layout.pages' not in sys.modules, 'the lower half imports pages'") + subprocess.run([sys.executable, "-c", code], check=True) diff --git a/tests/test_product_boundary.py b/tests/test_product_boundary.py index 304dc86f..05f35b26 100644 --- a/tests/test_product_boundary.py +++ b/tests/test_product_boundary.py @@ -326,7 +326,9 @@ def test_real_tree_gate_runs_from_a_gitless_source_copy(tmp_path: Path) -> None: # +1: Markdown subset import (tools/markdown_import.py); genre presets stay in automation. # +1: id-addressed text blocks, budgeted outline and batch text changes # (_document/text_blocks.py), the owner behind doc.text.blocks/outline/apply_changes. - assert report["classifiedFiles"] == 186 + # +1: the lower half of the page estimate (layout/_page_measure.py), out of layout/pages.py so that no + # shipped file passes 256 KiB (tests/test_distribution_file_sizes.py). + assert report["classifiedFiles"] == 187 def test_gitless_cli_reproduces_literal_dynamic_import_failure_without_mutating_source(