diff --git a/.cspell.dict/cpython.txt b/.cspell.dict/cpython.txt index da85c312898..f9aa440edee 100644 --- a/.cspell.dict/cpython.txt +++ b/.cspell.dict/cpython.txt @@ -165,6 +165,7 @@ Nondescriptor noninteger nops noraise +npools nseen NSIGNALS numer @@ -276,5 +277,6 @@ winconsoleio withitem withs worklist +XSETREF xstat XXPRIME diff --git a/.cspell.json b/.cspell.json index 57f7baab3f7..91aa4721cb4 100644 --- a/.cspell.json +++ b/.cspell.json @@ -69,6 +69,7 @@ "emscripten", "excs", "fdigits", + "feff", "flufl", "fnfe", "fsdefault", diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 18ba1b6951f..51c6dd747a8 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,7 +2,10 @@ Thanks for your contribution! --> -- [ ] Closes #xxxx +- [ ] Closes #xxxx + +One of checkbox below must be checked. +- [ ] I did not use AI to write the code of this patch. - [ ] This PR follows our [AI policy](https://github.com/RustPython/.github/blob/main/AI_POLICY.md) ## Summary diff --git a/.github/actions/install-linux-deps/action.yml b/.github/actions/install-linux-deps/action.yml index c2f1b20f2d9..6ce8393ce41 100644 --- a/.github/actions/install-linux-deps/action.yml +++ b/.github/actions/install-linux-deps/action.yml @@ -50,14 +50,26 @@ runs: GCC_AARCH64_LINUX_GNU: ${{ inputs.gcc-aarch64-linux-gnu }} GCC_MINGW_W64_X86_64: ${{ inputs.gcc-mingw-w64-x86-64 }} run: | - if ! sudo apt-get update; then - echo "::warning::apt-get update failed; disabling nonessential Microsoft apt sources and retrying" + # `apt-get update` has no deadline of its own, so a source that takes + # the connection and then stops answering holds the job rather than + # failing it, and the retry below never runs. Bound each attempt and + # give the transports a timeout to fail on. + apt_update() { + sudo timeout 300 apt-get \ + -o Acquire::Retries=3 \ + -o Acquire::http::Timeout=20 \ + -o Acquire::https::Timeout=20 \ + update + } + + if ! apt_update; then + echo "::warning::apt-get update did not finish; disabling nonessential Microsoft apt sources and retrying" for source in /etc/apt/sources.list.d/*microsoft* /etc/apt/sources.list.d/*azure-cli*; do if [ -e "$source" ]; then sudo mv "$source" "$source.disabled" fi done - sudo apt-get update + apt_update fi packages=() diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5a8daae06ef..06da9564e36 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -80,7 +80,10 @@ jobs: if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip:ci') }} env: RUST_BACKTRACE: full - name: Run rust tests + # Named after the matrix entry rather than left to be named for it: a + # generated name lists every value in the entry, so adding or removing one + # renames the check and drops it from the required list. + name: Run rust tests (${{ matrix.os }}) runs-on: ${{ matrix.os }} timeout-minutes: 45 strategy: @@ -165,7 +168,10 @@ jobs: if: runner.os == 'Linux' cargo_check: - name: cargo check + # Named after the matrix entry rather than left to be named for it: a + # generated name lists every value in the entry, so adding or removing one + # renames the check and drops it from the required list. + name: cargo check (${{ matrix.os }}, ${{ matrix.target }}) runs-on: ${{ matrix.os }} needs: - determine_changes @@ -292,7 +298,10 @@ jobs: test_multiprocessing_fork test_multiprocessing_forkserver test_multiprocessing_spawn - name: Run snippets and cpython tests + # Named after the matrix entry rather than left to be named for it: a + # generated name lists every value in the entry, so adding or removing one + # renames the check and drops it from the required list. + name: Run snippets and cpython tests (${{ matrix.os }}) runs-on: ${{ matrix.os }} strategy: matrix: @@ -302,8 +311,7 @@ jobs: - '-u all' - '--timeout 600' - '--dont-add-python-opts' - env_polluting_tests: - - test_set + env_polluting_tests: [] skips: [] timeout: 50 - os: ubuntu-latest @@ -311,8 +319,7 @@ jobs: - '-u all' - '--timeout 600' - '--dont-add-python-opts' - env_polluting_tests: - - test_set + env_polluting_tests: [] skips: [] timeout: 60 - os: windows-2025 @@ -320,8 +327,7 @@ jobs: - '-u all' - '--timeout 600' - '--dont-add-python-opts' - env_polluting_tests: - - test_set + env_polluting_tests: [] skips: [] timeout: 50 fail-fast: false @@ -465,7 +471,10 @@ jobs: run: python -I scripts/whats_left.py ${{ env.CARGO_ARGS }} --features jit clippy: - name: clippy + # Named after the matrix entry rather than left to be named for it: a + # generated name lists every value in the entry, so adding or removing one + # renames the check and drops it from the required list. + name: clippy (${{ matrix.os }}) runs-on: ${{ matrix.os }} needs: - determine_changes @@ -810,10 +819,10 @@ jobs: run: cargo build --profile wasm-release --target wasm32-wasip1 --no-default-features --features freeze-stdlib,stdlib,stdio,importlib,host_env --verbose - name: run snippets run: | - wasmer run --dir "$(pwd)" target/wasm32-wasip1/wasm-release/rustpython.wasm -- "$(pwd)/extra_tests/snippets/stdlib_random.py" - wasmer run --dir "$(pwd)" target/wasm32-wasip1/wasm-release/rustpython.wasm -- "$(pwd)/extra_tests/snippets/stdlib_time.py" + wasmer run --volume "$(pwd)" target/wasm32-wasip1/wasm-release/rustpython.wasm -- "$(pwd)/extra_tests/snippets/stdlib_random.py" + wasmer run --volume "$(pwd)" target/wasm32-wasip1/wasm-release/rustpython.wasm -- "$(pwd)/extra_tests/snippets/stdlib_time.py" - name: run cpython unittest - run: wasmer run --dir "$(pwd)" target/wasm32-wasip1/wasm-release/rustpython.wasm -- "$(pwd)/Lib/test/test_int.py" + run: wasmer run --volume "$(pwd)" target/wasm32-wasip1/wasm-release/rustpython.wasm -- "$(pwd)/Lib/test/test_int.py" cargo_doc: needs: diff --git a/.github/workflows/upgrade-pylib.lock.yml b/.github/workflows/upgrade-pylib.lock.yml index 3ac44585943..045c29e8457 100644 --- a/.github/workflows/upgrade-pylib.lock.yml +++ b/.github/workflows/upgrade-pylib.lock.yml @@ -58,7 +58,7 @@ jobs: comment_repo: "" steps: - name: Setup Scripts - uses: github/gh-aw/actions/setup@53258938b59e0797fefeed05ec0c681514b2a827 # v0.84.3 + uses: github/gh-aw/actions/setup@53843da968225dc56e1590978a7ed6407a8438ac # v0.85.4 with: destination: /opt/gh-aw/actions - name: Check workflow file timestamps @@ -99,7 +99,7 @@ jobs: secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }} steps: - name: Setup Scripts - uses: github/gh-aw/actions/setup@53258938b59e0797fefeed05ec0c681514b2a827 # v0.84.3 + uses: github/gh-aw/actions/setup@53843da968225dc56e1590978a7ed6407a8438ac # v0.85.4 with: destination: /opt/gh-aw/actions - name: Checkout repository @@ -806,7 +806,7 @@ jobs: total_count: ${{ steps.missing_tool.outputs.total_count }} steps: - name: Setup Scripts - uses: github/gh-aw/actions/setup@53258938b59e0797fefeed05ec0c681514b2a827 # v0.84.3 + uses: github/gh-aw/actions/setup@53843da968225dc56e1590978a7ed6407a8438ac # v0.85.4 with: destination: /opt/gh-aw/actions - name: Download agent output artifact @@ -927,7 +927,7 @@ jobs: success: ${{ steps.parse_results.outputs.success }} steps: - name: Setup Scripts - uses: github/gh-aw/actions/setup@53258938b59e0797fefeed05ec0c681514b2a827 # v0.84.3 + uses: github/gh-aw/actions/setup@53843da968225dc56e1590978a7ed6407a8438ac # v0.85.4 with: destination: /opt/gh-aw/actions - name: Download agent artifacts @@ -1039,7 +1039,7 @@ jobs: process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} steps: - name: Setup Scripts - uses: github/gh-aw/actions/setup@53258938b59e0797fefeed05ec0c681514b2a827 # v0.84.3 + uses: github/gh-aw/actions/setup@53843da968225dc56e1590978a7ed6407a8438ac # v0.85.4 with: destination: /opt/gh-aw/actions - name: Download agent output artifact diff --git a/Lib/_pycodecs.py b/Lib/_pycodecs.py index 98dec3c614d..2c043f0ec76 100644 --- a/Lib/_pycodecs.py +++ b/Lib/_pycodecs.py @@ -1102,20 +1102,6 @@ def unicodeescape_string(s, size, quotes): pos += 1 continue # endif - # /* Map UTF-16 surrogate pairs to Unicode \UXXXXXXXX escapes */ - elif ord(ch) >= 0xD800 and ord(ch) < 0xDC00: - pos += 1 - ch2 = s[pos] - - if ord(ch2) >= 0xDC00 and ord(ch2) <= 0xDFFF: - ucs = (((ord(ch) & 0x03FF) << 10) | (ord(ch2) & 0x03FF)) + 0x00010000 - p.append(b"\\U%08x" % ucs) - pos += 1 - continue - - # /* Fall through: isolated surrogates are copied as-is */ - pos -= 1 - # /* Map 16-bit characters to '\uxxxx' */ if ord(ch) >= 256: p.append(b"\\u%04x" % ord(ch)) diff --git a/Lib/_pydatetime.py b/Lib/_pydatetime.py index 70251dbb653..0f95a575084 100644 --- a/Lib/_pydatetime.py +++ b/Lib/_pydatetime.py @@ -55,7 +55,7 @@ def _days_before_year(year): def _days_in_month(year, month): "year, month -> number of days in that month in that year." - assert 1 <= month <= 12, month + assert 1 <= month <= 12, f"month must be in 1..12, not {month}" if month == 2 and _is_leap(year): return 29 return _DAYS_IN_MONTH[month] @@ -272,12 +272,12 @@ def _wrap_strftime(object, format, timetuple): newformat.append(Zreplace) # Note that datetime(1000, 1, 1).strftime('%G') == '1000' so # year 1000 for %G can go on the fast path. - elif ((ch in 'YG' or ch in 'FC') and - object.year < 1000 and _need_normalize_century()): + elif (ch in 'YGFC' and timetuple[0] < 1000 and + _need_normalize_century()): if ch == 'G': year = int(_time.strftime("%G", timetuple)) else: - year = object.year + year = timetuple[0] if ch == 'C': push('{:02}'.format(year // 100)) else: @@ -358,7 +358,8 @@ def _find_isoformat_datetime_separator(dtstr): def _parse_isoformat_date(dtstr): # It is assumed that this is an ASCII-only string of lengths 7, 8 or 10, # see the comment on Modules/_datetimemodule.c:_find_isoformat_datetime_separator - assert len(dtstr) in (7, 8, 10) + if len(dtstr) not in (7, 8, 10): + raise ValueError("Invalid isoformat string") year = int(dtstr[0:4]) has_sep = dtstr[4] == '-' @@ -1947,7 +1948,7 @@ def fromisoformat(cls, date_string): if became_next_day: year, month, day = date_components # Only wrap day/month when it was previously valid - if month <= 12 and day <= (days_in_month := _days_in_month(year, month)): + if 1 <= month <= 12 and day <= (days_in_month := _days_in_month(year, month)): # Calculate midnight of the next day day += 1 if day > days_in_month: diff --git a/Lib/_pyio.py b/Lib/_pyio.py index d0adef08e84..cc336d29394 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -1904,7 +1904,7 @@ def truncate(self, pos=None): """Truncate size to pos, where pos is an int.""" self._unsupported("truncate") - def readline(self): + def readline(self, size=-1, /): """Read until newline or EOF. Returns an empty string if EOF is hit immediately. diff --git a/Lib/argparse.py b/Lib/argparse.py index 24f4740562d..a106a718a99 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -1829,6 +1829,9 @@ def _prog_name(prog=None): if modspec is None: # simple script return _os.path.basename(arg0) + if modspec.name != '__main__' and arg0 != modspec.origin: + # named module executed as main without altering sys.argv[0] + return _os.path.basename(arg0) py = _os.path.basename(_sys.executable) if modspec.name != '__main__': # imported module or package diff --git a/Lib/base64.py b/Lib/base64.py index 775ceab0ec0..0f84420d7a2 100644 --- a/Lib/base64.py +++ b/Lib/base64.py @@ -1,4 +1,4 @@ -"""Base16, Base32, Base64 (RFC 3548), Base85 and Ascii85 data encodings""" +"""Base16, Base32, Base64 (RFC 4648), Base85 and Ascii85 data encodings""" # Modified 04-Oct-1995 by Jack Jansen to use binascii module # Modified 30-Dec-2003 by Barry Warsaw to add full RFC 3548 support @@ -147,7 +147,7 @@ def urlsafe_b64decode(s): characters present in the input. ''' _B32_DECODE_MAP01_DOCSTRING = ''' -RFC 3548 allows for optional mapping of the digit 0 (zero) to the +RFC 4648 allows for optional mapping of the digit 0 (zero) to the letter O (oh), and for optional mapping of the digit 1 (one) to either the letter I (eye) or letter L (el). The optional argument map01 when not None, specifies which letter the digit 1 should be @@ -261,7 +261,7 @@ def b32hexdecode(s, casefold=False): extra_args='') -# RFC 3548, Base 16 Alphabet specifies uppercase, but hexlify() returns +# RFC 4648, Base 16 Alphabet specifies uppercase, but hexlify() returns # lowercase. The RFC also recommends against accepting input case # insensitively. def b16encode(s): diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 803de0c6792..0aeca1ed7e5 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -553,6 +553,9 @@ class Counter(dict): or multiset. Elements are stored as dictionary keys and their counts are stored as dictionary values. + When constructed from a Mapping or Counter, the original object's + values will be used as the initial counts. + >>> c = Counter('abcdeabcdabcaba') # count elements from a string >>> c.most_common(3) # three most common elements diff --git a/Lib/configparser.py b/Lib/configparser.py index a53ac872764..3c452afe8ad 100644 --- a/Lib/configparser.py +++ b/Lib/configparser.py @@ -992,7 +992,9 @@ def _write_section(self, fp, section_name, section_items, delimiter, unnamed=Fal value = self._interpolation.before_write(self, section_name, key, value) if value is not None or not self._allow_no_value: - value = delimiter + str(value).replace('\n', '\n\t') + # Convert all possible line-endings into '\n\t' + value = (delimiter + str(value).replace('\r\n', '\n') + .replace('\r', '\n').replace('\n', '\n\t')) else: value = "" fp.write("{}{}\n".format(key, value)) diff --git a/Lib/csv.py b/Lib/csv.py index 0a627ba7a51..5d15344ea24 100644 --- a/Lib/csv.py +++ b/Lib/csv.py @@ -243,8 +243,14 @@ def __init__(self): def sniff(self, sample, delimiters=None): """ Returns a dialect (or None) corresponding to the sample + + If several delimiters fit the sample equally well, the + delimiters listed in the preferred attribute are preferred, in + that order, no matter how many times each of them occurs. """ + sample = sample.replace('\r\n', '\n').replace('\r', '\n') + quotechar, doublequote, delimiter, skipinitialspace = \ self._guess_quote_and_delimiter(sample, delimiters) if not delimiter: @@ -282,12 +288,16 @@ def _guess_quote_and_delimiter(self, data, delimiters): """ import re + # The body of a quoted field ends at the first quote which is + # not doubled, as it does for a reader. A lazy ".*?" scans to + # the end of the sample instead, from every start: quadratically. + body = r'(?:(?P=quote){2}|(?!(?P=quote)).)*+' matches = [] - for restr in (r'(?P[^\w\n"\'])(?P ?)(?P["\']).*?(?P=quote)(?P=delim)', # ,".*?", - r'(?:^|\n)(?P["\']).*?(?P=quote)(?P[^\w\n"\'])(?P ?)', # ".*?", - r'(?P[^\w\n"\'])(?P ?)(?P["\']).*?(?P=quote)(?:$|\n)', # ,".*?" - r'(?:^|\n)(?P["\']).*?(?P=quote)(?:$|\n)'): # ".*?" (no delim, no space) - regexp = re.compile(restr, re.DOTALL | re.MULTILINE) + for restr in (r'(?P[^\w\n"\'])(?P ?)(?P["\'])%s(?P=quote)(?P=delim)', # ,"...", + r'(?:^|\n)(?P["\'])%s(?P=quote)(?P[^\w\n"\'])(?P ?)', # "...", + r'(?P[^\w\n"\'])(?P ?)(?P["\'])%s(?P=quote)(?:$|\n)', # ,"..." + r'(?:^|\n)(?P["\'])%s(?P=quote)(?:$|\n)'): # "..." (no delim, no space) + regexp = re.compile(restr % body, re.DOTALL | re.MULTILINE) matches = regexp.findall(data) if matches: break @@ -330,18 +340,22 @@ def _guess_quote_and_delimiter(self, data, delimiters): delim = '' skipinitialspace = 0 - # if we see an extra quote between delimiters, we've got a - # double quoted format - dq_regexp = re.compile( - r"((%(delim)s)|^)\W*%(quote)s[^%(delim)s\n]*%(quote)s[^%(delim)s\n]*%(quote)s\W*((%(delim)s)|$)" % \ - {'delim':re.escape(delim), 'quote':quotechar}, re.MULTILINE) - - - - if dq_regexp.search(data): - doublequote = True - else: - doublequote = False + # A doubled quote character inside a quoted field means + # a double quoted format. Match whole fields, so that a match + # cannot slide across field boundaries. + doublequote = False + if delim: + dq_regexp = re.compile( + r"(?:(?<=%(delim)s)|^)%(space)s%(quote)s" # ," + r"((?:%(quote)s%(quote)s|[^%(quote)s]++)*+)" # the body + r"%(quote)s(?:%(delim)s|$)" # ", + % {'delim': re.escape(delim), 'quote': quotechar, + # Skipping spaces after a space rescans them. + 'space': ' *+' if delim != ' ' else ''}, + re.MULTILINE) + dquotechar = quotechar * 2 + doublequote = any(dquotechar in m[1] + for m in dq_regexp.finditer(data)) return (quotechar, doublequote, delim, skipinitialspace) diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index f9c1113b1e3..242a6d2ffc2 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -1247,6 +1247,7 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, # classes with slots. These could be slightly more performant if we generated # the code instead of iterating over fields. But that can be a project for # another day, if performance becomes an issue. + def _dataclass_getstate(self): return [getattr(self, f.name) for f in fields(self)] diff --git a/Lib/difflib.py b/Lib/difflib.py index ac1ba4a6e4e..aef2b6f0fd8 100644 --- a/Lib/difflib.py +++ b/Lib/difflib.py @@ -1977,6 +1977,8 @@ def make_table(self,fromlines,tolines,fromdesc='',todesc='',context=False, # change tabs to spaces before it gets more difficult after we insert # markup + # it also removes trailing newlines, causing some diffs to be missed + # see: gh-71896 fromlines,tolines = self._tab_newline_replace(fromlines,tolines) # create diffs iterator which generates side by side from/to data diff --git a/Lib/email/utils.py b/Lib/email/utils.py index 3de1f0d24a1..5838a808568 100644 --- a/Lib/email/utils.py +++ b/Lib/email/utils.py @@ -317,10 +317,13 @@ def parsedate_to_datetime(data): if parsed_date_tz is None: raise ValueError('Invalid date value or format "%s"' % str(data)) *dtuple, tz = parsed_date_tz - if tz is None: - return datetime.datetime(*dtuple[:6]) - return datetime.datetime(*dtuple[:6], - tzinfo=datetime.timezone(datetime.timedelta(seconds=tz))) + try: + if tz is None: + return datetime.datetime(*dtuple[:6]) + return datetime.datetime(*dtuple[:6], + tzinfo=datetime.timezone(datetime.timedelta(seconds=tz))) + except OverflowError as exc: + raise ValueError('Invalid date value or format "%s"' % str(data)) from exc def parseaddr(addr, *, strict=True): diff --git a/Lib/glob.py b/Lib/glob.py index f8be46771b4..173272ba38f 100644 --- a/Lib/glob.py +++ b/Lib/glob.py @@ -34,8 +34,8 @@ def glob(pathname, *, root_dir=None, dir_fd=None, recursive=False, If `dir_fd` is not None, it should be a file descriptor referring to a directory, and paths will then be relative to that directory. - If `include_hidden` is true, the patterns '*', '?', '**' will match - hidden directories. + If `include_hidden` is true, wildcards can match path segments beginning + with a dot ('.'). If `recursive` is true, the pattern '**' will match any files and zero or more directories and subdirectories. @@ -64,8 +64,8 @@ def iglob(pathname, *, root_dir=None, dir_fd=None, recursive=False, If `dir_fd` is not None, it should be a file descriptor referring to a directory, and paths will then be relative to that directory. - If `include_hidden` is true, the patterns '*', '?', '**' will match - hidden directories. + If `include_hidden` is true, wildcards can match path segments beginning + with a dot ('.'). If `recursive` is true, the pattern '**' will match any files and zero or more directories and subdirectories. diff --git a/Lib/html/parser.py b/Lib/html/parser.py index 80fb8c3f929..fbe0d3665e0 100644 --- a/Lib/html/parser.py +++ b/Lib/html/parser.py @@ -157,6 +157,9 @@ def reset(self): self.cdata_elem = None self._support_cdata = True self._escapable = True + self._pending = [] + self._pending_len = 0 + self._parse_threshold = 1 super().reset() def feed(self, data): @@ -165,11 +168,36 @@ def feed(self, data): Call this as often as you want, with as little or as much text as you want (may include '\n'). """ - self.rawdata = self.rawdata + data - self.goahead(0) + # Accumulate new data in a list and only join and parse it once + # enough has piled up. Rescanning an unparsed buffer (e.g. an + # unterminated tag) and concatenating onto it on every call would + # both be quadratic in the input size. + self._pending_len += len(data) + if self._pending_len < self._parse_threshold: + self._pending.append(data) + else: + if not self._pending: + self.rawdata += data + else: + self._pending.append(data) + self.rawdata += ''.join(self._pending) + self._pending.clear() + self._pending_len = 0 + n = len(self.rawdata) + self.goahead(0) + if len(self.rawdata) < n: + # Some data was parsed; resume on the next call. + self._parse_threshold = 1 + else: + # Nothing was parsed; wait until the buffer doubles. + self._parse_threshold = len(self.rawdata) def close(self): """Handle any buffered data.""" + if self._pending: + self.rawdata += ''.join(self._pending) + self._pending.clear() + self._pending_len = 0 self.goahead(1) __starttag_text = None @@ -387,9 +415,11 @@ def parse_html_declaration(self, i): def parse_comment(self, i, report=True): rawdata = self.rawdata assert rawdata.startswith('" or "--!>" close. + match = commentabruptclose.match(rawdata, i+4) if not match: - match = commentabruptclose.match(rawdata, i+4) + match = commentclose.search(rawdata, i+4) if not match: return -1 if report: diff --git a/Lib/inspect.py b/Lib/inspect.py index d3e406cae7d..cf61ae943b1 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -196,18 +196,18 @@ def ispackage(object): def ismethoddescriptor(object): """Return true if the object is a method descriptor. - But not if ismethod() or isclass() or isfunction() are true. + But not if ismethod(), isclass() or isfunction() is true. - This is new in Python 2.2, and, for example, is true of int.__add__. - An object passing this test has a __get__ attribute, but not a - __set__ attribute or a __delete__ attribute. Beyond that, the set - of attributes varies; __name__ is usually sensible, and __doc__ - often is. + An object passing this test (for example, int.__add__) has a __get__ + attribute, but not a __set__ attribute or a __delete__ attribute. + Beyond that, the set of attributes varies; __name__ is usually + sensible, and __doc__ often is. Methods implemented via descriptors that also pass one of the other - tests return false from the ismethoddescriptor() test, simply because - the other tests promise more -- you can, e.g., count on having the - __func__ attribute (etc) when an object passes ismethod().""" + tests (ismethod(), isclass(), isfunction()) make this function return + false, simply because those other tests promise more -- you can, for + example, count on having the __func__ attribute when an object passes + ismethod().""" if isclass(object) or ismethod(object) or isfunction(object): # mutual exclusion return False @@ -219,8 +219,13 @@ def ismethoddescriptor(object): def isdatadescriptor(object): """Return true if the object is a data descriptor. + But not if ismethod(), isclass() or isfunction() is true. + Data descriptors have a __set__ or a __delete__ attribute. Examples are - properties (defined in Python) and getsets and members (defined in C). + properties, getsets, and members. For the latter two (defined only in C + extension modules) more specific tests are available as well: + isgetsetdescriptor() and ismemberdescriptor(), respectively. + Typically, data descriptors will also have __name__ and __doc__ attributes (properties, getsets, and members have both of these attributes), but this is not guaranteed.""" @@ -2712,6 +2717,10 @@ def __init__(self, name, kind, *, default=_empty, annotation=_empty): raise ValueError(msg) self._kind = _POSITIONAL_ONLY name = 'implicit{}'.format(name[1:]) + elif name == '.format': + # gh-151665: Hidden parameter of compiler-generated annotation and type + # alias/typevar evaluators. Show it as "format". + name = 'format' # It's possible for C functions to have a positional-only parameter # where the name is a keyword, so for compatibility we'll allow it. diff --git a/Lib/json/decoder.py b/Lib/json/decoder.py index db87724a897..04e000e0760 100644 --- a/Lib/json/decoder.py +++ b/Lib/json/decoder.py @@ -111,7 +111,7 @@ def py_scanstring(s, end, strict=True, if strict: #msg = "Invalid control character %r at" % (terminator,) msg = "Invalid control character {0!r} at".format(terminator) - raise JSONDecodeError(msg, s, end) + raise JSONDecodeError(msg, s, end - 1) else: _append(terminator) continue diff --git a/Lib/locale.py b/Lib/locale.py index 498af087354..6984a6a5e2b 100644 --- a/Lib/locale.py +++ b/Lib/locale.py @@ -545,12 +545,6 @@ def getdefaultlocale(envvars=('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE')): """ - import warnings - warnings._deprecated( - "locale.getdefaultlocale", - "{name!r} is deprecated and slated for removal in Python {remove}. " - "Use setlocale(), getencoding() and getlocale() instead.", - remove=(3, 15)) return _getdefaultlocale(envvars) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 7d0f4c1fd40..e7581d2ae0a 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -244,7 +244,7 @@ def read(self, filename, strict=True): list of standard types, else to the list of non-standard types. """ - with open(filename, encoding='utf-8') as fp: + with open(filename, encoding='utf-8', errors='surrogateescape') as fp: self.readfp(fp, strict) def readfp(self, fp, strict=True): @@ -435,7 +435,7 @@ def init(files=None): def read_mime_types(file): try: - f = open(file, encoding='utf-8') + f = open(file, encoding='utf-8', errors='surrogateescape') except OSError: return None with f: diff --git a/Lib/ntpath.py b/Lib/ntpath.py index eb127ec2632..36da5b7cb0f 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -345,7 +345,7 @@ def _isreservedname(name): def expanduser(path): """Expand ~ and ~user constructs. - If user or $HOME is unknown, do nothing.""" + If user or home directory is unknown, do nothing.""" path = os.fspath(path) if isinstance(path, bytes): seps = b'\\/' diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 1f8a6ef3d7c..091f8af01b2 100644 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -1876,6 +1876,7 @@ class Helper: 'async': ('async', ''), 'await': ('await', ''), 'break': ('break', 'while for'), + 'case': 'match', 'class': ('class', 'CLASSES SPECIALMETHODS'), 'continue': ('continue', 'while for'), 'def': ('function', ''), @@ -1887,11 +1888,12 @@ class Helper: 'for': ('for', 'break continue while'), 'from': 'import', 'global': ('global', 'nonlocal NAMESPACES'), - 'if': ('if', 'TRUTHVALUE'), + 'if': ('if', 'TRUTHVALUE match'), 'import': ('import', 'MODULES'), 'in': ('in', 'SEQUENCEMETHODS'), 'is': 'COMPARISON', 'lambda': ('lambda', 'FUNCTIONS'), + 'match': ('match', 'if'), 'nonlocal': ('nonlocal', 'global NAMESPACES'), 'not': 'BOOLEAN', 'or': 'BOOLEAN', diff --git a/Lib/pydoc_data/module_docs.py b/Lib/pydoc_data/module_docs.py index 69b9046f49f..2d3543f2983 100644 --- a/Lib/pydoc_data/module_docs.py +++ b/Lib/pydoc_data/module_docs.py @@ -1,4 +1,4 @@ -# Autogenerated by Sphinx on Wed Jun 10 13:03:46 2026 +# Autogenerated by Sphinx on Wed Aug 5 13:29:41 2026 # as part of the release process. module_docs = { @@ -251,6 +251,7 @@ 'tkinter': 'tkinter#module-tkinter', 'tkinter.colorchooser': 'tkinter.colorchooser#module-tkinter.colorchooser', 'tkinter.commondialog': 'dialog#module-tkinter.commondialog', + 'tkinter.dialog': 'dialog#module-tkinter.dialog', 'tkinter.dnd': 'tkinter.dnd#module-tkinter.dnd', 'tkinter.filedialog': 'dialog#module-tkinter.filedialog', 'tkinter.font': 'tkinter.font#module-tkinter.font', diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 05d283c9540..753d9d43069 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,4 +1,4 @@ -# Autogenerated by Sphinx on Wed Jun 10 13:03:46 2026 +# Autogenerated by Sphinx on Wed Aug 5 13:29:41 2026 # as part of the release process. topics = { @@ -125,7 +125,7 @@ class Cls: inst.x = inst.x + 1 # writes inst.x as 4 leaving Cls.x as 3 This description does not necessarily apply to descriptor - attributes, such as properties created with "property()". + attributes, such as properties created with "@property". * If the target is a subscription: The primary expression in the reference is evaluated. Next, the subscript expression is evaluated. @@ -854,7 +854,7 @@ class to a new value, *value*. instances to acquire behaviors that differ from other instances of the same class. -The "property()" function is implemented as a data descriptor. +The "@property" decorator is implemented as a data descriptor. Accordingly, instances cannot override the behavior of a property. @@ -1683,7 +1683,7 @@ class attributes; they are shared by instances. Instance attributes The last two expressions apply to totally ordered collections (e.g. to sequences, but not to sets or mappings). See also the - "total_ordering()" decorator. + "@~functools.total_ordering" decorator. * The "hash()" result should be consistent with equality. Objects that are equal should either have the same hash value, or be marked as @@ -1946,12 +1946,12 @@ class attributes; they are shared by instances. Instance attributes handler, the outer handler will not handle the exception.) When an exception has been assigned using "as target", it is cleared -at the end of the "except" clause. This is as if +at the end of the "except" clause. This is as if: except E as N: foo -was translated to +was translated to: except E as N: try: @@ -1999,8 +1999,8 @@ class attributes; they are shared by instances. Instance attributes type for matching is mandatory in the case of "except*", so "except*:" is a syntax error. The type is interpreted as in the case of "except", but matching is performed on the exceptions contained in the group -that is being handled. An "TypeError" is raised if a matching type is -a subclass of "BaseExceptionGroup", because that would have ambiguous +that is being handled. A "TypeError" is raised if a matching type is a +subclass of "BaseExceptionGroup", because that would have ambiguous semantics. When an exception group is raised in the try block, each "except*" @@ -2015,7 +2015,7 @@ class attributes; they are shared by instances. Instance attributes After all "except*" clauses execute, the group of unhandled exceptions is merged with any exceptions that were raised or re-raised from -within "except*" clauses. This merged exception group propagates on.: +within "except*" clauses. This merged exception group propagates on: >>> try: ... raise ExceptionGroup("eg", @@ -2899,7 +2899,7 @@ def func(): pass by appending an item to a list), the default parameter value is in effect modified. This is generally not what was intended. A way around this is to use "None" as the default, and explicitly test for -it in the body of the function, e.g.: +it in the body of the function, for example: def whats_on_the_telly(penguin=None): if penguin is None: @@ -3434,7 +3434,7 @@ def f() -> annotation: ... arbitrary expressions. The presence of annotations does not change the runtime semantics of the code, except if some mechanism is used that introspects and uses the annotations (such as "dataclasses" or -"functools.singledispatch()"). +"@functools.singledispatch"). By default, annotations are lazily evaluated in an annotation scope. This means that they are not evaluated when the code containing the @@ -3786,7 +3786,7 @@ def f() -> annotation: ... operators or default implementations; for example, the truth of "(x(parameters): from left to right and placed into the list object in that order. When a comprehension is supplied, the list is constructed from the elements resulting from the comprehension. +''', + 'match': r'''The "match" statement +********************* + +Added in version 3.10. + +The match statement is used for pattern matching. Syntax: + + match_stmt: 'match' subject_expr ":" NEWLINE INDENT case_block+ DEDENT + subject_expr: flexible_expression "," [flexible_expression_list [',']] + | assignment_expression + case_block: 'case' patterns [guard] ":" suite + +Note: + + This section uses single quotes to denote soft keywords. + +Pattern matching takes a pattern as input (following "case") and a +subject value (following "match"). The pattern (which may contain +subpatterns) is matched against the subject value. The outcomes are: + +* A match success or failure (also termed a pattern success or + failure). + +* Possible binding of matched values to a name. The prerequisites for + this are further discussed below. + +The "match" and "case" keywords are soft keywords. + +See also: + + * **PEP 634** – Structural Pattern Matching: Specification + + * **PEP 636** – Structural Pattern Matching: Tutorial + + +Overview +======== + +Here’s an overview of the logical flow of a match statement: + +1. The subject expression "subject_expr" is evaluated and a resulting + subject value obtained. If the subject expression contains a comma, + a tuple is constructed using the standard rules. + +2. Each pattern in a "case_block" is attempted to match with the + subject value. The specific rules for success or failure are + described below. The match attempt can also bind some or all of the + standalone names within the pattern. The precise pattern binding + rules vary per pattern type and are specified below. **Name + bindings made during a successful pattern match outlive the + executed block and can be used after the match statement**. + + Note: + + During failed pattern matches, some subpatterns may succeed. Do + not rely on bindings being made for a failed match. Conversely, + do not rely on variables remaining unchanged after a failed + match. The exact behavior is dependent on implementation and may + vary. This is an intentional decision made to allow different + implementations to add optimizations. + +3. If the pattern succeeds, the corresponding guard (if present) is + evaluated. In this case all name bindings are guaranteed to have + happened. + + * If the guard evaluates as true or is missing, the "block" inside + "case_block" is executed. + + * Otherwise, the next "case_block" is attempted as described above. + + * If there are no further case blocks, the match statement is + completed. + +Note: + + Users should generally never rely on a pattern being evaluated. + Depending on implementation, the interpreter may cache values or use + other optimizations which skip repeated evaluations. + +A sample match statement: + + >>> flag = False + >>> match (100, 200): + ... case (100, 300): # Mismatch: 200 != 300 + ... print('Case 1') + ... case (100, 200) if flag: # Successful match, but guard fails + ... print('Case 2') + ... case (100, y): # Matches and binds y to 200 + ... print(f'Case 3, y: {y}') + ... case _: # Pattern not attempted + ... print('Case 4, I match anything!') + ... + Case 3, y: 200 + +In this case, "if flag" is a guard. Read more about that in the next +section. + + +Guards +====== + + guard: "if" assignment_expression + +A "guard" (which is part of the "case") must succeed for code inside +the "case" block to execute. It takes the form: "if" followed by an +expression. + +The logical flow of a "case" block with a "guard" follows: + +1. Check that the pattern in the "case" block succeeded. If the + pattern failed, the "guard" is not evaluated and the next "case" + block is checked. + +2. If the pattern succeeded, evaluate the "guard". + + * If the "guard" condition evaluates as true, the case block is + selected. + + * If the "guard" condition evaluates as false, the case block is + not selected. + + * If the "guard" raises an exception during evaluation, the + exception bubbles up. + +Guards are allowed to have side effects as they are expressions. +Guard evaluation must proceed from the first to the last case block, +one at a time, skipping case blocks whose pattern(s) don’t all +succeed. (I.e., guard evaluation must happen in order.) Guard +evaluation must stop once a case block is selected. + + +Irrefutable Case Blocks +======================= + +An irrefutable case block is a match-all case block. A match +statement may have at most one irrefutable case block, and it must be +last. + +A case block is considered irrefutable if it has no guard and its +pattern is irrefutable. A pattern is considered irrefutable if we can +prove from its syntax alone that it will always succeed. Only the +following patterns are irrefutable: + +* AS Patterns whose left-hand side is irrefutable + +* OR Patterns containing at least one irrefutable pattern + +* Capture Patterns + +* Wildcard Patterns + +* parenthesized irrefutable patterns + + +Patterns +======== + +Note: + + This section uses grammar notations beyond standard EBNF: + + * the notation "SEP.RULE+" is shorthand for "RULE (SEP RULE)*" + + * the notation "!RULE" is shorthand for a negative lookahead + assertion + +The top-level syntax for "patterns" is: + + patterns: open_sequence_pattern | pattern + pattern: as_pattern | or_pattern + closed_pattern: | literal_pattern + | capture_pattern + | wildcard_pattern + | value_pattern + | group_pattern + | sequence_pattern + | mapping_pattern + | class_pattern + +The descriptions below will include a description “in simple terms” of +what a pattern does for illustration purposes (credits to Raymond +Hettinger for a document that inspired most of the descriptions). Note +that these descriptions are purely for illustration purposes and **may +not** reflect the underlying implementation. Furthermore, they do not +cover all valid forms. + + +OR Patterns +----------- + +An OR pattern is two or more patterns separated by vertical bars "|". +Syntax: + + or_pattern: "|".closed_pattern+ + +Only the final subpattern may be irrefutable, and each subpattern must +bind the same set of names to avoid ambiguity. + +An OR pattern matches each of its subpatterns in turn to the subject +value, until one succeeds. The OR pattern is then considered +successful. Otherwise, if none of the subpatterns succeed, the OR +pattern fails. + +In simple terms, "P1 | P2 | ..." will try to match "P1", if it fails +it will try to match "P2", succeeding immediately if any succeeds, +failing otherwise. + + +AS Patterns +----------- + +An AS pattern matches an OR pattern on the left of the "as" keyword +against a subject. Syntax: + + as_pattern: or_pattern "as" capture_pattern + +If the OR pattern fails, the AS pattern fails. Otherwise, the AS +pattern binds the subject to the name on the right of the as keyword +and succeeds. "capture_pattern" cannot be a "_". + +In simple terms "P as NAME" will match with "P", and on success it +will set "NAME = ". + + +Literal Patterns +---------------- + +A literal pattern corresponds to most literals in Python. Syntax: + + literal_pattern: signed_number + | signed_number "+" NUMBER + | signed_number "-" NUMBER + | strings + | "None" + | "True" + | "False" + signed_number: ["-"] NUMBER + +The rule "strings" and the token "NUMBER" are defined in the standard +Python grammar. Triple-quoted strings are supported. Raw strings and +byte strings are supported. f-strings and t-strings are not +supported. + +The forms "signed_number '+' NUMBER" and "signed_number '-' NUMBER" +are for expressing complex numbers; they require a real number on the +left and an imaginary number on the right. E.g. "3 + 4j". + +In simple terms, "LITERAL" will succeed only if " == +LITERAL". For the singletons "None", "True" and "False", the "is" +operator is used. + + +Capture Patterns +---------------- + +A capture pattern binds the subject value to a name. Syntax: + + capture_pattern: !'_' NAME + +A single underscore "_" is not a capture pattern (this is what "!'_'" +expresses). It is instead treated as a "wildcard_pattern". + +In a given pattern, a given name can only be bound once. E.g. "case +x, x: ..." is invalid while "case [x] | x: ..." is allowed. + +Capture patterns always succeed. The binding follows scoping rules +established by the assignment expression operator in **PEP 572**; the +name becomes a local variable in the closest containing function scope +unless there’s an applicable "global" or "nonlocal" statement. + +In simple terms "NAME" will always succeed and it will set "NAME = +". + + +Wildcard Patterns +----------------- + +A wildcard pattern always succeeds (matches anything) and binds no +name. Syntax: + + wildcard_pattern: '_' + +"_" is a soft keyword within any pattern, but only within patterns. +It is an identifier, as usual, even within "match" subject +expressions, "guard"s, and "case" blocks. + +In simple terms, "_" will always succeed. + + +Value Patterns +-------------- + +A value pattern represents a named value in Python. Syntax: + + value_pattern: attr + attr: name_or_attr "." NAME + name_or_attr: attr | NAME + +The dotted name in the pattern is looked up using standard Python name +resolution rules. The pattern succeeds if the value found compares +equal to the subject value (using the "==" equality operator). + +In simple terms "NAME1.NAME2" will succeed only if " == +NAME1.NAME2" + +Note: + + If the same value occurs multiple times in the same match statement, + the interpreter may cache the first value found and reuse it rather + than repeat the same lookup. This cache is strictly tied to a given + execution of a given match statement. + + +Group Patterns +-------------- + +A group pattern allows users to add parentheses around patterns to +emphasize the intended grouping. Otherwise, it has no additional +syntax. Syntax: + + group_pattern: "(" pattern ")" + +In simple terms "(P)" has the same effect as "P". + + +Sequence Patterns +----------------- + +A sequence pattern contains several subpatterns to be matched against +sequence elements. The syntax is similar to the unpacking of a list or +tuple. + + sequence_pattern: "[" [maybe_sequence_pattern] "]" + | "(" [open_sequence_pattern] ")" + open_sequence_pattern: maybe_star_pattern "," [maybe_sequence_pattern] + maybe_sequence_pattern: ",".maybe_star_pattern+ ","? + maybe_star_pattern: star_pattern | pattern + star_pattern: "*" (capture_pattern | wildcard_pattern) + +There is no difference if parentheses or square brackets are used for +sequence patterns (i.e. "(...)" vs "[...]" ). + +Note: + + A single pattern enclosed in parentheses without a trailing comma + (e.g. "(3 | 4)") is a group pattern. While a single pattern enclosed + in square brackets (e.g. "[3 | 4]") is still a sequence pattern. + +At most one star subpattern may be in a sequence pattern. The star +subpattern may occur in any position. If no star subpattern is +present, the sequence pattern is a fixed-length sequence pattern; +otherwise it is a variable-length sequence pattern. + +The following is the logical flow for matching a sequence pattern +against a subject value: + +1. If the subject value is not a sequence [2], the sequence pattern + fails. + +2. If the subject value is an instance of "str", "bytes" or + "bytearray" the sequence pattern fails. + +3. The subsequent steps depend on whether the sequence pattern is + fixed or variable-length. + + If the sequence pattern is fixed-length: + + 1. If the length of the subject sequence is not equal to the number + of subpatterns, the sequence pattern fails + + 2. Subpatterns in the sequence pattern are matched to their + corresponding items in the subject sequence from left to right. + Matching stops as soon as a subpattern fails. If all + subpatterns succeed in matching their corresponding item, the + sequence pattern succeeds. + + Otherwise, if the sequence pattern is variable-length: + + 1. If the length of the subject sequence is less than the number of + non-star subpatterns, the sequence pattern fails. + + 2. The leading non-star subpatterns are matched to their + corresponding items as for fixed-length sequences. + + 3. If the previous step succeeds, the star subpattern matches a + list formed of the remaining subject items, excluding the + remaining items corresponding to non-star subpatterns following + the star subpattern. + + 4. Remaining non-star subpatterns are matched to their + corresponding subject items, as for a fixed-length sequence. + + Note: + + The length of the subject sequence is obtained via "len()" (i.e. + via the "__len__()" protocol). This length may be cached by the + interpreter in a similar manner as value patterns. + +In simple terms "[P1, P2, P3," … ", P]" matches only if all the +following happens: + +* check "" is a sequence + +* "len(subject) == " + +* "P1" matches "[0]" (note that this match can also bind + names) + +* "P2" matches "[1]" (note that this match can also bind + names) + +* … and so on for the corresponding pattern/element. + + +Mapping Patterns +---------------- + +A mapping pattern contains one or more key-value patterns. The syntax +is similar to the construction of a dictionary. Syntax: + + mapping_pattern: "{" [items_pattern] "}" + items_pattern: ",".key_value_pattern+ ","? + key_value_pattern: (literal_pattern | value_pattern) ":" pattern + | double_star_pattern + double_star_pattern: "**" capture_pattern + +At most one double star pattern may be in a mapping pattern. The +double star pattern must be the last subpattern in the mapping +pattern. + +Duplicate keys in mapping patterns are disallowed. Duplicate literal +keys will raise a "SyntaxError". Two keys that otherwise have the same +value will raise a "ValueError" at runtime. + +The following is the logical flow for matching a mapping pattern +against a subject value: + +1. If the subject value is not a mapping [3],the mapping pattern + fails. + +2. If every key given in the mapping pattern is present in the subject + mapping, and the pattern for each key matches the corresponding + item of the subject mapping, the mapping pattern succeeds. + +3. If duplicate keys are detected in the mapping pattern, the pattern + is considered invalid. A "SyntaxError" is raised for duplicate + literal values; or a "ValueError" for named keys of the same value. + +Note: + + Key-value pairs are matched using the two-argument form of the + mapping subject’s "get()" method. Matched key-value pairs must + already be present in the mapping, and not created on-the-fly via + "__missing__()" or "__getitem__()". + +In simple terms "{KEY1: P1, KEY2: P2, ... }" matches only if all the +following happens: + +* check "" is a mapping + +* "KEY1 in " + +* "P1" matches "[KEY1]" + +* … and so on for the corresponding KEY/pattern pair. + + +Class Patterns +-------------- + +A class pattern represents a class and its positional and keyword +arguments (if any). Syntax: + + class_pattern: name_or_attr "(" [pattern_arguments ","?] ")" + pattern_arguments: positional_patterns ["," keyword_patterns] + | keyword_patterns + positional_patterns: ",".pattern+ + keyword_patterns: ",".keyword_pattern+ + keyword_pattern: NAME "=" pattern + +The same keyword should not be repeated in class patterns. + +The following is the logical flow for matching a class pattern against +a subject value: + +1. If "name_or_attr" is not an instance of the builtin "type" , raise + "TypeError". + +2. If the subject value is not an instance of "name_or_attr" (tested + via "isinstance()"), the class pattern fails. + +3. If no pattern arguments are present, the pattern succeeds. + Otherwise, the subsequent steps depend on whether keyword or + positional argument patterns are present. + + For a number of built-in types (specified below), a single + positional subpattern is accepted which will match the entire + subject; for these types keyword patterns also work as for other + types. + + If only keyword patterns are present, they are processed as + follows, one by one: + + 1. The keyword is looked up as an attribute on the subject. + + * If this raises an exception other than "AttributeError", the + exception bubbles up. + + * If this raises "AttributeError", the class pattern has failed. + + * Else, the subpattern associated with the keyword pattern is + matched against the subject’s attribute value. If this fails, + the class pattern fails; if this succeeds, the match proceeds + to the next keyword. + + 2. If all keyword patterns succeed, the class pattern succeeds. + + If any positional patterns are present, they are converted to + keyword patterns using the "__match_args__" attribute on the class + "name_or_attr" before matching: + + 1. The equivalent of "getattr(cls, "__match_args__", ())" is + called. + + * If this raises an exception, the exception bubbles up. + + * If the returned value is not a tuple, the conversion fails and + "TypeError" is raised. + + * If there are more positional patterns than + "len(cls.__match_args__)", "TypeError" is raised. + + * Otherwise, positional pattern "i" is converted to a keyword + pattern using "__match_args__[i]" as the keyword. + "__match_args__[i]" must be a string; if not "TypeError" is + raised. + + * If there are duplicate keywords, "TypeError" is raised. + + See also: + + Customizing positional arguments in class pattern matching + + 2. Once all positional patterns have been converted to keyword + patterns, the match proceeds as if there were only keyword + patterns. + + For the following built-in types the handling of positional + subpatterns is different: + + * "bool" + + * "bytearray" + + * "bytes" + + * "dict" + + * "float" + + * "frozenset" + + * "int" + + * "list" + + * "set" + + * "str" + + * "tuple" + + These classes accept a single positional argument, and the pattern + there is matched against the whole object rather than an attribute. + For example "int(0|1)" matches the value "0", but not the value + "0.0". + +In simple terms "CLS(P1, attr=P2)" matches only if the following +happens: + +* "isinstance(, CLS)" + +* convert "P1" to a keyword pattern using "CLS.__match_args__" + +* For each keyword argument "attr=P2": + + * "hasattr(, "attr")" + + * "P2" matches ".attr" + +* … and so on for the corresponding keyword argument/pattern pair. + +See also: + + * **PEP 634** – Structural Pattern Matching: Specification + + * **PEP 636** – Structural Pattern Matching: Tutorial ''', 'naming': r'''Naming and binding ****************** @@ -8426,7 +9024,7 @@ class C: pass # a class with no methods (yet) operators or default implementations; for example, the truth of "(x>> try: ... raise ExceptionGroup("eg", diff --git a/Lib/random.py b/Lib/random.py index 726a71e7828..0e6a183d179 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -861,7 +861,11 @@ def binomialvariate(self, n=1, p=0.5): u = random() u -= 0.5 us = 0.5 - _fabs(u) - k = _floor((2.0 * a / us + b) * u + c) + try: + k = _floor((2.0 * a / us + b) * u + c) + except ZeroDivisionError: + # Reject case where random() returned 0.0 + continue if k < 0 or k > n: continue v = random() diff --git a/Lib/test/_isolated_sample.py b/Lib/test/_isolated_sample.py new file mode 100644 index 00000000000..c89f7145e73 --- /dev/null +++ b/Lib/test/_isolated_sample.py @@ -0,0 +1,143 @@ +"""Sample tests driven by test.test_support.TestIsolated. + +This module is imported, never run as a test file, so that +:func:`test.support.isolation.runInSubprocess` has a real, importable target to run in +a subprocess. Several of these tests fail, error or are skipped on purpose. +""" + +import atexit +import os +import time +import unittest +from test.support import isolation + +# DurationSample sleeps this long in the subprocess; a parent-reported duration +# close to it proves the subprocess timing was forwarded, not the replay time. +DURATION_SLEEP = 0.2 + + +class MethodSample(unittest.TestCase): + + @isolation.runInSubprocess() + def test_pass(self): + self.assertTrue(isolation.runningInSubprocess) + + @isolation.runInSubprocess() + def test_fail(self): + self.assertEqual(1, 2) + + @isolation.runInSubprocess() + def test_error(self): + raise RuntimeError('boom') + + @isolation.runInSubprocess() + def test_skip(self): + self.skipTest('nope') + + @isolation.runInSubprocess() + @unittest.expectedFailure + def test_expected_failure(self): + self.assertEqual(1, 2) + + @isolation.runInSubprocess() + @unittest.expectedFailure + def test_unexpected_success(self): + pass + + +@isolation.runInSubprocess() +class ClassSample(unittest.TestCase): + + def test_pass(self): + self.assertTrue(isolation.runningInSubprocess) + + def test_fail(self): + self.assertEqual(1, 2) + + @unittest.expectedFailure + def test_expected_failure(self): + self.assertEqual(1, 2) + + +class SubtestSample(unittest.TestCase): + + @isolation.runInSubprocess() + def test_subtests(self): + for i in range(3): + with self.subTest(i=i): + self.assertNotEqual(i, 1) + + +@isolation.runInSubprocess() +class DurationSample(unittest.TestCase): + + def test_slow(self): + time.sleep(DURATION_SLEEP) + + +@isolation.runInSubprocess() +class SubclassingSample(unittest.TestCase): + # setUpClass must run bound to the runtime class, so a subclass sees its own + # name here rather than the base class's. + + @classmethod + def setUpClass(cls): + cls.setup_class_name = cls.__name__ + + def setUp(self): + self.set_up = True + + def test_runtime_class(self): + self.assertEqual(self.setup_class_name, type(self).__name__) + + +class SubclassSample(SubclassingSample): + # What a subclass adds or overrides must run in the subprocess too. + + def setUp(self): + super().setUp() + self.set_up_in_subclass = True + + def test_added_in_subclass(self): + self.assertTrue(isolation.runningInSubprocess) + self.assertTrue(self.set_up) + self.assertTrue(self.set_up_in_subclass) + + +class BrokenSubclassSample(SubclassingSample): + # An overriding setUpClass() that does not call super() bypasses the + # subprocess entirely. + + @classmethod + def setUpClass(cls): + pass + + +# The exit code the samples below die with, after their tests have run. +EXIT_CODE = 3 + + +def _die_at_exit(): + atexit.register(os._exit, EXIT_CODE) + + +class MethodExitSample(unittest.TestCase): + + @isolation.runInSubprocess() + def test_passes_then_dies(self): + _die_at_exit() + + @isolation.runInSubprocess() + def test_fails_and_dies(self): + _die_at_exit() + self.fail('the test itself failed') + + +@isolation.runInSubprocess() +class ClassExitSample(unittest.TestCase): + + def test_pass(self): + pass + + def test_dies(self): + _die_at_exit() diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index c1bb6138a1b..1b71b71c544 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -3581,6 +3581,11 @@ def test_fromisoformat_fails_datetime(self): '2009-04-19T12:30:45.400 +02:30', # Space between ms and timezone (gh-130959) '2009-04-19T12:30:45.400 ', # Trailing space (gh-130959) '2009-04-19T12:30:45. 400', # Space before fraction (gh-130959) + '2020-2020', # Ambiguous 9-char date portion + '2009-04-19T12:30:45.+05:00', # Empty fraction before offset + '2009-04-19T12:30:45.-05:00', # Empty fraction before offset + '2009-04-19T12:30:45.Z', # Empty fraction before Z + '2009-04-19T12:30:45,+05:00', # Empty fraction (comma) before offset ] for bad_str in bad_strs: @@ -3597,6 +3602,7 @@ def test_fromisoformat_fails_datetime_valueerror(self): "2009-04-01T12:30:90", # Second out of range "2009-04-01T12:90:45", # Minute out of range "2009-04-01T25:30:45", # Hour out of range + "2009-00-01T24:00:00", # Month below range "2009-13-01T24:00:00", # Month out of range "9999-12-31T24:00:00", # Year out of range ] @@ -3625,6 +3631,32 @@ def test_fromisoformat_utc(self): self.assertIs(dt.tzinfo, timezone.utc) + def test_fromisoformat_utc_subsecond_offset(self): + # A UTC offset whose whole-second part is zero but with a non-zero + # microsecond part must be preserved, not collapsed to UTC. + for us in (1, -1, 999999, -999999): + with self.subTest(microseconds=us): + tz = timezone(timedelta(microseconds=us)) + dt = self.theclass(2020, 6, 15, 12, 34, 56, tzinfo=tz) + rt = self.theclass.fromisoformat(dt.isoformat()) + self.assertEqual(rt.utcoffset(), timedelta(microseconds=us)) + self.assertEqual(rt, dt) + self.assertIsNot(rt.tzinfo, timezone.utc) + + tz = timezone(timedelta(hours=5, minutes=30, seconds=15, + microseconds=123456)) + dt = self.theclass(2020, 6, 15, 12, 34, 56, tzinfo=tz) + rt = self.theclass.fromisoformat(dt.isoformat()) + self.assertEqual(rt.utcoffset(), tz.utcoffset(None)) + self.assertEqual(rt, dt) + + for tstr in ('2020-06-15T12:34:56+00:00', + '2020-06-15T12:34:56+00:00:00.000000', + '2020-06-15T12:34:56Z'): + with self.subTest(tstr=tstr): + self.assertIs(self.theclass.fromisoformat(tstr).tzinfo, + timezone.utc) + def test_fromisoformat_subclass(self): class DateTimeSubclass(self.theclass): pass @@ -3908,6 +3940,11 @@ def test_strftime_special(self): self.assertEqual(t.strftime('\0'*1000), '\0'*1000) self.assertEqual(t.strftime('\0%I%p%Z\0%X'), f'\0{s1}\0{s2}') self.assertEqual(t.strftime('%I%p%Z\0%X\0'), f'{s1}\0{s2}\0') + # gh-152305: the year directives must not raise on a time. + for directive, expected in (('%Y', '1900'), ('%G', '1900'), + ('%C', '19'), ('%F', '1900-01-01')): + with self.subTest(directive=directive): + self.assertEqual(t.strftime(directive), expected) def test_format(self): t = self.theclass(1, 2, 3, 4) @@ -4805,6 +4842,10 @@ def test_fromisoformat_fails(self): '12:30:45.400 +02:30', # Space between ms and timezone (gh-130959) '12:30:45.400 ', # Trailing space (gh-130959) '12:30:45. 400', # Space before fraction (gh-130959) + '12:30:45.+05:00', # Empty fraction before offset + '12:30:45.-05:00', # Empty fraction before offset + '12:30:45.Z', # Empty fraction before Z + '12:30:45,+05:00', # Empty fraction (comma) before offset ] for bad_str in bad_strs: diff --git a/Lib/test/mime.types b/Lib/test/mime.types index 68724430c8a..eb39a17b6bf 100644 --- a/Lib/test/mime.types +++ b/Lib/test/mime.types @@ -1,11 +1,11 @@ # This is a comment. I love comments. -*- indent-tabs-mode: t -*- -# This file controls what Internet media types are sent to the client for +# This file controls what internet media types are sent to the client for # given file extension(s). Sending the correct media type to the client # is important so they know how to handle the content of the file. # Extra types can either be added here or by using an AddType directive -# in your config files. For more information about Internet media types, -# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type +# in your config files. For more information about internet media types, +# please read RFC 2045, 2046, 2047, 2048, and 2077. The internet media type # registry is at . # IANA types diff --git a/Lib/test/mime.types2 b/Lib/test/mime.types2 new file mode 100644 index 00000000000..b05c318d1c0 --- /dev/null +++ b/Lib/test/mime.types2 @@ -0,0 +1,3 @@ +# MIME type Extensions +testing/test2 test test2 +testing/test3 test test3 diff --git a/Lib/test/seq_tests.py b/Lib/test/seq_tests.py index e8834c2bafc..b7875fe8f2f 100644 --- a/Lib/test/seq_tests.py +++ b/Lib/test/seq_tests.py @@ -439,7 +439,6 @@ def test_pickle(self): self.assertEqual(lst2, lst) self.assertNotEqual(id(lst2), id(lst)) - @unittest.skip("TODO: RUSTPYTHON; hangs") def test_free_after_iterating(self): support.check_free_after_iterating(self, iter, self.type2test) support.check_free_after_iterating(self, reversed, self.type2test) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 701d34bba2d..504a0ffb401 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -35,7 +35,7 @@ "requires_gil_enabled", "requires_linux_version", "requires_mac_ver", "check_syntax_error", "requires_gzip", "requires_bz2", "requires_lzma", "requires_zstd", - "bigmemtest", "bigaddrspacetest", "cpython_only", "get_attribute", + "bigmemtest", "nomemtest", "bigaddrspacetest", "cpython_only", "get_attribute", "requires_IEEE_754", "requires_zlib", "has_fork_support", "requires_fork", "has_subprocess_support", "requires_subprocess", @@ -44,7 +44,8 @@ "check__all__", "skip_if_buggy_ucrt_strfptime", "check_disallow_instantiation", "check_sanitizer", "skip_if_sanitizer", "requires_limited_api", "requires_specialization", "thread_unsafe", - "skip_if_unlimited_stack_size", + "skip_if_unlimited_stack_size", "skip_if_huge_c_stack", + "run_with_limited_c_stack", # sys "MS_WINDOWS", "is_jython", "is_android", "is_emscripten", "is_wasi", "is_apple_mobile", "check_impl_detail", "unix_shell", "setswitchinterval", @@ -1226,6 +1227,22 @@ def wrapper(self): return wrapper return decorator +def nomemtest(f): + """Check that we can use this test with `_testcapi.set_nomemory`.""" + from .import_helper import import_module + + @functools.wraps(f) + def internal(*args, **kwargs): + import_module('_testcapi') + return f(*args, **kwargs) + + return unittest.skipIf( + # Python built with Py_TRACE_REFS fail with a fatal error in + # _PyRefchain_Trace() on memory allocation error. + Py_TRACE_REFS, + 'cannot test Py_TRACE_REFS build', + )(cpython_only(internal)) + def bigaddrspacetest(f): """Decorator for tests that fill the address space.""" def wrapper(self): @@ -2727,6 +2744,96 @@ def exceeds_recursion_limit(): return 150_000 +def _has_huge_c_stack(depth): + """Check that *depth* recursive calls cannot exhaust the C stack.""" + try: + from _testinternalcapi import get_c_recursion_remaining + except ImportError: + # Fall back to checking for an unlimited stack size. + if is_emscripten or is_wasi or os.name == "nt": + return False + import resource + soft, hard = resource.getrlimit(resource.RLIMIT_STACK) + return soft == hard and soft in (-1, 0xFFFF_FFFF_FFFF_FFFF) + else: + remaining = get_c_recursion_remaining() + # A negative value means integer overflow in the estimate + # (e.g. with an unlimited RLIMIT_STACK). The estimate is based on + # the size of the interpreter loop frame, so it is only a lower + # bound for recursion with smaller C frames. + return remaining >= depth or remaining < 0 + + +def skip_if_huge_c_stack(depth=150_000): + """Skip decorator for tests which cannot overflow the C stack. + + Tests exhausting the C stack with *depth* recursive calls cannot + trigger the recursion protection if the C stack is too large (e.g. + with a large or unlimited RLIMIT_STACK), and either fail, or run + for a very long time, or crash, or consume all memory. + + Prefer run_with_limited_c_stack() for tests recursing to a fixed depth. + """ + return unittest.skipIf( + _has_huge_c_stack(depth), + f"the C stack is large enough for {depth} recursive calls") + + +# Small enough to be exhausted by tens of thousands of recursive calls, +# but not smaller than Py_C_STACK_SIZE (4 MiB) which the interpreter +# assumes if it cannot query the thread stack size. +C_STACK_SIZE = 8 * 1024 * 1024 + + +def run_with_limited_c_stack(depth=150_000, size=C_STACK_SIZE): + """Decorator for tests exhausting the C stack with *depth* recursive calls. + + Run the test in a separate thread with the C stack of *size* bytes, so + that the outcome does not depend on the C stack size of the main thread + (which can be large or unlimited, see RLIMIT_STACK). + + If a thread with the limited C stack cannot be created, run the test in + the current thread, but skip it if the C stack is too large. + """ + reason = f"the C stack is large enough for {depth} recursive calls" + def decorator(test): + @functools.wraps(test) + def wrapper(*args, **kwargs): + def run_test(): + # The C stack can still be too large if limiting it failed. + if _has_huge_c_stack(depth): + raise unittest.SkipTest(reason) + test(*args, **kwargs) + + try: + import threading + old_size = threading.stack_size(size) + except (ImportError, ValueError, RuntimeError): + # Setting the thread stack size is not supported. + return run_test() + + exceptions = [] + def run(): + try: + run_test() + except BaseException as exc: + exceptions.append(exc) + + thread = threading.Thread(target=run) + try: + thread.start() + except RuntimeError: + # Threads are not supported. + return run_test() + finally: + threading.stack_size(old_size) + thread.join() + if exceptions: + raise exceptions[0] + return wrapper + return decorator + + # Windows doesn't have os.uname() but it doesn't support s390x. is_s390x = hasattr(os, 'uname') and os.uname().machine == 's390x' skip_on_s390x = unittest.skipIf(is_s390x, 'skipped on s390x') @@ -3073,7 +3180,7 @@ def in_systemd_nspawn_sync_suppressed() -> bool: with open("/run/systemd/container", "rb") as fp: if fp.read().rstrip() != b"systemd-nspawn": return False - except FileNotFoundError: + except (FileNotFoundError, PermissionError): return False # If systemd-nspawn is used, O_SYNC flag will immediately diff --git a/Lib/test/support/isolation.py b/Lib/test/support/isolation.py new file mode 100644 index 00000000000..bc2189329c0 --- /dev/null +++ b/Lib/test/support/isolation.py @@ -0,0 +1,309 @@ +"""Run tests in isolated subprocesses (the test.support.isolation.runInSubprocess decorator). + +A failure, error or skip that happens in the subprocess is replayed in the +parent process so that the test runner records it. The original (subprocess) +traceback is attached as the cause of the replayed exception, the same way +:mod:`concurrent.futures` surfaces tracebacks from worker processes. +""" + +import functools +import os +import sys +import unittest + +# Let unittest strip this module's frames from tracebacks, so only the original +# subprocess traceback (attached as the cause) is shown, not the replay frames. +__unittest = True + +# test.support globals set by regrtest (libregrtest/setup.py) that affect how +# tests run and which are skipped at runtime in the subprocess. +_PROPAGATED_CONFIG = ( + 'use_resources', # -u (is_resource_enabled/requires) + 'max_memuse', 'real_max_memuse', # -M (bigmemtest) + 'verbose', # -v + 'failfast', # -f +) + +def _child_config(): + import test.support as support + return {name: getattr(support, name) for name in _PROPAGATED_CONFIG} + +def _apply_child_config(config): + """Set up the child to run the test like a regrtest worker would. + + Mark this process as the subprocess, mirror the parent's -u/-M/-v config, + then suppress the Windows CRT assertion dialogs, which would block a debug + build on a modal dialog and hang the parent. + """ + global runningInSubprocess + import marshal + import test.support as support + runningInSubprocess = True + for name, value in marshal.loads(bytes.fromhex(config)).items(): + setattr(support, name, value) + support.suppress_msvcrt_asserts(support.verbose >= 2) + +# True inside the subprocess spawned by @runInSubprocess(), set by +# _apply_child_config() before the test is imported. Fixtures can test it to +# decide what to run in the subprocess as opposed to the parent process. +runningInSubprocess = False + + +class _RemoteTraceback(Exception): + """Carry a formatted traceback string from the subprocess for display. + + Attached as the ``__cause__`` of the replayed failure/error, so that the + original traceback is shown by the traceback machinery. + """ + def __init__(self, tb): + self.tb = tb + + def __str__(self): + return self.tb + + +class _SubprocessTestError(Exception): + """Replay a subprocess error (as opposed to a failure) in the parent.""" + + +def _decode(data): + # Decode the child output, which is only ever shown as a diagnostic: an + # undecodable byte must not hide the failure it is part of. + if not data: + return '' + import locale + encoding = 'utf-8' if sys.flags.utf8_mode else locale.getencoding() + return data.decode(encoding, 'backslashreplace').replace('\r\n', '\n') + + +def _remote(detail): + # Wrap the subprocess traceback the way concurrent.futures does, so it is + # clearly delimited when shown as the cause. + return _RemoteTraceback(f'\n"""\n{detail}"""') + + +def _check_subprocess_support(): + # runInSubprocess() always runs the test in a subprocess, so skip (in the + # parent) on platforms that do not support spawning one. + import test.support as support + if not support.has_subprocess_support: + raise unittest.SkipTest('requires subprocess support') + + +def _run_in_subprocess(module, qualname): + """Run module.qualname (a test method or class) in a fresh subprocess. + + Return ``(payload, output, returncode)``, where *payload* is the decoded + ``{'outcomes': ..., 'durations': ...}`` mapping from the subprocess, or + ``None`` if it did not run to completion (crash, import error, ...). + """ + import marshal + import subprocess + import tempfile + fd, result_path = tempfile.mkstemp(suffix='.json') + os.close(fd) + try: + # Pass the config on the command line, not in the environment, so that + # the test cannot pass it on to the processes it spawns itself. Use + # marshal, not json: it is built in, so the child imports nothing that + # the test would not see in a normal test run. + cmd = [sys.executable, '-m', 'test.support.subprocess_runner', + module, qualname, result_path, + marshal.dumps(_child_config()).hex()] + proc = subprocess.run(cmd, capture_output=True) + try: + with open(result_path, 'rb') as f: + payload = marshal.load(f) + except (OSError, EOFError, ValueError): + payload = None + finally: + try: + os.unlink(result_path) + except OSError: + pass + return payload, _decode(proc.stdout) + _decode(proc.stderr), proc.returncode + + +def _replay_outcome(test, outcome): + kind = outcome['kind'] + detail = outcome['detail'] + if kind == 'skipped': + test.skipTest(detail) # the detail is the skip reason, not a traceback + elif kind in ('failure', 'expected_failure'): + # Replay an expected failure like a failure: the wrapper keeps the + # @expectedFailure marker (via functools.wraps), so the parent records + # the raised exception as an expectedFailure. + exc = test.failureException('test failed in the subprocess') + raise exc from _remote(detail) + else: # 'error' + exc = _SubprocessTestError('test failed in the subprocess') + raise exc from _remote(detail) + + +def _replay_outcomes(test, outcomes): + # Replay each subtest outcome in its own subTest() context so that they are + # reported individually, then replay the whole-test outcome (if any). + main = [] + for outcome in outcomes: + if outcome['subtest']: + with test.subTest(outcome['desc']): + _replay_outcome(test, outcome) + else: + main.append(outcome) + for outcome in main: + _replay_outcome(test, outcome) + + +def _raise_fixture_outcome(outcome): + # Reproduce a setUpClass()/setUpModule() failure or skip from the + # subprocess in a parent-process fixture, so it applies to every test. + if outcome['kind'] == 'skipped': + raise unittest.SkipTest(outcome['detail']) + exc = _SubprocessTestError('class failed in the subprocess') + raise exc from _remote(outcome['detail']) + + +def _check_returncode(returncode, output, what): + # The subprocess writes its result before exiting, so a non-zero exit code + # means it died afterwards, during finalization, unnoticed by the result. + if returncode: + exc = _SubprocessTestError( + f'the subprocess exited with code {returncode} ' + f'after running the {what}') + raise exc from _remote(output) + + +def _isolate_method(func): + @functools.wraps(func) + def wrapper(self, /, *args, **kwargs): + if runningInSubprocess: + # Already running in the subprocess: run the real test. + return func(self, *args, **kwargs) + _check_subprocess_support() + cls = type(self) + qualname = f'{cls.__qualname__}.{func.__name__}' + payload, output, returncode = _run_in_subprocess(cls.__module__, + qualname) + if payload is None: + exc = _SubprocessTestError( + f'test did not complete in a subprocess (exit code {returncode})') + raise exc from _remote(output) + # The parent measures this method's own duration (the real cost of the + # isolated run, subprocess startup included), so nothing to forward here. + # Replay the outcomes first: a failure of the test itself is more useful. + _replay_outcomes(self, payload['outcomes']) + _check_returncode(returncode, output, 'test') + return wrapper + + +def _isolate_class(cls): + # Unwrap to the plain functions so the replacements can call them with the + # runtime cls; a bound classmethod would freeze the decoration-time class + # and a subclass would run the fixtures bound to the base class. + orig_setUpClass = cls.setUpClass.__func__ + orig_tearDownClass = cls.tearDownClass.__func__ + # Hook the _call*() indirections rather than setUp(), tearDown() and the + # test methods themselves, to cover what a subclass adds or overrides too. + orig_callSetUp = cls._callSetUp + orig_callTearDown = cls._callTearDown + orig_callTestMethod = cls._callTestMethod + orig_addDuration = cls._addDuration + + def setUpClass(cls): + if runningInSubprocess: + orig_setUpClass(cls) + return + _check_subprocess_support() + # Run the whole class in a single subprocess and stash the outcomes + # for the test methods to replay. + payload, output, returncode = _run_in_subprocess(cls.__module__, + cls.__qualname__) + if payload is None: + exc = _SubprocessTestError( + f'class did not complete in a subprocess (exit code {returncode})') + raise exc from _remote(output) + by_id = {} + for outcome in payload['outcomes']: + if outcome['fixture']: + # A setUpClass()/setUpModule() failure or skip: apply it to the + # whole class by raising it here, in the parent's setUpClass(). + _raise_fixture_outcome(outcome) + by_id.setdefault(outcome['id'], []).append(outcome) + cls._isolated_outcomes = by_id + cls._isolated_durations = dict(payload.get('durations', ())) + # Report the crash from tearDownClass(), after replaying the outcomes. + cls._isolated_exit = (returncode, output) + + def tearDownClass(cls): + if runningInSubprocess: + orig_tearDownClass(cls) + return + cls._isolated_outcomes = None + cls._isolated_durations = None + # Missing if an overriding setUpClass() bypassed the subprocess. + exited = getattr(cls, '_isolated_exit', None) + cls._isolated_exit = None + if exited is not None: + _check_returncode(*exited, 'class') + + def _callSetUp(self): + # In the parent the real test does not run, so neither should setUp(). + if runningInSubprocess: + orig_callSetUp(self) + + def _callTearDown(self): + if runningInSubprocess: + orig_callTearDown(self) + + def _callTestMethod(self, method): + if runningInSubprocess: + orig_callTestMethod(self, method) + return + by_id = getattr(type(self), '_isolated_outcomes', None) + if by_id is None: + raise _SubprocessTestError( + f'{type(self).__name__} did not run in a subprocess; ' + f'an overriding setUpClass() must call super().setUpClass()') + _replay_outcomes(self, by_id.get(self.id(), [])) + + def _addDuration(self, result, elapsed): + # In the parent, report the subprocess timing rather than the (instant) + # replay time; subprocess startup is paid once, in setUpClass. + if not runningInSubprocess: + durations = getattr(type(self), '_isolated_durations', None) or {} + elapsed = durations.get(self.id(), elapsed) + orig_addDuration(self, result, elapsed) + + cls.setUpClass = classmethod(setUpClass) + cls.tearDownClass = classmethod(tearDownClass) + cls._callSetUp = _callSetUp + cls._callTearDown = _callTearDown + cls._callTestMethod = _callTestMethod + cls._addDuration = _addDuration + return cls + + +def runInSubprocess(): + """Decorator to run a test method or class in a fresh subprocess. + + The decorated test runs in a separate, fresh Python process, so it does not + share global or interpreter state with the rest of the test run. When a + :class:`~unittest.TestCase` subclass is decorated, the whole class runs in a + single subprocess and its ``setUpClass()``/``setUpModule()`` fixtures run + once there; when a method is decorated, only that method runs in a + subprocess. Decorated methods must take no extra arguments. + + A failure, error or skip of the whole test is reported for the test, and + individual subtests (:meth:`~unittest.TestCase.subTest`) that fail or are + skipped are reported individually. The original subprocess traceback is + shown as the cause of a reported failure or error. Use + :data:`runningInSubprocess` in fixtures to choose what to run in the subprocess. + + The test is skipped on platforms without subprocess support, since it must + spawn one. + """ + def decorator(obj): + if isinstance(obj, type) and issubclass(obj, unittest.TestCase): + return _isolate_class(obj) + return _isolate_method(obj) + return decorator diff --git a/Lib/test/support/os_helper.py b/Lib/test/support/os_helper.py index 2c45fe2369e..daf6060940e 100644 --- a/Lib/test/support/os_helper.py +++ b/Lib/test/support/os_helper.py @@ -467,12 +467,23 @@ def _rmtree(path): def _rmtree_inner(path): from test.support import _force_run + # Clear file flags (e.g. UF_IMMUTABLE, UF_NOUNLINK on BSD). + if hasattr(os, 'chflags'): + try: + os.chflags(path, 0) + except OSError: + pass for name in _force_run(path, os.listdir, path): fullname = os.path.join(path, name) try: mode = os.lstat(fullname).st_mode except OSError: mode = 0 + if hasattr(os, 'lchflags'): + try: + os.lchflags(fullname, 0) + except OSError: + pass if stat.S_ISDIR(mode): _rmtree_inner(fullname) _force_run(path, os.rmdir, fullname) diff --git a/Lib/test/support/subprocess_runner.py b/Lib/test/support/subprocess_runner.py new file mode 100644 index 00000000000..90d74cc757d --- /dev/null +++ b/Lib/test/support/subprocess_runner.py @@ -0,0 +1,79 @@ +"""Run a single test method in this (sub)process and report the result. + +Invoked as ``python -m test.support.subprocess_runner MODULE QUALNAME OUTFILE +CONFIG`` by :func:`test.support.isolation.runInSubprocess`. CONFIG is the +marshalled test.support configuration of the parent test run, as a hex string. +The outcome of the test (including that of each individual subtest) is +marshalled to OUTFILE. This module is not meant to be imported. + +Import as little as possible before running the test: every module imported +here is state that the test would not see in a normal test run. +""" + +import marshal +import sys +import unittest +from unittest.case import _SubTest + +if __name__ != '__main__': + raise ImportError('this module cannot be directly imported') + +if len(sys.argv) != 5: + print('usage: python -m test.support.subprocess_runner ' + 'MODULE QUALNAME OUTFILE CONFIG', file=sys.stderr) + sys.exit(2) + +module, qualname, outfile, config = sys.argv[1:] + +# Set up the child before importing the test. +from test.support.isolation import _apply_child_config +_apply_child_config(config) + + +class _Result(unittest.TestResult): + # Capture per-test durations keyed by test id, so the parent can report the + # subprocess timings instead of its own replay time. + def __init__(self): + super().__init__() + self.id_durations = [] + + def addDuration(self, test, elapsed): + super().addDuration(test, elapsed) + self.id_durations.append((test.id(), elapsed)) + + +# Resolve the qualname in the imported module, rather than letting +# loadTestsFromName() guess where the module name ends: it guesses by trying +# imports that fail, and a failing import pulls in importlib.resources. +__import__(module) +suite = unittest.TestLoader().loadTestsFromName(qualname, sys.modules[module]) +result = _Result() +suite.run(result) + + +def _outcome(kind, test, detail): + subtest = isinstance(test, _SubTest) + real = test.test_case if subtest else test + return { + 'kind': kind, + 'subtest': subtest, + 'desc': test._subDescription() if subtest else '', + # id() groups outcomes by test method; a non-TestCase (e.g. an + # _ErrorHolder) marks a setUpClass()/setUpModule() fixture failure. + 'id': real.id(), + 'fixture': not isinstance(real, unittest.TestCase), + 'detail': detail, + } + + +outcomes = [_outcome('failure', t, tb) for t, tb in result.failures] +outcomes += [_outcome('error', t, tb) for t, tb in result.errors] +outcomes += [_outcome('expected_failure', t, tb) + for t, tb in result.expectedFailures] +outcomes += [_outcome('skipped', t, reason) for t, reason in result.skipped] + +payload = {'outcomes': outcomes, 'durations': result.id_durations} +with open(outfile, 'wb') as f: + marshal.dump(payload, f) + +sys.exit(0) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 627e395c49b..e376c44faa4 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -7128,6 +7128,19 @@ def test_module(self, compiled=False): def test_module_compiled(self): self.test_module(compiled=True) + def test_module_as_main_without_altering_argv(self): + basename = 'module' + os_helper.FS_NONASCII + modulename = f'{self.dirname}.{basename}' + self.make_script(self.dirname, basename) + runner_source = textwrap.dedent(f'''\ + import runpy + runpy._run_module_as_main({modulename!r}, alter_argv=False) + ''') + runner = script_helper.make_script( + self.dirname, 'runner', runner_source) + self.check_usage(os.path.basename(runner), runner, + PYTHONPATH=os.curdir) + def test_package(self, compiled=False): basename = 'subpackage' + os_helper.FS_NONASCII packagename = f'{self.dirname}.{basename}' diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py index 13df6134882..8cf669935f9 100644 --- a/Lib/test/test_array.py +++ b/Lib/test/test_array.py @@ -5,7 +5,7 @@ import collections.abc import unittest from test import support -from test.support import import_helper +from test.support import import_helper, script_helper from test.support import os_helper from test.support import _2G from test.support import subTests @@ -35,6 +35,11 @@ def __init__(self, typecode, newarg=None): class MiscTest(unittest.TestCase): + def test_array_type_importable(self): + from array import ArrayType + + self.assertIs(array.array, ArrayType) + def test_array_is_sequence(self): self.assertIsInstance(array.array("B"), collections.abc.MutableSequence) self.assertIsInstance(array.array("B"), collections.abc.Reversible) @@ -45,6 +50,23 @@ def test_bad_constructor(self): self.assertRaises(TypeError, array.array, 'xx') self.assertRaises(ValueError, array.array, 'x') + @support.cpython_only + def test_does_not_crash_on_broken_imports(self): + # gh-153210 + code = """if 1: + import collections.abc + + del collections.abc.MutableSequence + + try: + import array # it used to crash before + except AttributeError: + pass + else: + raise AssertionError('AttributeError was not raised') + """ + script_helper.assert_python_ok('-c', code) + @support.cpython_only def test_disallow_instantiation(self): my_array = array.array("I") @@ -1198,7 +1220,6 @@ def test_obsolete_write_lock(self): a = array.array('B', b"") self.assertRaises(BufferError, _testcapi.getbuffer_with_null_view, a) - @unittest.skip("TODO: RUSTPYTHON; hangs") def test_free_after_iterating(self): support.check_free_after_iterating(self, iter, array.array, (self.typecode,)) @@ -1686,7 +1707,6 @@ def test_gh_128961(self): # when the index conversion mutates the array. # See: https://github.com/python/cpython/issues/142555. - @unittest.skip("TODO: RUSTPYTHON; Hangs") @subTests("dtype", ["b", "B", "h", "H", "i", "l", "q", "I", "L", "Q"]) def test_setitem_use_after_clear_with_int_data(self, dtype): victim = array.array(dtype, list(range(64))) @@ -1699,7 +1719,6 @@ def __index__(self): self.assertRaises(IndexError, victim.__setitem__, 1, Index()) self.assertEqual(len(victim), 0) - @unittest.skip("TODO: RUSTPYTHON; Hangs") def test_setitem_use_after_shrink_with_int_data(self): victim = array.array('b', [1, 2, 3]) @@ -1711,7 +1730,6 @@ def __index__(self): self.assertRaises(IndexError, victim.__setitem__, 1, Index()) - @unittest.skip("TODO: RUSTPYTHON; Hangs") @subTests("dtype", ["f", "d"]) def test_setitem_use_after_clear_with_float_data(self, dtype): victim = array.array(dtype, [1.0, 2.0, 3.0]) diff --git a/Lib/test/test_atexit.py b/Lib/test/test_atexit.py index 6f57ee06879..aba377d4175 100644 --- a/Lib/test/test_atexit.py +++ b/Lib/test/test_atexit.py @@ -136,9 +136,7 @@ def callback(): self.assertEqual(os.read(r, len(expected)), expected) os.close(r) - # Python built with Py_TRACE_REFS fail with a fatal error in - # _PyRefchain_Trace() on memory allocation error. - @unittest.skipIf(support.Py_TRACE_REFS, 'cannot test Py_TRACE_REFS build') + @support.nomemtest def test_atexit_with_low_memory(self): # gh-140080: Test that setting low memory after registering an atexit # callback doesn't cause an infinite loop during finalization. diff --git a/Lib/test/test_bigmem.py b/Lib/test/test_bigmem.py index 12b221a66e3..7f53379a952 100644 --- a/Lib/test/test_bigmem.py +++ b/Lib/test/test_bigmem.py @@ -10,11 +10,6 @@ from test import support from test.support import bigmemtest, _1G, _2G, _4G, import_helper -# _testcapi = import_helper.import_module('_testcapi') -try: # TODO: RUSTPYTHON - import _testcapi -except ImportError: - _testcapi = None import unittest import operator @@ -1268,6 +1263,7 @@ class ImmortalityTest(unittest.TestCase): def test_stickiness(self, size): """Check that immortality is "sticky", so that once an object is immortal it remains so.""" + _testcapi = import_helper.import_module('_testcapi') if size < _2G: # Not enough memory to cause immortality on overflow return diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index 48631cecec7..82eabf4bb06 100644 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -117,7 +117,6 @@ def addnoise(line): # empty strings. TBD: shouldn't it raise an exception instead ? self.assertEqual(binascii.a2b_base64(self.type2test(fillers)), b'') - @unittest.expectedFailure # TODO: RUSTPYTHON def test_base64_strict_mode(self): # Test base64 with strict mode on def _assertRegexTemplate(assert_regex: str, data: bytes, non_strict_mode_expected_result: bytes): @@ -175,7 +174,6 @@ def assertExcessPadding(data, non_strict_mode_expected_result: bytes): assertExcessPadding(b'abcd====', b'i\xb7\x1d') assertExcessPadding(b'abcd=====', b'i\xb7\x1d') - @unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: b'i' != b'i\xb7' def test_base64_excess_data(self): # Test excess data exceptions def assertExcessData(data, expected): diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 32a9ca7df87..16099ceb665 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -1041,7 +1041,6 @@ def test_find_etc_raise_correct_error_messages(self): self.assertRaisesRegex(TypeError, r'\bendswith\b', b.endswith, x, None, None, None) - @unittest.skip("TODO: RUSTPYTHON; hangs") def test_free_after_iterating(self): test.support.check_free_after_iterating(self, iter, self.type2test) test.support.check_free_after_iterating(self, reversed, self.type2test) diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index 6ce64109fba..6c26259cf15 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -215,10 +215,6 @@ from test.support import threading_helper, import_helper from test.support.bytecode_helper import instructions_with_positions from opcode import opmap, opname -try: # TODO: RUSTPYTHON - from _testcapi import code_offset_to_line -except ModuleNotFoundError: - code_offset_to_line = None try: import _testinternalcapi except ModuleNotFoundError: @@ -1489,8 +1485,9 @@ async def async_func(): rc, out, err = assert_python_ok('-OO', '-c', code) - @unittest.expectedFailureIf(code_offset_to_line is None, "TODO: RUSTPYTHON") def test_co_branches(self): + _testcapi = import_helper.import_module("_testcapi") + code_offset_to_line = _testcapi.code_offset_to_line def get_line_branches(func): code = func.__code__ diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index 58a7d6f3a38..a55057d91d7 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -2776,9 +2776,6 @@ def test_partial(self): ] ) - @unittest.expectedFailure # TODO: RUSTPYTHON; IndexError: index out of range - def test_incremental_surrogatepass(self): - return super().test_incremental_surrogatepass() class RawUnicodeEscapeTest(ReadTest, unittest.TestCase): encoding = "raw-unicode-escape" diff --git a/Lib/test/test_colorsys.py b/Lib/test/test_colorsys.py index 74d76294b0b..9dfaef44a6a 100644 --- a/Lib/test/test_colorsys.py +++ b/Lib/test/test_colorsys.py @@ -42,6 +42,10 @@ def test_hsv_values(self): self.assertTripleEqual(hsv, colorsys.rgb_to_hsv(*rgb)) self.assertTripleEqual(rgb, colorsys.hsv_to_rgb(*hsv)) + # test 360 phase shift in hue + h, s, v = hsv + self.assertTripleEqual(rgb, colorsys.hsv_to_rgb(h + 1.0, s, v)) + def test_hls_roundtrip(self): for r in frange(0.0, 1.0, 0.2): for g in frange(0.0, 1.0, 0.2): @@ -89,6 +93,18 @@ def test_yiq_roundtrip(self): colorsys.yiq_to_rgb(*colorsys.rgb_to_yiq(*rgb)) ) + def test_yiq_to_rgb_clamping(self): + values = [ + # rgb, yiq (invalid YIQ values clamped to RGB range) + ((1.0, 0.0, 1.0), (0.0, 0.5, 1.0)), + ((0.0, 1.0, 0.0), (0.25, -1.0, -1.0)), + ((0.0, 0.0, 1.0), (0.0, -1.0, 0.5)) + ] + + for (rgb, yiq) in values: + with self.subTest(rgb=rgb, yiq=yiq): + self.assertTripleEqual(rgb, colorsys.yiq_to_rgb(*yiq)) + def test_yiq_values(self): values = [ # rgb, yiq diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index a6542b396cc..021c3622566 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -724,6 +724,8 @@ def test_yet_more_evil_still_undecodable(self): @support.cpython_only @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") + @support.run_with_limited_c_stack( + 100_000 if sys.platform == "android" else 500_000) @support.skip_emscripten_stack_overflow() def test_compiler_recursion_limit(self): # Compiler frames are small diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index 8d8dd2a2bf2..4783943f71a 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -526,6 +526,17 @@ def test_default_case_sensitivity(self): cf.get(self.default_section, "Foo"), "Bar", "could not locate option, expecting case-insensitive defaults") + def test_crlf_normalization(self): + cf = self.newconfig({"key1": "a\nb","key2": "a\rb", "key3": "a\r\nb", "key4": "a\r\nb"}) + buf = io.StringIO() + cf.write(buf) + cf_str = buf.getvalue() + self.assertNotIn("\r", cf_str) + self.assertNotIn("\r\n", cf_str) + self.assertEqual(cf_str.count("\n"), 10) + self.assertEqual(cf_str.count("\n\t"), 4) + self.assertTrue(cf_str.endswith("\n\n")) + def test_parse_errors(self): cf = self.newconfig() self.parse_error(cf, configparser.ParsingError, diff --git a/Lib/test/test_csv.py b/Lib/test/test_csv.py index 65093dc70c1..2dd012c93b2 100644 --- a/Lib/test/test_csv.py +++ b/Lib/test/test_csv.py @@ -87,12 +87,10 @@ def _test_arg_valid(self, ctor, arg): self.assertRaises(ValueError, ctor, arg, quotechar='\x85', lineterminator='\x85') - @unittest.expectedFailure # TODO: RUSTPYTHON def test_reader_arg_valid(self): self._test_arg_valid(csv.reader, []) self.assertRaises(OSError, csv.reader, BadIterable()) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_writer_arg_valid(self): self._test_arg_valid(csv.writer, StringIO()) class BadWriter: @@ -1288,7 +1286,6 @@ class mydialect(csv.Dialect): self.assertEqual(str(cm.exception), '"lineterminator" must be a string, not NoneType') - @unittest.expectedFailure # TODO: RUSTPYTHON def test_invalid_chars(self): def create_invalid(field_name, value, **kwargs): class mydialect(csv.Dialect): @@ -1408,6 +1405,9 @@ class TestSniffer(unittest.TestCase): sample18.append("v,twenty_one") # 'u' was not skipped sample18 = '\n'.join(sample18) + sample19 = ('time,title\r\n' + '2020-10-01,"Pocket - Save news, videos, stories and more"\r\n') + def test_issue43625(self): sniffer = csv.Sniffer() self.assertTrue(sniffer.has_header(self.sample12)) @@ -1487,6 +1487,9 @@ def test_delimiters(self): sniffer.sniff, self.sample15) self.assertRaisesRegex(csv.Error, "Could not determine delimiter", sniffer.sniff, self.sample16) + dialect = sniffer.sniff(self.sample19) + self.assertEqual(dialect.delimiter, ',') + self.assertEqual(dialect.quotechar, '"') def test_doublequote(self): sniffer = csv.Sniffer() @@ -1501,6 +1504,57 @@ def test_doublequote(self): dialect = sniffer.sniff(self.sample9) self.assertTrue(dialect.doublequote) + def test_sniff_regex_backtracking(self): + # gh-109638: this artificial sample used to take minutes. + sniffer = csv.Sniffer() + sample = '"",' * 100 + '"' * 100 + '0' + '"' * 100 + '0' + self.assertEqual(sniffer.sniff(sample).delimiter, ',') + + def test_sniff_doublequote_across_fields(self): + # A quoted field which contains the delimiter, followed by + # an empty quoted field, is not a doubled quote. + sniffer = csv.Sniffer() + sample = '",","",","\n' * 4 + dialect = sniffer.sniff(sample) + self.assertEqual(dialect.delimiter, ',') + self.assertEqual(dialect.quotechar, '"') + self.assertIs(dialect.doublequote, False) + self.assertEqual(next(csv.reader(StringIO(sample), dialect)), + [',', '', ',']) + + def test_sniff_doublequote_record_separators(self): + # The record separator ends a field as a delimiter does. + sniffer = csv.Sniffer() + for sep in '\n', '\r\n', '\r': + with self.subTest(sep=sep): + sample = ('x,"a""b"' + sep + 'y,"c"' + sep) * 2 + self.assertIs(sniffer.sniff(sample).doublequote, True) + sample = ('"",","' + sep) * 4 + self.assertIs(sniffer.sniff(sample).doublequote, False) + + def test_sniff_single_column(self): + # This sample used to be quadratic. + sniffer = csv.Sniffer() + sample = '"a"\n' + ' ' * 100000 + with self.assertRaisesRegex(csv.Error, "Could not determine delimiter"): + sniffer.sniff(sample, delimiters=',;') + + def test_sniff_space_delimiter(self): + # This sample used to be quadratic. + sniffer = csv.Sniffer() + sample = '"a" "b"\n' + ' ' * 100000 + dialect = sniffer.sniff(sample) + self.assertEqual(dialect.delimiter, ' ') + self.assertIs(dialect.doublequote, False) + + def test_sniff_quoted_single_column(self): + # gh-98820: this sample used to take minutes. + sniffer = csv.Sniffer() + sample = '"abcdefghijklmnopqrstuvwxyz"\n' * 10000 + with self.assertRaisesRegex(csv.Error, "Could not determine delimiter"): + sniffer.sniff(sample, delimiters=',:|\t') + + class NUL: def write(s, *args): pass diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 0b19496ec4b..da919fae6e4 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -4857,7 +4857,6 @@ class X(object): with self.assertRaises(AttributeError): del X.__abstractmethods__ - @unittest.skip("TODO: RUSTPYTHON; crash. \"dict has non-string keys: [PyObject PyInt { value: 1 }]\"") def test_gh55664(self): # gh-55664: issue a warning when the # __dict__ of a class contains non-string keys @@ -5297,7 +5296,7 @@ def __pow__(self, *args): class MiscTests(unittest.TestCase): - @unittest.skip("TODO: RUSTPYTHON; rustpython panicked at 'dict has non-string keys: [PyObject PyBaseObject]'") + @unittest.expectedFailure # TODO: RUSTPYTHON; a class namespace drops keys that are not strings, so MyKey.__eq__ is never reached and __bases__ stays put def test_type_lookup_mro_reference(self): # Issue #14199: _PyType_Lookup() has to keep a strong reference to # the type MRO because it may be modified during the lookup, if diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index e2a73773cc2..e11dd17f1d9 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -678,7 +678,7 @@ def __repr__(self): d = {1: BadRepr()} self.assertRaises(Exc, repr, d) - @unittest.skip("TODO: RUSTPYTHON; segfault") + @support.run_with_limited_c_stack() @support.skip_wasi_stack_overflow() @support.skip_emscripten_stack_overflow() def test_repr_deep(self): @@ -1258,7 +1258,6 @@ def __eq__(self, o): d = {X(): 0, 1: 1} self.assertRaises(RuntimeError, d.update, other) - @unittest.skip("TODO: RUSTPYTHON; hangs") def test_free_after_iterating(self): support.check_free_after_iterating(self, iter, dict) support.check_free_after_iterating(self, lambda d: iter(d.keys()), dict) @@ -1406,6 +1405,28 @@ def __init__(self, x, y): self.assertEqual(list(reversed(A(1, 0).__dict__)), ['x']) self.assertEqual(list(reversed(A(0, 1).__dict__)), ['y']) + @unittest.expectedFailure # TODO: RUSTPYTHON; RuntimeError: dictionary changed size during iteration + def test_reversed_dict_after_clear_and_restore(self): + d = {} + for i in range(1000): + d[f"k{i}"] = i + + for i in range(1, 1000): + del d[f"k{i}"] + + iterators = ( + reversed(d), + reversed(d.keys()), + reversed(d.values()), + reversed(d.items()), + ) + + d.clear() + d["k0"] = 0 + + for it in iterators: + self.assertEqual(list(it), []) + def test_dict_copy_order(self): # bpo-34320 od = collections.OrderedDict([('a', 1), ('b', 2)]) diff --git a/Lib/test/test_difflib.py b/Lib/test/test_difflib.py index 36be5c99c3f..518b8c5278e 100644 --- a/Lib/test/test_difflib.py +++ b/Lib/test/test_difflib.py @@ -282,6 +282,29 @@ def test_make_file_usascii_charset_with_nonascii_input(self): self.assertIn('content="text/html; charset=us-ascii"', output) self.assertIn('ımplıcıt', output) + def test_strip_trailing_newlines_before_diff(self): + # characterization test for the current buggy behavior + # see: gh-71896 + html_diff = difflib.HtmlDiff() + from_lines = [ + "Line 1: no newline after", + "Line 2: one newline after\n", + "Line 3: several newlines after\n\n\n\n\n", + ] + to_lines = [ + "Line 1: no newline after", + "Line 2: one newline after", # actually no \n + "Line 3: several newlines after", # actually no \n + ] + output = html_diff.make_table(from_lines, to_lines) + # we (currently) expect no line change, so all equal + self.assertNotIn('class="diff_add"', output) + self.assertNotIn('class="diff_chg"', output) + self.assertNotIn('class="diff_sub"', output) + self.assertEqual(output.count('>Line 1: no newline after<'), 2) + self.assertEqual(output.count('>Line 2: one newline after<'), 2) + self.assertEqual(output.count('>Line 3: several newlines after<'), 2) + class TestDiffer(unittest.TestCase): def test_close_matches_aligned(self): # Of the 4 closely matching pairs, we want 1 to match with 3, diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 7360ead1144..190374fba8c 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -1106,7 +1106,6 @@ def f(): def test_bug_708901(self): self.do_disassembly_test(bug708901, dis_bug708901) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_bug_1333982(self): # This one is checking bytecodes generated for an `assert` statement, # so fails if the tests are run with -O. Skip this test then. @@ -1164,7 +1163,6 @@ def func(count): from test import dis_module self.do_disassembly_test(dis_module, dis_module_expected_results) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_disassemble_str(self): self.do_disassembly_test(expr_str, dis_expr_str) self.do_disassembly_test(simple_stmt_str, dis_simple_stmt_str) @@ -1251,7 +1249,6 @@ def test_dis_traceback(self): def test_dis_object(self): self.assertRaises(TypeError, dis.dis, object()) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_disassemble_recursive(self): def check(expected, **kwargs): dis = self.get_disassembly(_h, **kwargs) @@ -1623,13 +1620,11 @@ class CodeInfoTests(unittest.TestCase): (async_def, code_info_async_def) ] - @unittest.expectedFailure # TODO: RUSTPYTHON def test_code_info(self): self.maxDiff = 1000 for x, expected in self.test_pairs: self.assertRegex(dis.code_info(x), expected) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_show_code(self): self.maxDiff = 1000 for x, expected in self.test_pairs: @@ -2322,7 +2317,6 @@ def test_source_line_in_disassembly(self): actual = actual.strip().partition(" ")[0] # extract the line no self.assertEqual(actual, "350") - @unittest.expectedFailure # TODO: RUSTPYTHON def test_info(self): self.maxDiff = 1000 for x, expected in CodeInfoTests.test_pairs: diff --git a/Lib/test/test_email/test_headerregistry.py b/Lib/test/test_email/test_headerregistry.py index 854b76966ec..df29f788847 100644 --- a/Lib/test/test_email/test_headerregistry.py +++ b/Lib/test/test_email/test_headerregistry.py @@ -223,6 +223,14 @@ def test_invalid_date_value(self): self.assertEqual(len(h.defects), 1) self.assertIsInstance(h.defects[0], errors.InvalidDateDefect) + def test_out_of_range_date_value(self): + s = 'Mon, 20 Nov 9999999999 12:00:00 +0000' + h = self.make_header('date', s) + self.assertEqual(h, s) + self.assertIsNone(h.datetime) + self.assertEqual(len(h.defects), 1) + self.assertIsInstance(h.defects[0], errors.InvalidDateDefect) + def test_datetime_read_only(self): h = self.make_header('date', self.datestring) with self.assertRaises(AttributeError): diff --git a/Lib/test/test_email/test_utils.py b/Lib/test/test_email/test_utils.py index c9d09098b50..86d1bfff891 100644 --- a/Lib/test/test_email/test_utils.py +++ b/Lib/test/test_email/test_utils.py @@ -77,6 +77,15 @@ def test_parsedate_to_datetime_with_invalid_raises_valueerror(self): with self.subTest(dtstr=dtstr): self.assertRaises(ValueError, utils.parsedate_to_datetime, dtstr) + def test_parsedate_to_datetime_out_of_range_raises_valueerror(self): + out_of_range_dates = [ + 'Mon, 20 Nov 9999999999 12:00:00 +0000', + 'Mon, 20 Nov 2017 12:00:00 +24000000000000', + ] + for dtstr in out_of_range_dates: + with self.subTest(dtstr=dtstr): + self.assertRaises(ValueError, utils.parsedate_to_datetime, dtstr) + class LocaltimeTests(unittest.TestCase): def test_localtime_is_tz_aware_daylight_true(self): diff --git a/Lib/test/test_exception_group.py b/Lib/test/test_exception_group.py index 1e1c43a6bf4..5d78a4d698a 100644 --- a/Lib/test/test_exception_group.py +++ b/Lib/test/test_exception_group.py @@ -538,7 +538,6 @@ def make_deep_eg(self): e = ExceptionGroup('eg', [e]) return e - @unittest.skip("TODO: RUSTPYTHON; Segfault") @skip_emscripten_stack_overflow() @skip_wasi_stack_overflow() def test_deep_split(self): @@ -546,7 +545,6 @@ def test_deep_split(self): with self.assertRaises(RecursionError): e.split(TypeError) - @unittest.skip("TODO: RUSTPYTHON; Segfault") @skip_emscripten_stack_overflow() @skip_wasi_stack_overflow() def test_deep_subgroup(self): diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 7c81c4b3905..ee5af3e3985 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -2453,7 +2453,6 @@ def try_compile(source): self.assertEqual(exc.offset, 1) self.assertEqual(exc.end_offset, 12) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_file_source(self): self.addCleanup(unlink, TESTFN) err = run_script('return "ä"') diff --git a/Lib/test/test_flufl.py b/Lib/test/test_flufl.py index bd6267d45ae..d77e481c81d 100644 --- a/Lib/test/test_flufl.py +++ b/Lib/test/test_flufl.py @@ -4,7 +4,6 @@ class FLUFLTests(unittest.TestCase): - @unittest.expectedFailure # TODO: RUSTPYTHON def test_barry_as_bdfl(self): code = "from __future__ import barry_as_FLUFL\n2 {0} 3" compile(code.format('<>'), '', 'exec', @@ -22,7 +21,6 @@ def test_barry_as_bdfl(self): # parser reports the start of the token self.assertEqual(cm.exception.offset, 3) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_guido_as_bdfl(self): code = '2 {0} 3' compile(code.format('!='), '', 'exec') @@ -36,7 +34,6 @@ def test_guido_as_bdfl(self): # parser reports the start of the token self.assertEqual(cm.exception.offset, 3) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_barry_as_bdfl_look_ma_with_no_compiler_flags(self): # Check that the future import is handled by the parser # even if the compiler flags are not passed. @@ -50,7 +47,6 @@ def test_barry_as_bdfl_look_ma_with_no_compiler_flags(self): self.assertEqual(cm.exception.lineno, 1) self.assertEqual(cm.exception.offset, len(code) - 4) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_barry_as_bdfl_relative_import(self): code = "from .__future__ import barry_as_FLUFL;2 {0} 3" compile(code.format('!='), '', 'exec') diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index e35d5118f18..8649f597977 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -383,7 +383,6 @@ def test_ast_line_numbers_multiline_fstring(self): self.assertEqual(t.body[0].value.values[1].value.col_offset, 11) self.assertEqual(t.body[0].value.values[1].value.end_col_offset, 16) - @unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: 4 != 5 def test_ast_line_numbers_with_parentheses(self): expr = """ x = ( diff --git a/Lib/test/test_future_stmt/test_future.py b/Lib/test/test_future_stmt/test_future.py index 02690919cf3..71f1e616116 100644 --- a/Lib/test/test_future_stmt/test_future.py +++ b/Lib/test/test_future_stmt/test_future.py @@ -111,7 +111,6 @@ def test_future_import_not_on_top(self): """ self.assertSyntaxError(code, lineno=3) - @unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: SyntaxError not raised def test_future_import_with_extra_string(self): code = """ '''Docstring''' @@ -260,7 +259,6 @@ def _exec_future(self, code): ) return scope - @unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: "t'{a + b}'" != "t'{a + b}'" def test_annotations(self): eq = self.assertAnnotationEqual eq('...') diff --git a/Lib/test/test_getopt.py b/Lib/test/test_getopt.py index 8d0d5084abb..fac2ca3db81 100644 --- a/Lib/test/test_getopt.py +++ b/Lib/test/test_getopt.py @@ -149,6 +149,18 @@ def test_getopt(self): ('-a', ''), ('--alpha', '')]) self.assertEqual(args, ['arg1', 'arg2']) + # Allow string for single long argument + opts, args = getopt.getopt(cmdline, 'a::', 'alpha=?') + self.assertEqual(opts, [('-a', '1'), ('--alpha', '2'), ('--alpha', ''), + ('-a', ''), ('--alpha', '')]) + self.assertEqual(args, ['arg1', 'arg2']) + + # Pass everything after -- as args + cmdline = ['-a1', '--alpha=2', '--', '-b', '--beta=5'] + opts, args = getopt.getopt(cmdline, 'a:b', ['alpha=', 'beta']) + self.assertEqual(opts, [('-a', '1'), ('--alpha', '2')]) + self.assertEqual(args, ['-b', '--beta=5']) + self.assertError(getopt.getopt, cmdline, 'a:b', ['alpha', 'beta']) def test_gnu_getopt(self): @@ -191,6 +203,25 @@ def test_gnu_getopt(self): self.assertEqual(args, ['arg1', '-b', '1', '--alpha', '--beta=2', '--beta', '3', 'arg2']) + # Allow string for single long argument + opts, args = getopt.gnu_getopt(cmdline, 'ab:', 'alpha') + self.assertEqual(opts, [('-a', '')]) + self.assertEqual(args, ['arg1', '-b', '1', '--alpha', '--beta=2', + '--beta', '3', 'arg2']) + + # Pass everything after -- as args + cmdline = ['-a1', '--alpha=2', '--', '-b', '--beta=5'] + opts, args = getopt.gnu_getopt(cmdline, 'a:b', ['alpha=', 'beta']) + self.assertEqual(opts, [('-a', '1'), ('--alpha', '2')]) + self.assertEqual(args, ['-b', '--beta=5']) + + # In order arguments + cmdline = ["gamma", "--alpha=3"] + opts, args = getopt.gnu_getopt(cmdline, '-', ["alpha="]) + self.assertEqual(opts, [(None, ['gamma']), ('--alpha', '3')]) + self.assertEqual(args, []) + + def test_issue4629(self): longopts, shortopts = getopt.getopt(['--help='], '', ['help=']) self.assertEqual(longopts, [('--help', '')]) @@ -198,6 +229,10 @@ def test_issue4629(self): self.assertEqual(longopts, [('--help', 'x')]) self.assertRaises(getopt.GetoptError, getopt.getopt, ['--help='], '', ['help']) + def test_getopt_error_str(self): + error = getopt.GetoptError('option -a not recognized', 'a') + self.assertEqual(str(error), 'option -a not recognized') + def test_libref_examples(): """ Examples from the Library Reference: Doc/lib/libgetopt.tex diff --git a/Lib/test/test_htmlparser.py b/Lib/test/test_htmlparser.py index e4eff1ea17a..3fdaed4ff46 100644 --- a/Lib/test/test_htmlparser.py +++ b/Lib/test/test_htmlparser.py @@ -116,6 +116,11 @@ def _run_check(self, source, expected_events, *, collector=None, convert_charrefs=False): if collector is None: collector = self.get_collector(convert_charrefs=convert_charrefs) + if isinstance(source, str): + # Also feed the whole string at once, not just character by + # character (below), to exercise different input buffering. + self._run_check([source], expected_events, + convert_charrefs=convert_charrefs) parser = collector for s in source: parser.feed(s) @@ -593,6 +598,9 @@ def test_comments(self): ' -->' '' '' + # abruptly closed empty comment must not swallow later text + 'x-->' + 'y-->' ) expected = [('comment', " I'm a valid comment "), ('comment', 'me too!'), @@ -613,6 +621,8 @@ def test_comments(self): ('comment', ' '), ('comment', ''), + ('comment', ''), ('data', 'y-->'), ] self._run_check(html, expected) @@ -1031,6 +1041,26 @@ def check(source): check("") # comment + check("") # processing instruction + check("") # doctype + check("") # CDATA section + check("") # start tag + check("") # RAWTEXT element + class AttributesTestCase(TestCaseBase): diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 99ab6c7ba90..b023b1c5dec 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -5053,13 +5053,11 @@ def alarm2(sig, frame): if e.errno != errno.EBADF: raise - @unittest.skip("TODO: RUSTPYTHON; thread 'main' (103833) panicked at crates/vm/src/stdlib/signal.rs:233:43: RefCell already borrowed") @requires_alarm @support.requires_resource('walltime') def test_interrupted_write_retry_buffered(self): self.check_interrupted_write_retry(b"x", mode="wb") - @unittest.skip("TODO: RUSTPYTHON; thread 'main' (103833) panicked at crates/vm/src/stdlib/signal.rs:233:43: RefCell already borrowed") @requires_alarm @support.requires_resource('walltime') def test_interrupted_write_retry_text(self): @@ -5069,10 +5067,6 @@ def test_interrupted_write_retry_text(self): class CSignalsTest(SignalsTest): io = io - @unittest.skip("TODO: RUSTPYTHON; thread 'main' (103833) panicked at crates/vm/src/stdlib/signal.rs:233:43: RefCell already borrowed") - def test_interrupted_read_retry_buffered(self): - return super().test_interrupted_read_retry_buffered() - class PySignalsTest(SignalsTest): io = pyio diff --git a/Lib/test/test_isinstance.py b/Lib/test/test_isinstance.py index d97535ba46e..16d879a3831 100644 --- a/Lib/test/test_isinstance.py +++ b/Lib/test/test_isinstance.py @@ -263,6 +263,7 @@ def test_subclass_tuple(self): self.assertEqual(True, issubclass(int, (int, (float, int)))) self.assertEqual(True, issubclass(str, (str, (Child, str)))) + @support.skip_if_huge_c_stack() @support.skip_wasi_stack_overflow() @support.skip_emscripten_stack_overflow() def test_subclass_recursion_limit(self): @@ -270,6 +271,7 @@ def test_subclass_recursion_limit(self): # blown self.assertRaises(RecursionError, blowstack, issubclass, str, str) + @support.skip_if_huge_c_stack() @support.skip_wasi_stack_overflow() @support.skip_emscripten_stack_overflow() def test_isinstance_recursion_limit(self): @@ -317,7 +319,7 @@ def __bases__(self): self.assertRaises(RecursionError, issubclass, int, X()) self.assertRaises(RecursionError, isinstance, 1, X()) - @support.skip_if_unlimited_stack_size + @support.skip_if_huge_c_stack() @support.skip_emscripten_stack_overflow() @support.skip_wasi_stack_overflow() def test_infinite_recursion_via_bases_tuple(self): @@ -329,7 +331,7 @@ def __getattr__(self, attr): with self.assertRaises(RecursionError): issubclass(Failure(), int) - @support.skip_if_unlimited_stack_size + @support.skip_if_huge_c_stack() @support.skip_emscripten_stack_overflow() @support.skip_wasi_stack_overflow() def test_infinite_cycle_in_bases(self): diff --git a/Lib/test/test_iter.py b/Lib/test/test_iter.py index 7ac48a50233..18e4b676c53 100644 --- a/Lib/test/test_iter.py +++ b/Lib/test/test_iter.py @@ -1137,7 +1137,6 @@ def test_iter_neg_setstate(self): self.assertEqual(next(it), 0) self.assertEqual(next(it), 1) - @unittest.skip("TODO: RUSTPYTHON; hangs") def test_free_after_iterating(self): check_free_after_iterating(self, iter, SequenceClass, (0,)) diff --git a/Lib/test/test_json/test_default.py b/Lib/test/test_json/test_default.py index 4d569dadfa4..811880a15c8 100644 --- a/Lib/test/test_json/test_default.py +++ b/Lib/test/test_json/test_default.py @@ -1,8 +1,6 @@ import collections from test.test_json import PyTest, CTest -import unittest # XXX: RUSTPYTHON; importing to be able to skip tests - class TestDefault: def test_default(self): @@ -10,7 +8,6 @@ def test_default(self): self.dumps(type, default=repr), self.dumps(repr(type))) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_bad_default(self): def default(obj): if obj is NotImplemented: diff --git a/Lib/test/test_list.py b/Lib/test/test_list.py index 40cec226183..d7624734089 100644 --- a/Lib/test/test_list.py +++ b/Lib/test/test_list.py @@ -3,7 +3,6 @@ import textwrap from test import list_tests, support from test.support import cpython_only -from test.support.import_helper import import_module from test.support.script_helper import assert_python_failure, assert_python_ok import pickle import unittest @@ -329,10 +328,9 @@ def test_tier2_invalidates_iterator(self): a.append(4) self.assertEqual(list(it), []) - @support.cpython_only + @support.nomemtest def test_no_memory(self): # gh-118331: Make sure we don't crash if list allocation fails - import_module("_testcapi") code = textwrap.dedent(""" import _testcapi, sys # Prime the freelist diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py index 8e49aa8954e..f91843562c3 100644 --- a/Lib/test/test_locale.py +++ b/Lib/test/test_locale.py @@ -1,6 +1,5 @@ from decimal import Decimal from test.support import cpython_only, verbose, is_android, linked_to_musl, os_helper -from test.support.warnings_helper import check_warnings from test.support.import_helper import ensure_lazy_imports, import_fresh_module from unittest import mock import unittest @@ -554,8 +553,7 @@ def test_defaults_UTF8(self): env.unset('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE') env.set('LC_CTYPE', 'UTF-8') - with check_warnings(('', DeprecationWarning)): - self.assertEqual(locale.getdefaultlocale(), (None, 'UTF-8')) + self.assertEqual(locale.getdefaultlocale(), (None, 'UTF-8')) finally: if orig_getlocale is not None: _locale._getdefaultlocale = orig_getlocale diff --git a/Lib/test/test_marshal.py b/Lib/test/test_marshal.py index 4e5311cd0a2..eb2e8bda9d3 100644 --- a/Lib/test/test_marshal.py +++ b/Lib/test/test_marshal.py @@ -704,7 +704,6 @@ def testModule(self): self.helper(code) self.helper3(code) - @unittest.skip("TODO: RUSTPYTHON") def testRecursion(self): obj = 1.2345 d = {"hello": obj, "goodbye": obj, obj: "hello"} diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 5678536ff18..943448d69ca 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -238,6 +238,19 @@ def __init__(self, value): def __index__(self): return self.value +# int subclass with broken arithmetic operators; implementations must +# convert their arguments to exact ints instead of using these. +class BadIntSubclass(int): + def _binop(self, other='ignored', mod=None): + return 42 + __add__ = __radd__ = __sub__ = __rsub__ = _binop + __mul__ = __rmul__ = __mod__ = __rmod__ = _binop + __divmod__ = __rdivmod__ = __pow__ = __rpow__ = _binop + __floordiv__ = __rfloordiv__ = _binop + __lshift__ = __rlshift__ = __rshift__ = __rrshift__ = _binop + __and__ = __rand__ = __or__ = __ror__ = __xor__ = __rxor__ = _binop + __lt__ = __le__ = __gt__ = __ge__ = _binop + class BadDescr: def __get__(self, obj, objtype=None): raise ValueError @@ -1117,6 +1130,16 @@ def __index__(self): self.assertIs(type(s), int) self.assertEqual(s, 41) + # Overridden operators of an int subclass must not affect the + # result. + s = math.isqrt(BadIntSubclass(10**20)) + self.assertIs(type(s), int) + self.assertEqual(s, 10**10) + + s = math.isqrt(BadIntSubclass(10**20 - 1)) + self.assertIs(type(s), int) + self.assertEqual(s, 10**10 - 1) + with self.assertRaises(ValueError): math.isqrt(IntegerLike(-3)) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index e263487e0be..a7d1d724ff0 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -31,50 +31,11 @@ def tearDownModule(): mimetypes.knownfiles = knownfiles -class MimeTypesTestCase(unittest.TestCase): +class MimeTypesModuleTestCase(unittest.TestCase): def setUp(self): - self.db = mimetypes.MimeTypes() - - def test_case_sensitivity(self): - eq = self.assertEqual - eq(self.db.guess_file_type("foobar.html"), ("text/html", None)) - eq(self.db.guess_type("scheme:foobar.html"), ("text/html", None)) - eq(self.db.guess_file_type("foobar.HTML"), ("text/html", None)) - eq(self.db.guess_type("scheme:foobar.HTML"), ("text/html", None)) - eq(self.db.guess_file_type("foobar.tgz"), ("application/x-tar", "gzip")) - eq(self.db.guess_type("scheme:foobar.tgz"), ("application/x-tar", "gzip")) - eq(self.db.guess_file_type("foobar.TGZ"), ("application/x-tar", "gzip")) - eq(self.db.guess_type("scheme:foobar.TGZ"), ("application/x-tar", "gzip")) - eq(self.db.guess_file_type("foobar.tar.Z"), ("application/x-tar", "compress")) - eq(self.db.guess_type("scheme:foobar.tar.Z"), ("application/x-tar", "compress")) - eq(self.db.guess_file_type("foobar.tar.z"), (None, None)) - eq(self.db.guess_type("scheme:foobar.tar.z"), (None, None)) - - def test_default_data(self): - eq = self.assertEqual - eq(self.db.guess_file_type("foo.html"), ("text/html", None)) - eq(self.db.guess_file_type("foo.HTML"), ("text/html", None)) - eq(self.db.guess_file_type("foo.tgz"), ("application/x-tar", "gzip")) - eq(self.db.guess_file_type("foo.tar.gz"), ("application/x-tar", "gzip")) - eq(self.db.guess_file_type("foo.tar.Z"), ("application/x-tar", "compress")) - eq(self.db.guess_file_type("foo.tar.bz2"), ("application/x-tar", "bzip2")) - eq(self.db.guess_file_type("foo.tar.xz"), ("application/x-tar", "xz")) - - def test_data_urls(self): - eq = self.assertEqual - guess_type = self.db.guess_type - eq(guess_type("data:invalidDataWithoutComma"), (None, None)) - eq(guess_type("data:,thisIsTextPlain"), ("text/plain", None)) - eq(guess_type("data:;base64,thisIsTextPlain"), ("text/plain", None)) - eq(guess_type("data:text/x-foo,thisIsTextXFoo"), ("text/x-foo", None)) - - def test_file_parsing(self): - eq = self.assertEqual - sio = io.StringIO("x-application/x-unittest pyunit\n") - self.db.readfp(sio) - eq(self.db.guess_file_type("foo.pyunit"), - ("x-application/x-unittest", None)) - eq(self.db.guess_extension("x-application/x-unittest"), ".pyunit") + mimetypes.inited = False + mimetypes._default_mime_types() + mimetypes._db = None def test_read_mime_types(self): eq = self.assertEqual @@ -106,103 +67,49 @@ def test_read_mime_types(self): with unittest.mock.patch.object(mimetypes, 'open', return_value=fp) as mock_open: mime_dict = mimetypes.read_mime_types(filename) - mock_open.assert_called_with(filename, encoding='utf-8') + mock_open.assert_called_with(filename, encoding='utf-8', + errors='surrogateescape') eq(mime_dict[".Français"], "application/no-mans-land") - def test_non_standard_types(self): - eq = self.assertEqual - # First try strict - eq(self.db.guess_file_type('foo.xul', strict=True), (None, None)) - eq(self.db.guess_extension('image/jpg', strict=True), None) - # And then non-strict - eq(self.db.guess_file_type('foo.xul', strict=False), ('text/xul', None)) - eq(self.db.guess_file_type('foo.XUL', strict=False), ('text/xul', None)) - eq(self.db.guess_file_type('foo.invalid', strict=False), (None, None)) - eq(self.db.guess_extension('image/jpg', strict=False), '.jpg') - eq(self.db.guess_extension('image/JPG', strict=False), '.jpg') - - def test_filename_with_url_delimiters(self): - # bpo-38449: URL delimiters cases should be handled also. - # They would have different mime types if interpreted as URL as - # compared to when interpreted as filename because of the semicolon. - eq = self.assertEqual - gzip_expected = ('application/x-tar', 'gzip') - for name in ( - ';1.tar.gz', - '?1.tar.gz', - '#1.tar.gz', - '#1#.tar.gz', - ';1#.tar.gz', - ';&1=123;?.tar.gz', - '?k1=v1&k2=v2.tar.gz', - ): - for prefix in ('', '/', '\\', - 'c:', 'c:/', 'c:\\', 'c:/d/', 'c:\\d\\', - '//share/server/', '\\\\share\\server\\'): - path = prefix + name - with self.subTest(path=path): - eq(self.db.guess_file_type(path), gzip_expected) - eq(self.db.guess_type(path), gzip_expected) - expected = (None, None) if os.name == 'nt' else gzip_expected - for prefix in ('//', '\\\\', '//share/', '\\\\share\\'): - path = prefix + name - with self.subTest(path=path): - eq(self.db.guess_file_type(path), expected) - eq(self.db.guess_type(path), expected) - eq(self.db.guess_file_type(r" \"\`;b&b&c |.tar.gz"), gzip_expected) - eq(self.db.guess_type(r" \"\`;b&b&c |.tar.gz"), gzip_expected) + def test_read_mime_types_invalid_utf8_comment(self): + with os_helper.temp_dir() as directory: + data = (b"# non-UTF-8 comment: \x83\n" + b"x-application/x-unittest pyunit\n") + file = os.path.join(directory, "sample.mimetype") + with open(file, "wb") as f: + f.write(data) - eq(self.db.guess_file_type(r'foo/.tar.gz'), (None, 'gzip')) - eq(self.db.guess_type(r'foo/.tar.gz'), (None, 'gzip')) - expected = (None, 'gzip') if os.name == 'nt' else gzip_expected - eq(self.db.guess_file_type(r'foo\.tar.gz'), expected) - eq(self.db.guess_type(r'foo\.tar.gz'), expected) - eq(self.db.guess_type(r'scheme:foo\.tar.gz'), gzip_expected) + mime_dict = mimetypes.read_mime_types(file) + self.assertEqual( + mime_dict[".pyunit"], "x-application/x-unittest") + + db = mimetypes.MimeTypes() + db.read(file) + self.assertEqual( + db.guess_file_type("sample.pyunit")[0], + "x-application/x-unittest") + + mimetypes.init(files=[file]) + self.assertEqual( + mimetypes.guess_file_type("sample.pyunit")[0], + "x-application/x-unittest") + + def test_read_mime_types_invalid_utf8_type(self): + # A non-UTF-8 byte in a type or extension (not only in a comment) is + # preserved via surrogateescape, so the mapping is not corrupted. + with os_helper.temp_dir() as directory: + data = (b"x-application/x-unittest pyunit\n" + b"application/bad\x83 badext\x83\n") + file = os.path.join(directory, "sample.mimetype") + with open(file, "wb") as f: + f.write(data) - def test_url(self): - result = self.db.guess_type('http://example.com/host.html') - result = self.db.guess_type('http://host.html') - msg = 'URL only has a host name, not a file' - self.assertSequenceEqual(result, (None, None), msg) - result = self.db.guess_type('http://example.com/host.html') - msg = 'Should be text/html' - self.assertSequenceEqual(result, ('text/html', None), msg) - result = self.db.guess_type('http://example.com/host.html#x.tar') - self.assertSequenceEqual(result, ('text/html', None)) - result = self.db.guess_type('http://example.com/host.html?q=x.tar') - self.assertSequenceEqual(result, ('text/html', None)) + bad_type = b"application/bad\x83".decode("utf-8", "surrogateescape") + bad_ext = b".badext\x83".decode("utf-8", "surrogateescape") - def test_guess_all_types(self): - # First try strict. Use a set here for testing the results because if - # test_urllib2 is run before test_mimetypes, global state is modified - # such that the 'all' set will have more items in it. - all = self.db.guess_all_extensions('text/plain', strict=True) - self.assertTrue(set(all) >= {'.bat', '.c', '.h', '.ksh', '.pl', '.txt'}) - self.assertEqual(len(set(all)), len(all)) # no duplicates - # And now non-strict - all = self.db.guess_all_extensions('image/jpg', strict=False) - self.assertEqual(all, ['.jpg']) - # And now for no hits - all = self.db.guess_all_extensions('image/jpg', strict=True) - self.assertEqual(all, []) - # And now for type existing in both strict and non-strict mappings. - self.db.add_type('test-type', '.strict-ext') - self.db.add_type('test-type', '.non-strict-ext', strict=False) - all = self.db.guess_all_extensions('test-type', strict=False) - self.assertEqual(all, ['.strict-ext', '.non-strict-ext']) - all = self.db.guess_all_extensions('test-type') - self.assertEqual(all, ['.strict-ext']) - # Test that changing the result list does not affect the global state - all.append('.no-such-ext') - all = self.db.guess_all_extensions('test-type') - self.assertNotIn('.no-such-ext', all) - - def test_encoding(self): - filename = support.findfile("mime.types") - mimes = mimetypes.MimeTypes([filename]) - exts = mimes.guess_all_extensions('application/vnd.geocube+xml', - strict=True) - self.assertEqual(exts, ['.g3', '.g\xb3']) + mime_dict = mimetypes.read_mime_types(file) + self.assertEqual(mime_dict[".pyunit"], "x-application/x-unittest") + self.assertEqual(mime_dict[bad_ext], bad_type) def test_init_reinitializes(self): # Issue 4936: make sure an init starts clean @@ -336,6 +243,203 @@ def test_init_stability(self): self.assertEqual(types_map, mimetypes.types_map) self.assertEqual(common_types, mimetypes.common_types) + def test_init_files(self): + guess_file_type = mimetypes.guess_file_type + self.assertEqual(guess_file_type("file.test2")[0], None) + + filename = support.findfile("mime.types2") + mimetypes.init([filename]) + self.assertEqual(guess_file_type("file.test2")[0], "testing/test2") + + mimetypes.init() + self.assertEqual(guess_file_type("file.test2")[0], None) + + def test_init_knownfiles(self): + guess_file_type = mimetypes.guess_file_type + self.assertEqual(guess_file_type("file.test2")[0], None) + + filename = support.findfile("mime.types2") + mimetypes.knownfiles = [filename, "non-existent"] + self.addCleanup(mimetypes.knownfiles.clear) + + mimetypes.init() + self.assertEqual(guess_file_type("file.test2")[0], "testing/test2") + + def test_added_types_are_used(self): + mimetypes.add_type('testing/default-type', '') + mime_type, _ = mimetypes.guess_type('') + self.assertEqual(mime_type, 'testing/default-type') + + mime_type, _ = mimetypes.guess_type('test.myext') + self.assertEqual(mime_type, None) + + mimetypes.add_type('testing/type', '.myext') + mime_type, _ = mimetypes.guess_type('test.myext') + self.assertEqual(mime_type, 'testing/type') + + def test_add_type_with_undotted_extension_deprecated(self): + with self.assertWarns(DeprecationWarning): + mimetypes.add_type("testing/type", "undotted") + + +class MimeTypesClassTestCase(unittest.TestCase): + def setUp(self): + self.db = mimetypes.MimeTypes() + + def test_init_files(self): + guess_file_type = self.db.guess_file_type + self.assertEqual(guess_file_type("file.test2")[0], None) + + filename = support.findfile("mime.types2") + db = mimetypes.MimeTypes([filename]) + guess_file_type = db.guess_file_type + self.assertEqual(guess_file_type("file.test2")[0], "testing/test2") + + def test_init_knownfiles(self): + filename = support.findfile("mime.types2") + mimetypes.knownfiles = [filename, "non-existent"] + self.addCleanup(mimetypes.knownfiles.clear) + + db = mimetypes.MimeTypes() + guess_file_type = db.guess_file_type + self.assertEqual(guess_file_type("file.test2")[0], None) + + def test_case_sensitivity(self): + eq = self.assertEqual + eq(self.db.guess_file_type("foobar.html"), ("text/html", None)) + eq(self.db.guess_type("scheme:foobar.html"), ("text/html", None)) + eq(self.db.guess_file_type("foobar.HTML"), ("text/html", None)) + eq(self.db.guess_type("scheme:foobar.HTML"), ("text/html", None)) + eq(self.db.guess_file_type("foobar.tgz"), ("application/x-tar", "gzip")) + eq(self.db.guess_type("scheme:foobar.tgz"), ("application/x-tar", "gzip")) + eq(self.db.guess_file_type("foobar.TGZ"), ("application/x-tar", "gzip")) + eq(self.db.guess_type("scheme:foobar.TGZ"), ("application/x-tar", "gzip")) + eq(self.db.guess_file_type("foobar.tar.Z"), ("application/x-tar", "compress")) + eq(self.db.guess_type("scheme:foobar.tar.Z"), ("application/x-tar", "compress")) + eq(self.db.guess_file_type("foobar.tar.z"), (None, None)) + eq(self.db.guess_type("scheme:foobar.tar.z"), (None, None)) + + def test_default_data(self): + eq = self.assertEqual + eq(self.db.guess_file_type("foo.html"), ("text/html", None)) + eq(self.db.guess_file_type("foo.HTML"), ("text/html", None)) + eq(self.db.guess_file_type("foo.tgz"), ("application/x-tar", "gzip")) + eq(self.db.guess_file_type("foo.tar.gz"), ("application/x-tar", "gzip")) + eq(self.db.guess_file_type("foo.tar.Z"), ("application/x-tar", "compress")) + eq(self.db.guess_file_type("foo.tar.bz2"), ("application/x-tar", "bzip2")) + eq(self.db.guess_file_type("foo.tar.xz"), ("application/x-tar", "xz")) + + def test_data_urls(self): + eq = self.assertEqual + guess_type = self.db.guess_type + eq(guess_type("data:invalidDataWithoutComma"), (None, None)) + eq(guess_type("data:,thisIsTextPlain"), ("text/plain", None)) + eq(guess_type("data:;base64,thisIsTextPlain"), ("text/plain", None)) + eq(guess_type("data:text/x-foo,thisIsTextXFoo"), ("text/x-foo", None)) + + def test_file_parsing(self): + eq = self.assertEqual + sio = io.StringIO("x-application/x-unittest pyunit\n") + self.db.readfp(sio) + eq(self.db.guess_file_type("foo.pyunit"), + ("x-application/x-unittest", None)) + eq(self.db.guess_extension("x-application/x-unittest"), ".pyunit") + + def test_non_standard_types(self): + eq = self.assertEqual + # First try strict + eq(self.db.guess_file_type('foo.xul', strict=True), (None, None)) + eq(self.db.guess_extension('image/jpg', strict=True), None) + # And then non-strict + eq(self.db.guess_file_type('foo.xul', strict=False), ('text/xul', None)) + eq(self.db.guess_file_type('foo.XUL', strict=False), ('text/xul', None)) + eq(self.db.guess_file_type('foo.invalid', strict=False), (None, None)) + eq(self.db.guess_extension('image/jpg', strict=False), '.jpg') + eq(self.db.guess_extension('image/JPG', strict=False), '.jpg') + + def test_filename_with_url_delimiters(self): + # bpo-38449: URL delimiters cases should be handled also. + # They would have different mime types if interpreted as URL as + # compared to when interpreted as filename because of the semicolon. + eq = self.assertEqual + gzip_expected = ('application/x-tar', 'gzip') + for name in ( + ';1.tar.gz', + '?1.tar.gz', + '#1.tar.gz', + '#1#.tar.gz', + ';1#.tar.gz', + ';&1=123;?.tar.gz', + '?k1=v1&k2=v2.tar.gz', + ): + for prefix in ('', '/', '\\', + 'c:', 'c:/', 'c:\\', 'c:/d/', 'c:\\d\\', + '//share/server/', '\\\\share\\server\\'): + path = prefix + name + with self.subTest(path=path): + eq(self.db.guess_file_type(path), gzip_expected) + eq(self.db.guess_type(path), gzip_expected) + expected = (None, None) if os.name == 'nt' else gzip_expected + for prefix in ('//', '\\\\', '//share/', '\\\\share\\'): + path = prefix + name + with self.subTest(path=path): + eq(self.db.guess_file_type(path), expected) + eq(self.db.guess_type(path), expected) + eq(self.db.guess_file_type(r" \"\`;b&b&c |.tar.gz"), gzip_expected) + eq(self.db.guess_type(r" \"\`;b&b&c |.tar.gz"), gzip_expected) + + eq(self.db.guess_file_type(r'foo/.tar.gz'), (None, 'gzip')) + eq(self.db.guess_type(r'foo/.tar.gz'), (None, 'gzip')) + expected = (None, 'gzip') if os.name == 'nt' else gzip_expected + eq(self.db.guess_file_type(r'foo\.tar.gz'), expected) + eq(self.db.guess_type(r'foo\.tar.gz'), expected) + eq(self.db.guess_type(r'scheme:foo\.tar.gz'), gzip_expected) + + def test_url(self): + result = self.db.guess_type('http://example.com/host.html') + result = self.db.guess_type('http://host.html') + msg = 'URL only has a host name, not a file' + self.assertSequenceEqual(result, (None, None), msg) + result = self.db.guess_type('http://example.com/host.html') + msg = 'Should be text/html' + self.assertSequenceEqual(result, ('text/html', None), msg) + result = self.db.guess_type('http://example.com/host.html#x.tar') + self.assertSequenceEqual(result, ('text/html', None)) + result = self.db.guess_type('http://example.com/host.html?q=x.tar') + self.assertSequenceEqual(result, ('text/html', None)) + + def test_guess_all_types(self): + # First try strict. Use a set here for testing the results because if + # test_urllib2 is run before test_mimetypes, global state is modified + # such that the 'all' set will have more items in it. + all = self.db.guess_all_extensions('text/plain', strict=True) + self.assertTrue(set(all) >= {'.bat', '.c', '.h', '.ksh', '.pl', '.txt'}) + self.assertEqual(len(set(all)), len(all)) # no duplicates + # And now non-strict + all = self.db.guess_all_extensions('image/jpg', strict=False) + self.assertEqual(all, ['.jpg']) + # And now for no hits + all = self.db.guess_all_extensions('image/jpg', strict=True) + self.assertEqual(all, []) + # And now for type existing in both strict and non-strict mappings. + self.db.add_type('test-type', '.strict-ext') + self.db.add_type('test-type', '.non-strict-ext', strict=False) + all = self.db.guess_all_extensions('test-type', strict=False) + self.assertEqual(all, ['.strict-ext', '.non-strict-ext']) + all = self.db.guess_all_extensions('test-type') + self.assertEqual(all, ['.strict-ext']) + # Test that changing the result list does not affect the global state + all.append('.no-such-ext') + all = self.db.guess_all_extensions('test-type') + self.assertNotIn('.no-such-ext', all) + + def test_encoding(self): + filename = support.findfile("mime.types") + mimes = mimetypes.MimeTypes([filename]) + exts = mimes.guess_all_extensions('application/vnd.geocube+xml', + strict=True) + self.assertEqual(exts, ['.g3', '.g\xb3']) + def test_path_like_ob(self): filename = "LICENSE.txt" filepath = os_helper.FakePath(filename) @@ -375,22 +479,6 @@ def test_keywords_args_api(self): self.assertEqual(self.db.guess_extension( type='image/jpg', strict=False), '.jpg') - def test_added_types_are_used(self): - mimetypes.add_type('testing/default-type', '') - mime_type, _ = mimetypes.guess_type('') - self.assertEqual(mime_type, 'testing/default-type') - - mime_type, _ = mimetypes.guess_type('test.myext') - self.assertEqual(mime_type, None) - - mimetypes.add_type('testing/type', '.myext') - mime_type, _ = mimetypes.guess_type('test.myext') - self.assertEqual(mime_type, 'testing/type') - - def test_add_type_with_undotted_extension_deprecated(self): - with self.assertWarns(DeprecationWarning): - mimetypes.add_type("testing/type", "undotted") - @unittest.skipUnless(sys.platform.startswith("win"), "Windows only") class Win32MimeTypesTestCase(unittest.TestCase): diff --git a/Lib/test/test_pydoc/test_pydoc.py b/Lib/test/test_pydoc/test_pydoc.py index f44c56da652..fc6c830be00 100644 --- a/Lib/test/test_pydoc/test_pydoc.py +++ b/Lib/test/test_pydoc/test_pydoc.py @@ -2243,7 +2243,7 @@ def mock_getline(prompt): def test_keywords(self): self.assertEqual(sorted(pydoc.Helper.keywords), - sorted(keyword.kwlist)) + sorted(keyword.kwlist + ['case', 'match'])) def test_interact_empty_line_continues(self): # gh-138568: test pressing Enter without input should continue in help session diff --git a/Lib/test/test_pyrepl/test_interact.py b/Lib/test/test_pyrepl/test_interact.py index 65b1eed5bdd..7cbe523a92f 100644 --- a/Lib/test/test_pyrepl/test_interact.py +++ b/Lib/test/test_pyrepl/test_interact.py @@ -166,7 +166,6 @@ def g(x: int): ... self.assertFalse(result) self.assertEqual(f.getvalue(), "{'x': 'int'}\n") - @unittest.expectedFailure # TODO: RUSTPYTHON def test_future_barry_as_flufl(self): console = InteractiveColoredConsole() f = io.StringIO() diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py index 42f11c9eb28..40997a34e15 100644 --- a/Lib/test/test_set.py +++ b/Lib/test/test_set.py @@ -362,7 +362,6 @@ class C(object): gc.collect() self.assertTrue(ref() is None, "Cycle was not collected") - @unittest.skipIf("RUSTPYTHON_SKIP_ENV_POLLUTERS" in __import__("os").environ, "TODO: RUSTPYTHON") def test_free_after_iterating(self): support.check_free_after_iterating(self, iter, self.thetype) diff --git a/Lib/test/test_shlex.py b/Lib/test/test_shlex.py index 2a355abdeeb..a88dc286e4e 100644 --- a/Lib/test/test_shlex.py +++ b/Lib/test/test_shlex.py @@ -1,8 +1,11 @@ import io import itertools +import os import shlex import string +import tempfile import unittest +from unittest.mock import patch from test.support import cpython_only from test.support import import_helper @@ -368,6 +371,203 @@ def testPunctuationCharsReadOnly(self): with self.assertRaises(AttributeError): shlex_instance.punctuation_chars = False + def testLinenoAfterNewLine(self): + s = shlex.shlex("line 1\nline 2") + self.assertEqual(s.lineno, 1) # before consumption + list(s) + self.assertEqual(s.lineno, 2) + + def testLinenoAfterComment(self): + """Comment handler increments lineno even without a trailing newline.""" + s = shlex.shlex("line 1 # line 2") + list(s) + self.assertEqual(s.lineno, 2) + + def testPushToken(self): + s = shlex.shlex("b c") + s.push_token("a") + self.assertListEqual(list(s), ["a", "b", "c"]) + + def testPushTokenLifo(self): + s = shlex.shlex("") + s.push_token("first") + s.push_token("last") + self.assertListEqual(list(s), ["last", "first"]) + + def testPushTokenDebug(self): + s = shlex.shlex("") + s.debug = 1 + tok = "a" + with patch("builtins.print") as mock_print: + s.push_token(tok) + mock_print.assert_called_once_with(f"shlex: pushing token {tok!r}") + + def testPushSourceString(self): + s = shlex.shlex("world") + s.push_source("hello") + self.assertListEqual(list(s), ["hello", "world"]) + + def testPushSourceStream(self): + s = shlex.shlex("world") + s.push_source(io.StringIO("hello")) + self.assertListEqual(list(s), ["hello", "world"]) + + def testPushSourceStreamDebug(self): + s = shlex.shlex("") + stream = io.StringIO("hello") + s.debug = 1 + with patch("builtins.print") as mock_print: + s.push_source(stream) + mock_print.assert_called_once_with(f"shlex: pushing to stream {stream}") + + def testPushSourceNewfile(self): + """shlex.push_source sets infile to newfile; pop_source restores the original on exhaustion.""" + original_file = "original.sh" + new_file = "new.sh" + s = shlex.shlex("b", infile=original_file) + s.debug = 1 + with patch("builtins.print") as mock_print: + s.push_source("a", newfile=new_file) + mock_print.assert_called_once_with(f"shlex: pushing to file {new_file}") + self.assertEqual(s.infile, new_file) + s.debug = 0 + list(s) + self.assertEqual(s.infile, original_file) + + def testPopSourceDebug(self): + """pop_source emits debug output when debug is set.""" + s = shlex.shlex("b") + original_stream = s.instream + s.push_source("a") + s.debug = 1 + with patch("builtins.print") as mock_print: + list(s) # exhausts pushed source and triggers pop_source internally + mock_print.assert_any_call(f"shlex: popping to {original_stream}, line 1") + + def testErrorLeaderTracksPosition(self): + infile_label = "test.sh" + s = shlex.shlex("line 1\nline 2", infile=infile_label) + list(s) + result = s.error_leader() + self.assertEqual(result, f'"{infile_label}", line 2: ') + + def testErrorLeaderOverrides(self): + s = shlex.shlex("foo", infile="original.sh") + infile_label_override = "override.sh" + lineno_override = 42 + result = s.error_leader(infile=infile_label_override, lineno=lineno_override) + self.assertEqual(result, f'"{infile_label_override}", line {lineno_override}: ') + + def testNoClosingQuotation(self): + s = shlex.shlex('"foo') + with self.assertRaisesRegex(ValueError, "No closing quotation"): + list(s) + + def testNoEscapedCharacter(self): + s = shlex.shlex("\\", posix=True) + with self.assertRaisesRegex(ValueError, "No escaped character"): + list(s) + + def testSourcehookStripsQuotes(self): + with tempfile.NamedTemporaryFile(mode="w", suffix=".sh", delete_on_close=False) as f: + f.write("hello") + f.close() + s = shlex.shlex("") + newfile, stream = s.sourcehook(f'"{f.name}"') + stream.close() + self.assertEqual(newfile, f.name) + + def testSourcehookAbsolutePath(self): + with tempfile.NamedTemporaryFile(mode="w", delete_on_close=False) as f: + f.close() + s = shlex.shlex("", infile="/some/dir/main.sh") + newfile, stream = s.sourcehook(f.name) + stream.close() + self.assertEqual(newfile, f.name) + + def testSourcehookRelativePath(self): + with tempfile.TemporaryDirectory() as d: + fpath = os.path.join(d, "included.sh") + with open(fpath, "w"): + pass + s = shlex.shlex("", infile=os.path.join(d, "main.sh")) + newfile, stream = s.sourcehook("included.sh") + stream.close() + self.assertEqual(newfile, fpath) + + def testSourceInclusion(self): + """shlex.source sets a trigger keyword: when the lexer reads a token equal + to it, the next token is consumed as a filename and passed to + sourcehook, which returns a stream to push onto the input stack. + Tokens flow from that stream first, then resume from the original. + """ + s = shlex.shlex("trigger filename remaining") + s.source = "trigger" + s.sourcehook = lambda f: (f, io.StringIO("included")) + self.assertEqual(list(s), ["included", "remaining"]) + + def testGetTokenPopsPushbackDebug(self): + s = shlex.shlex("") + s.push_token("hello") + s.debug = 1 # set after push_token to isolate the pop-token branch + with patch("builtins.print") as mock_print: + tok = s.get_token() + self.assertEqual(tok, "hello") + mock_print.assert_called_once_with("shlex: popping token 'hello'") + + def testDebugWhitespaceInWhitespaceState(self): + s = shlex.shlex(" a") + s.debug = 2 + with patch("builtins.print") as mock_print: + list(s) + mock_print.assert_any_call("shlex: I see whitespace in whitespace state") + + def testDebugWhitespaceInWordState(self): + s = shlex.shlex("a b") + s.debug = 2 + with patch("builtins.print") as mock_print: + list(s) + mock_print.assert_any_call("shlex: I see whitespace in word state") + + def testDebugPunctuationInWordState(self): + s = shlex.shlex("a(") + s.debug = 2 + with patch("builtins.print") as mock_print: + list(s) + mock_print.assert_any_call("shlex: I see punctuation in word state") + + def testDebugRawToken(self): + s = shlex.shlex("hello") + s.debug = 2 + with patch("builtins.print") as mock_print: + list(s) + mock_print.assert_any_call("shlex: raw token='hello'") + + def testDebugEOFInQuote(self): + s = shlex.shlex('"oops', posix=True) + s.debug = 2 + with patch('builtins.print') as mock_print: + with self.assertRaises(ValueError): + list(s) + msgs = [call.args[0] for call in mock_print.call_args_list] + self.assertTrue(any("EOF in quotes" in m for m in msgs)) + + def testDebugEOFInEscape(self): + s = shlex.shlex("oops\\", posix=True) + s.debug = 2 + with patch("builtins.print") as mock_print: + with self.assertRaises(ValueError): + list(s) + msgs = [call.args[0] for call in mock_print.call_args_list] + self.assertTrue(any("EOF in escape" in m for m in msgs)) + + def testDebugStateTrace(self): + s = shlex.shlex("a") + s.debug = 3 + with patch("builtins.print") as mock_print: + list(s) + mock_print.assert_any_call("shlex: in state ' ' I see character: 'a'") + @cpython_only def test_lazy_imports(self): import_helper.ensure_lazy_imports('shlex', {'collections', 're', 'os'}) diff --git a/Lib/test/test_str.py b/Lib/test/test_str.py index 2a3c36f2e57..4869c5ca9b0 100644 --- a/Lib/test/test_str.py +++ b/Lib/test/test_str.py @@ -2606,7 +2606,6 @@ def test_compare(self): self.assertTrue(astral >= bmp2) self.assertFalse(astral >= astral2) - @unittest.skip("TODO: RUSTPYTHON; hangs") def test_free_after_iterating(self): support.check_free_after_iterating(self, iter, str) if not support.Py_GIL_DISABLED: diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index f828b778659..b01f002c12b 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -181,6 +181,16 @@ def test_calcsize(self): self.assertGreaterEqual(struct.calcsize('n'), struct.calcsize('i')) self.assertGreaterEqual(struct.calcsize('n'), struct.calcsize('P')) + def test_cache_bytes_vs_str_bb(self): + # Mixing str and bytes formats must not raise BytesWarning under -bb. + code = ( + 'import struct\n' + 'struct.calcsize(b"!d"); struct.calcsize("!d")\n' + 'struct.calcsize(">d"); struct.calcsize(b">d")\n' + 'struct.Struct(b"i"); struct.Struct("i")\n' + ) + assert_python_ok('-bb', '-c', code) + def test_integers(self): # Integer tests (bBhHiIlLqQnN). import binascii diff --git a/Lib/test/test_super.py b/Lib/test/test_super.py index 4d338bbbc5a..cde2352e6e1 100644 --- a/Lib/test/test_super.py +++ b/Lib/test/test_super.py @@ -90,7 +90,6 @@ def nested(): self.assertEqual(E().f(), 'AE') - @unittest.expectedFailure # TODO: RUSTPYTHON def test_various___class___pathologies(self): # See issue #12370 class X(A): diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index 42aa7e3d9bb..5885ab238ae 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -17,6 +17,7 @@ import warnings from test import support +from test.support import isolation from test.support import import_helper from test.support import os_helper from test.support import script_helper @@ -833,5 +834,150 @@ def test_linked_to_musl(self): # SuppressCrashReport +class TestIsolated(unittest.TestCase): + # Drive the sample tests in test._isolated_sample (which really spawn + # subprocesses through @isolation.runInSubprocess()) under a private + # TestResult, and check that each subprocess outcome is replayed in the parent. + + @staticmethod + def _run(name): + suite = unittest.TestLoader().loadTestsFromName( + 'test._isolated_sample.' + name) + result = unittest.TestResult() + suite.run(result) + return result + + @staticmethod + def _names(items): + # Map outcome entries (which are (test, detail) pairs, except + # unexpectedSuccesses which are bare tests) to their method names. + names = [] + for item in items: + test = item[0] if isinstance(item, tuple) else item + names.append(test.id().rpartition('.')[2]) + return sorted(names) + + @support.requires_subprocess() + def test_method_outcomes(self): + result = self._run('MethodSample') + self.assertEqual(result.testsRun, 6) + self.assertEqual(self._names(result.failures), ['test_fail']) + self.assertEqual(self._names(result.errors), ['test_error']) + self.assertEqual(self._names(result.skipped), ['test_skip']) + self.assertEqual(self._names(result.expectedFailures), + ['test_expected_failure']) + self.assertEqual(self._names(result.unexpectedSuccesses), + ['test_unexpected_success']) + + @support.requires_subprocess() + def test_class_outcomes(self): + result = self._run('ClassSample') + self.assertEqual(result.testsRun, 3) + self.assertEqual(self._names(result.failures), ['test_fail']) + self.assertEqual(self._names(result.expectedFailures), + ['test_expected_failure']) + self.assertEqual(result.errors, []) + self.assertEqual(result.unexpectedSuccesses, []) + + @support.requires_subprocess() + def test_subtests_reported_individually(self): + result = self._run('SubtestSample') + self.assertEqual(result.testsRun, 1) + self.assertEqual(len(result.failures), 1) + test, _ = result.failures[0] + self.assertIn('i=1', str(test)) + + @support.requires_subprocess() + def test_skip_reason_propagated(self): + result = self._run('MethodSample.test_skip') + self.assertEqual([reason for _, reason in result.skipped], ['nope']) + + @support.requires_subprocess() + def test_subprocess_traceback_is_cause(self): + result = self._run('MethodSample.test_fail') + self.assertEqual(len(result.failures), 1) + _, tb = result.failures[0] + # The real assertion that failed in the subprocess is shown ... + self.assertIn('self.assertEqual(1, 2)', tb) + # ... as the direct cause of the replayed failure ... + self.assertIn('direct cause', tb) + # ... without leaking the parent-side replay frames. + self.assertNotIn('isolation.py', tb) + + @support.requires_subprocess() + def test_durations_forwarded_for_class(self): + from test._isolated_sample import DURATION_SLEEP + result = unittest.TestResult() + suite = unittest.TestLoader().loadTestsFromName( + 'test._isolated_sample.DurationSample') + suite.run(result) + # The duration reported in the parent is the one measured in the + # subprocess (around the sleep), not the near-instant replay time. + self.assertEqual(len(result.collectedDurations), 1) + name, elapsed = result.collectedDurations[0] + self.assertEqual(name.split()[0], 'test_slow') + self.assertGreaterEqual(elapsed, DURATION_SLEEP / 2) + + @support.requires_subprocess() + def test_subclass_of_isolated_class(self): + # Both samples pass only if the fixtures are bound to the runtime class + # and what the subclass adds or overrides runs in the subprocess. + for name, count in (('SubclassingSample', 1), ('SubclassSample', 2)): + with self.subTest(sample=name): + result = self._run(name) + self.assertEqual(result.testsRun, count) + self.assertEqual(result.failures, []) + self.assertEqual(result.errors, []) + + @support.requires_subprocess() + def test_subclass_bypassing_setupclass_is_reported(self): + # A class that never ran in a subprocess must error out, not pass with + # no outcome to replay. + result = self._run('BrokenSubclassSample') + self.assertEqual(result.testsRun, 1) + self.assertEqual(len(result.errors), 1) + self.assertIn('did not run in a subprocess', result.errors[0][1]) + + @support.requires_subprocess() + def test_subprocess_dying_after_the_test_is_reported(self): + from test._isolated_sample import EXIT_CODE + result = self._run('MethodExitSample.test_passes_then_dies') + self.assertEqual(result.testsRun, 1) + self.assertEqual(len(result.errors), 1) + self.assertIn(f'exited with code {EXIT_CODE}', result.errors[0][1]) + + @support.requires_subprocess() + def test_subprocess_dying_does_not_hide_the_failure(self): + result = self._run('MethodExitSample.test_fails_and_dies') + self.assertEqual(self._names(result.failures), ['test_fails_and_dies']) + self.assertEqual(result.errors, []) + + @support.requires_subprocess() + def test_class_subprocess_dying_after_the_tests_is_reported(self): + # The tests that ran are still reported, and the crash once, for the class. + from test._isolated_sample import EXIT_CODE + result = self._run('ClassExitSample') + self.assertEqual(result.testsRun, 2) + self.assertEqual(result.failures, []) + self.assertEqual(len(result.errors), 1) + self.assertIn('tearDownClass', str(result.errors[0][0])) + self.assertIn(f'exited with code {EXIT_CODE}', result.errors[0][1]) + + def test_skipped_without_subprocess_support(self): + # On a platform without subprocess support the test is skipped in the + # parent, before any subprocess is spawned. + calls = [] + orig = isolation._run_in_subprocess + with support.swap_attr(support, 'has_subprocess_support', False): + isolation._run_in_subprocess = lambda *a, **k: calls.append(a) + try: + result = self._run('MethodSample.test_pass') + finally: + isolation._run_in_subprocess = orig + self.assertEqual(result.testsRun, 1) + self.assertEqual(len(result.skipped), 1) + self.assertEqual(calls, []) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_symtable.py b/Lib/test/test_symtable.py index 16204bc45dd..9537de3756f 100644 --- a/Lib/test/test_symtable.py +++ b/Lib/test/test_symtable.py @@ -299,7 +299,6 @@ def test_symbol_lookup(self): self.assertRaises(KeyError, self.top.lookup, "not_here") - @unittest.expectedFailure # TODO: RUSTPYTHON def test_namespaces(self): self.assertTrue(self.top.lookup("Mine").is_namespace()) self.assertTrue(self.Mine.lookup("a_method").is_namespace()) @@ -360,7 +359,6 @@ def test_name(self): self.assertEqual(self.spam.lookup("x").get_name(), "x") self.assertEqual(self.Mine.get_name(), "Mine") - @unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: Tuples differ: () != ('a_method',) def test_class_get_methods(self): deprecation_mess = ( re.escape('symtable.Class.get_methods() is deprecated ' @@ -442,7 +440,6 @@ def check_body(body, expected_methods): check_body('\n'.join((gen, func)), ('genexpr',)) check_body('\n'.join((func, gen)), ('genexpr',)) - @unittest.expectedFailure # TODO: RUSTPYTHON; SyntaxError: name 'x' is parameter and global def test_filename_correct(self): ### Bug tickler: SyntaxError file name correct whether error raised ### while parsing or building symbol table. @@ -474,7 +471,6 @@ def test_single(self): def test_exec(self): symbols = symtable.symtable("def f(x): return x", "?", "exec") - @unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: Expected type 'str' but 'bytes' found. def test_bytes(self): top = symtable.symtable(TEST_CODE.encode('utf8'), "?", "exec") self.assertIsNotNone(find_block(top, "Mine")) @@ -563,7 +559,6 @@ def test_loopvar_in_only_one_scope(self): class CommandLineTest(unittest.TestCase): maxDiff = None - @unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: Expected type 'str' but 'bytes' found. def test_file(self): filename = os_helper.TESTFN self.addCleanup(os_helper.unlink, filename) diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 5013eb096f5..6dab7dfa102 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -684,7 +684,7 @@ SyntaxError: Generator expression must be parenthesized >>> f((x for x in L), 1) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ->>> class C(x for x in L): # TODO: RUSTPYTHON; Wrong error message # doctest: +EXPECTED_FAILURE +>>> class C(x for x in L): ... pass Traceback (most recent call last): SyntaxError: invalid syntax diff --git a/Lib/test/test_thread.py b/Lib/test/test_thread.py index ebb193eabda..a88051bd44a 100644 --- a/Lib/test/test_thread.py +++ b/Lib/test/test_thread.py @@ -323,7 +323,6 @@ def test_set_done_unstarted(self): with self.assertRaisesRegex(RuntimeError, "thread not started"): handle._set_done() - @unittest.skipIf(__import__("sys").platform == "linux", "TODO: RUSTPYTHON; panic") def test_start_duplicate_handle(self): lock = thread.allocate_lock() lock.acquire() @@ -339,7 +338,6 @@ def func(): lock.release() handle.join() - @unittest.skipIf(__import__("sys").platform == "linux", "TODO: RUSTPYTHON; panic") def test_start_with_none_handle(self): def func(): pass diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py index 40f8e7a1005..4280e8d450b 100644 --- a/Lib/test/test_unicodedata.py +++ b/Lib/test/test_unicodedata.py @@ -306,9 +306,9 @@ def test_category(self): self.assertRaises(TypeError, self.db.category) self.assertRaises(TypeError, self.db.category, 'xx') - @unittest.expectedFailure # TODO: RUSTPYTHON; - 'BN' != '' + # NOTE: RUSTPYTHON; This test is from 3.15. See RustPython#8548 for motivation. def test_bidirectional(self): - self.assertEqual(self.db.bidirectional('\uFFFE'), '') + self.assertEqual(self.db.bidirectional('\uFFFE'), '' if self.old else 'BN') self.assertEqual(self.db.bidirectional(' '), 'WS') self.assertEqual(self.db.bidirectional('A'), 'L') self.assertEqual(self.db.bidirectional('\U00020000'), 'L') @@ -329,6 +329,9 @@ def test_bidirectional(self): # New in 16.0.0 self.assertEqual(self.db.bidirectional('\u0897'), '' if self.old else 'NSM') self.assertEqual(self.db.bidirectional('\U0001fbef'), '' if self.old else 'ON') + # New in 17.0.0 + self.assertEqual(self.db.bidirectional('\u088f'), '' if self.old else 'AL') + self.assertEqual(self.db.bidirectional('\U0001fbfa'), '' if self.old else 'ON') self.assertRaises(TypeError, self.db.bidirectional) self.assertRaises(TypeError, self.db.bidirectional, 'xx') diff --git a/README.md b/README.md index cb086687d8f..9da54c4b4ee 100644 --- a/README.md +++ b/README.md @@ -120,7 +120,7 @@ cargo build --target wasm32-wasip1 --no-default-features --features freeze-stdli Run by wasmer ```bash -wasmer run --dir `pwd` -- target/wasm32-wasip1/release/rustpython.wasm `pwd`/extra_tests/snippets/stdlib_random.py +wasmer run --volume `pwd` -- target/wasm32-wasip1/release/rustpython.wasm `pwd`/extra_tests/snippets/stdlib_random.py ``` Run by wapm diff --git a/crates/codegen/src/compile.rs b/crates/codegen/src/compile.rs index fe0a983187a..8a4a37319d4 100644 --- a/crates/codegen/src/compile.rs +++ b/crates/codegen/src/compile.rs @@ -12,8 +12,9 @@ use crate::{ IndexMap, IndexSet, ToPythonName, ast_constant_value_to_constant_data, error::{CodegenError, CodegenErrorType, InternalError}, + interpolated_string_literal_value, interpolation_debug_text, ir::{self, Block, BlockIdx, Blocks}, - preprocess, + preprocess, string_literal_part_value, string_literal_value, symboltable::{self, CompilerScope, Symbol, SymbolFlags, SymbolScope, SymbolTable}, unparse::UnparseExpr, }; @@ -22,7 +23,7 @@ use core::{mem, slice}; use malachite_bigint::BigInt; use num_complex::Complex; use num_traits::{Num, ToPrimitive, Zero}; -use ruff_python_ast as ast; +use ruff_python_ast::{self as ast, name::Name}; use ruff_text_size::{Ranged, TextRange, TextSize}; use rustpython_compiler_core::{ Mode, OneIndexed, PositionEncoding, SourceFile, SourceLocation, @@ -144,9 +145,9 @@ fn checked_future_features( source_file: &SourceFile, ) -> CompileResult { preprocess::checked_future_features(ast).map_err(|err| { - let location = source_file - .to_source_code() - .source_location(err.range.start(), PositionEncoding::Utf8); + let source_code = source_file.to_source_code(); + let location = source_code.source_location(err.range.start(), PositionEncoding::Utf8); + let end_location = source_code.source_location(err.range.end(), PositionEncoding::Utf8); let error = match err.kind { preprocess::FutureFeatureErrorKind::InvalidFeature(feature) => { CodegenErrorType::InvalidFutureFeature(feature) @@ -157,6 +158,7 @@ fn checked_future_features( }; CodegenError { location: Some(location), + end_location: Some(end_location), error, source_path: source_file.name().to_owned(), } @@ -176,7 +178,6 @@ struct Compiler<'a> { source_file: SourceFile, // current_source_location: SourceLocation, current_source_range: TextRange, - done_with_future_stmts: DoneWithFuture, future_features: bytecode::CodeFlags, future_annotations: bool, ctx: CompileContext, @@ -194,13 +195,6 @@ struct Compiler<'a> { syntax_warning_handler: Option<&'a mut SyntaxWarningHandler<'a>>, } -#[derive(Clone, Copy)] -enum DoneWithFuture { - No, - DoneWithDoc, - Yes, -} - /// A Python `__future__` feature flag imported via `from __future__ import `. /// /// # See Also @@ -675,7 +669,7 @@ fn compiler_unwrap_option(zelf: &Compiler<'_>, o: Option) -> T { #[derive(Clone)] pub struct PatternContext { /// A list of names captured by the pattern. - pub stores: Vec, + pub stores: Vec, /// If false, then any name captures against our subject will raise. pub allow_irrefutable: bool, /// A list of jump target labels used on pattern failure. @@ -1115,7 +1109,6 @@ impl<'warnings> Compiler<'warnings> { source_file, // current_source_location: SourceLocation::default(), current_source_range: TextRange::default(), - done_with_future_stmts: DoneWithFuture::No, future_features: opts.future_features, future_annotations: false, ctx: CompileContext { @@ -1268,7 +1261,7 @@ impl<'warnings> Compiler<'warnings> { fn starunpack_helper_impl( &mut self, elts: &[ast::Expr], - injected_arg: Option<&str>, + injected_arg: Option<&Name>, pushed: u32, collection_type: CollectionType, ) -> CompileResult<()> { @@ -1430,13 +1423,13 @@ impl<'warnings> Compiler<'warnings> { } fn error_ranged(&mut self, error: CodegenErrorType, range: TextRange) -> CodegenError { - let location = self - .source_file - .to_source_code() - .source_location(range.start(), PositionEncoding::Utf8); + let source_code = self.source_file.to_source_code(); + let location = source_code.source_location(range.start(), PositionEncoding::Utf8); + let end_location = source_code.source_location(range.end(), PositionEncoding::Utf8); CodegenError { error, location: Some(location), + end_location: Some(end_location), source_path: self.source_file.name().to_owned(), } } @@ -1451,6 +1444,7 @@ impl<'warnings> Compiler<'warnings> { None => CodegenError { error, location: None, + end_location: None, source_path: self.source_file.name().to_owned(), }, } @@ -1713,7 +1707,7 @@ impl<'warnings> Compiler<'warnings> { // 5. "super" must be GlobalImplicit in the current scope. let table = self.current_symbol_table(); - if let Some(symbol) = table.lookup("super") + if let Some(symbol) = table.lookup(&"super".into()) && symbol.scope != SymbolScope::GlobalImplicit { return None; @@ -1721,7 +1715,7 @@ impl<'warnings> Compiler<'warnings> { // Then check the top-level scope and reject any statically // visible symbol for "super", not just local bindings. if let Some(top_table) = self.symbol_table_stack.first() - && top_table.lookup("super").is_some() + && top_table.lookup(&"super".into()).is_some() { return None; } @@ -1753,7 +1747,7 @@ impl<'warnings> Compiler<'warnings> { // Check if __class__ is available as a cell/free variable // The scope must be Free (from enclosing class) or have DEF_FREE_CLASS flag { - let symbol = table.lookup("__class__")?; + let symbol = table.lookup(&"__class__".into())?; if symbol.scope != SymbolScope::Free && !symbol.flags.contains(SymbolFlags::DEF_FREE_CLASS) { @@ -1777,7 +1771,7 @@ impl<'warnings> Compiler<'warnings> { ) -> CompileResult<()> { // 1. Load global super self.set_source_range(super_name_range); - self.compile_name("super", NameUsage::Load)?; + self.compile_name(&"super".into(), NameUsage::Load)?; match super_type { SuperCallType::TwoArg { @@ -1792,7 +1786,9 @@ impl<'warnings> Compiler<'warnings> { // 0-arg: load __class__ cell and first parameter // Load __class__ from cell/free variable self.set_source_range(super_call_range); - let scope = self.get_ref_type("__class__").map_err(|e| self.error(e))?; + let scope = self + .get_ref_type(&"__class__".into()) + .map_err(|e| self.error(e))?; let idx = match scope { SymbolScope::Cell => self.get_cell_var_index("__class__"), SymbolScope::Free => self.get_free_var_index("__class__"), @@ -1817,7 +1813,7 @@ impl<'warnings> Compiler<'warnings> { )) })?; self.set_source_range(super_call_range); - self.compile_name(&first_param, NameUsage::Load)?; + self.compile_name(&first_param.into(), NameUsage::Load)?; } } Ok(()) @@ -1861,7 +1857,7 @@ impl<'warnings> Compiler<'warnings> { }; // Use varnames from symbol table (already collected in definition order) - let varname_cache: IndexSet = ste.varnames.iter().cloned().collect(); + let varname_cache: IndexSet = ste.varnames.iter().cloned().collect(); let nparams = ste.varnames.len(); // Build cellvars using dictbytype (CELL scope or COMP_CELL flag, sorted) @@ -1876,7 +1872,7 @@ impl<'warnings> Compiler<'warnings> { .collect(); cell_names.sort(); for name in cell_names { - cellvar_cache.insert(name); + cellvar_cache.insert(name.into()); } // Handle implicit __class__ cell if needed @@ -1900,7 +1896,7 @@ impl<'warnings> Compiler<'warnings> { // Build freevars using dictbytype (FREE scope, offset by cellvars size) let mut freevar_cache = IndexSet::default(); - let annotation_free_names: IndexSet = ste + let annotation_free_names: IndexSet = ste .annotation_block .as_ref() .map(|annotation| { @@ -1936,7 +1932,14 @@ impl<'warnings> Compiler<'warnings> { .collect(); free_names.sort(); for name in free_names { - freevar_cache.insert(name); + freevar_cache.insert(name.into()); + } + + // The `__conditional_annotations__` cell an annotation scope reads is + // cooked up here rather than carried by the symbol table, so it lands + // after the names the symbol table did supply. + if scope_type == CompilerScope::Annotation && ste.has_conditional_annotations { + freevar_cache.insert("__conditional_annotations__".to_string()); } // Initialize u_metadata fields @@ -2022,7 +2025,7 @@ impl<'warnings> Compiler<'warnings> { qualname: None, // Will be set below consts: Default::default(), names: IndexSet::default(), - varnames: varname_cache, + varnames: varname_cache.into_iter().map(Into::into).collect(), cellvars: cellvar_cache, freevars: freevar_cache, fast_hidden: IndexMap::default(), @@ -2129,6 +2132,7 @@ impl<'warnings> Compiler<'warnings> { | bytecode::CodeFlags::FUTURE_WITH_STATEMENT | bytecode::CodeFlags::FUTURE_PRINT_FUNCTION | bytecode::CodeFlags::FUTURE_UNICODE_LITERALS + | bytecode::CodeFlags::FUTURE_BARRY_AS_BDFL | bytecode::CodeFlags::FUTURE_GENERATOR_STOP | bytecode::CodeFlags::FUTURE_ANNOTATIONS)); info.metadata.argcount = arg_count; @@ -2159,6 +2163,12 @@ impl<'warnings> Compiler<'warnings> { } } + fn configure_annotation_format_parameter(&mut self) { + let info = self.current_code_info(); + info.metadata.varnames.insert(".format".to_owned()); + info.nparams = 1; + } + /// Exit a function signature annotation scope. fn exit_annotation_scope(&mut self, saved_ctx: CompileContext) -> CodeObject { self.pop_annotation_symbol_table(); @@ -2208,10 +2218,7 @@ impl<'warnings> Compiler<'warnings> { // Keep the internal ".format" name; exit_annotation_scope() // renames it to "format" on the final code object. - self.current_code_info() - .metadata - .varnames - .insert(".format".to_owned()); + self.configure_annotation_format_parameter(); // Emit format validation: if format > VALUE_WITH_FAKE_GLOBALS: raise NotImplementedError // VALUE_WITH_FAKE_GLOBALS = 2 (from annotationlib.Format) @@ -2407,10 +2414,22 @@ impl<'warnings> Compiler<'warnings> { if let FBlockDatum::FinallyBody(ref body) = info.fb_datum { // This is an extra copy of the finally body, emitted for the - // path that leaves the try block early. The try statement - // emits its own copies afterwards, so rewind the symbol table - // cursors and leave the nested scopes for those copies. + // path that leaves the try block early. Nested scopes are + // handed out by position, and the cursors are still inside + // the try block's own run of scopes here, so seek them to the + // ones this body opened before compiling it. The try + // statement emits its own copies from the same place + // afterwards, so put the cursors back when the copy is done. let symbol_table_cursors = self.current_symbol_table_cursors(); + if let Some(first) = body.first() { + let line = self + .source_file + .to_source_code() + .line_index(first.range().start()) + .get() + .to_u32(); + self.seek_symbol_table_cursors_to_line(line); + } self.compile_statements(body)?; self.set_symbol_table_cursors(symbol_table_cursors); } @@ -2511,10 +2530,10 @@ impl<'warnings> Compiler<'warnings> { self.emit_load_const(ConstantData::None); self.mark_unwind_no_location(*loc); self.set_unwind_source_range(*loc); - self.store_name(name)?; + self.store_name(&name.into())?; self.mark_unwind_no_location(*loc); self.set_unwind_source_range(*loc); - self.compile_name(name, NameUsage::Delete)?; + self.compile_name(&name.into(), NameUsage::Delete)?; self.mark_unwind_no_location(*loc); } } @@ -2606,11 +2625,12 @@ impl<'warnings> Compiler<'warnings> { name: &str, cache: impl FnOnce(&mut ir::CodeInfo) -> &mut IndexSet, ) -> u32 { - let name = self.mangle(name); + let target = name.into(); + let name = self.mangle(&target); let cache = cache(self.current_code_info()); cache - .get_index_of(name.as_ref()) - .unwrap_or_else(|| cache.insert_full(name.into_owned()).0) + .get_index_of(name.as_str()) + .unwrap_or_else(|| cache.insert_full(name.to_string()).0) .to_u32() } @@ -2621,9 +2641,9 @@ impl<'warnings> Compiler<'warnings> { } /// Set the qualname of an annotation scope, qualified by the function whose - /// signature it annotates. CPython records that name on the annotation - /// block's symbol table entry (`ste_function_name`) and folds it into the - /// qualname, so `f`'s annotation scope is named `f.__annotate__`. + /// signature it annotates. The annotation block's symbol table entry records + /// that name (`ste_function_name`) and folds it into the qualname, so `f`'s + /// annotation scope is named `f.__annotate__`. fn set_annotation_qualname(&mut self, function_name: &str) { self.set_qualname_for_function(Some(function_name)); } @@ -2697,14 +2717,15 @@ impl<'warnings> Compiler<'warnings> { // We might be in a situation where symbol table isn't pushed yet // In this case, check the parent symbol table if let Some(parent_table) = self.symbol_table_stack.last() - && let Some(symbol) = parent_table.lookup(¤t_obj_name) + && let Some(symbol) = parent_table.lookup(¤t_obj_name.clone().into()) && symbol.scope == SymbolScope::GlobalExplicit { force_global = true; } } else if let Some(_current_table) = self.symbol_table_stack.last() { // Mangle the name if necessary (for private names in classes) - let mangled_name = self.mangle(¤t_obj_name); + let target = ¤t_obj_name.clone().into(); + let mangled_name = self.mangle(target); // Look up in parent symbol table to check scope if self.symbol_table_stack.len() >= 2 { @@ -2808,7 +2829,7 @@ impl<'warnings> Compiler<'warnings> { if Self::scope_needs_conditional_annotations_cell(self.current_symbol_table()) { self.set_source_range(module_start_loc); emit!(self, Instruction::BuildSet { count: 0 }); - self.store_name("__conditional_annotations__")?; + self.store_name(&"__conditional_annotations__".into())?; } if self.future_annotations && annotations_used { @@ -2866,6 +2887,15 @@ impl<'warnings> Compiler<'warnings> { .flags .insert(bytecode::CodeFlags::COROUTINE); } + + // Module-level __conditional_annotations__ cell + if Self::scope_needs_conditional_annotations_cell(&symbol_table) { + self.current_code_info() + .metadata + .cellvars + .insert("__conditional_annotations__".to_string()); + } + self.symbol_table_stack.push(symbol_table); let module_start_loc = self.module_start_location(body); @@ -2877,7 +2907,7 @@ impl<'warnings> Compiler<'warnings> { if self.current_symbol_table().has_conditional_annotations { self.set_source_range(module_start_loc); emit!(self, Instruction::BuildSet { count: 0 }); - self.store_name("__conditional_annotations__")?; + self.store_name(&"__conditional_annotations__".into())?; } if self.future_annotations && annotations_used { @@ -2929,7 +2959,7 @@ impl<'warnings> Compiler<'warnings> { }) => { validate_duplicate_params(parameters).map_err(|e| self.error(e))?; self.compile_function_def( - name.as_str(), + name.id(), parameters, body, decorator_list, @@ -2948,7 +2978,7 @@ impl<'warnings> Compiler<'warnings> { .. }) => { self.compile_class_def( - name.as_str(), + name.id(), body, decorator_list, type_params.as_deref(), @@ -2987,6 +3017,9 @@ impl<'warnings> Compiler<'warnings> { self.compile_expression(&expression.body)?; self.emit_return_value(); + // The return belongs to no expression, so the exit block can take its + // location from whichever path reaches it. + self.set_no_location(); Ok(()) } @@ -3072,15 +3105,15 @@ impl<'warnings> Compiler<'warnings> { } } - fn load_name(&mut self, name: &str) -> CompileResult<()> { + fn load_name(&mut self, name: &Name) -> CompileResult<()> { self.compile_name(name, NameUsage::Load) } - fn store_name(&mut self, name: &str) -> CompileResult<()> { + fn store_name(&mut self, name: &Name) -> CompileResult<()> { self.compile_name(name, NameUsage::Store) } - fn emit_no_location_exception_name_cleanup(&mut self, name: &str) -> CompileResult<()> { + fn emit_no_location_exception_name_cleanup(&mut self, name: &Name) -> CompileResult<()> { // CPython codegen_try_except() emits `name = None; del name` // with NO_LOCATION for `except ... as name` cleanup. self.emit_load_const(ConstantData::None); @@ -3092,17 +3125,17 @@ impl<'warnings> Compiler<'warnings> { Ok(()) } - fn mangle<'a>(&self, name: &'a str) -> Cow<'a, str> { + fn mangle<'a>(&self, name: &'a Name) -> Cow<'a, Name> { // Use private from current code unit for name mangling let private = self .code_stack .last() - .and_then(|info| info.private.as_deref()); + .and_then(|info| info.private.as_ref()); let mangled_names = self.current_symbol_table().mangled_names.as_ref(); - symboltable::maybe_mangle_name(private, mangled_names, name) + symboltable::maybe_mangle_name(private.map(Name::from).as_ref(), mangled_names, name) } - fn module_name_declared_global_in_nested_scope(table: &SymbolTable, name: &str) -> bool { + fn module_name_declared_global_in_nested_scope(table: &SymbolTable, name: &Name) -> bool { table.sub_tables.iter().any(|subtable| { (!subtable.comp_inlined && subtable @@ -3113,7 +3146,7 @@ impl<'warnings> Compiler<'warnings> { } // = compiler_nameop - fn compile_name(&mut self, name: &str, usage: NameUsage) -> CompileResult<()> { + fn compile_name(&mut self, name: &Name, usage: NameUsage) -> CompileResult<()> { enum NameOp { Fast, Global, @@ -3125,7 +3158,7 @@ impl<'warnings> Compiler<'warnings> { let name = self.mangle(name); // Special handling for __debug__ - if NameUsage::Load == usage && name == "__debug__" { + if NameUsage::Load == usage && name.as_str() == "__debug__" { self.emit_load_const(ConstantData::Boolean { value: self.opts.optimize == 0, }); @@ -3147,14 +3180,14 @@ impl<'warnings> Compiler<'warnings> { let can_see_class = current_table.can_see_class_scope; // First try to find in current table - let symbol = current_table.lookup(name.as_ref()); + let symbol = current_table.lookup(&name); // If not found and we're in ast::TypeParams or Annotation scope, try parent scope let symbol = if symbol.is_none() && (is_typeparams || is_annotation) { self.symbol_table_stack .get(self.symbol_table_stack.len() - 2) // Try to get parent index .expect("Symbol has no parent! This is a compiler bug.") - .lookup(name.as_ref()) + .lookup(&name) } else { symbol }; @@ -3163,7 +3196,7 @@ impl<'warnings> Compiler<'warnings> { .iter() .rev() .find(|table| table.typ == CompilerScope::Class) - .and_then(|table| table.lookup(name.as_ref())) + .and_then(|table| table.lookup(&name)) .is_some_and(|symbol| symbol.flags.contains(SymbolFlags::DEF_GLOBAL)); ( @@ -3173,9 +3206,8 @@ impl<'warnings> Compiler<'warnings> { ) }; - // Special handling for class scope implicit cell variables - // These are treated as Cell even if not explicitly marked in symbol table - // __class__ and __classdict__: only LOAD uses Cell (stores go to class namespace) + // Special handling for class scope implicit cell variables. + // __classdict__: only LOAD uses Cell (stores go to class namespace) // __conditional_annotations__: both LOAD and STORE use Cell (it's a mutable set // that the annotation scope accesses through the closure) let symbol_scope = { @@ -3183,10 +3215,12 @@ impl<'warnings> Compiler<'warnings> { if current_table.typ == CompilerScope::Class && !self.current_code_info().in_inlined_comp && ((usage == NameUsage::Load - && (name == "__class__" - || name == "__classdict__" - || name == "__conditional_annotations__")) - || (name == "__conditional_annotations__" && usage == NameUsage::Store)) + && (matches!( + name.as_str(), + "__classdict__" | "__conditional_annotations__" + ))) + || (name.as_str() == "__conditional_annotations__" + && usage == NameUsage::Store)) { Some(SymbolScope::Cell) } else { @@ -3210,13 +3244,15 @@ impl<'warnings> Compiler<'warnings> { ) { SymbolScope::GlobalImplicit } else if matches!( - name.as_ref(), + name.as_str(), "__name__" | "__module__" | "__qualname__" | "__firstlineno__" | "__doc__" | "__static_attributes__" + | "__annotate__" + | "__annotate_func__" | "__classdictcell__" | "__classcell__" ) { @@ -3247,7 +3283,7 @@ impl<'warnings> Compiler<'warnings> { .current_code_info() .metadata .fast_hidden - .get(name.as_ref()) + .get(name.as_str()) .is_some_and(|&hidden| hidden) { NameOp::Fast @@ -3371,26 +3407,18 @@ impl<'warnings> Compiler<'warnings> { let prev_source_range = self.current_source_range; self.set_source_range(statement.range()); - match &statement { - // we do this here because `from __future__` still executes that `from` statement at runtime, - // we still need to compile the ImportFrom down below - ast::Stmt::ImportFrom(ast::StmtImportFrom { - module, - names, - level, - .. - }) if *level == 0 && module.as_ref().map(|id| id.as_str()) == Some("__future__") => { - self.compile_future_features(names)? - } - // ignore module-level doc comments - ast::Stmt::Expr(ast::StmtExpr { value, .. }) - if is_docstring_expr(value) - && matches!(self.done_with_future_stmts, DoneWithFuture::No) => - { - self.done_with_future_stmts = DoneWithFuture::DoneWithDoc - } - // if we find any other statement, stop accepting future statements - _ => self.done_with_future_stmts = DoneWithFuture::Yes, + // `from __future__` still executes that `from` statement at runtime, so the + // ImportFrom is compiled down below as well. + if let ast::Stmt::ImportFrom(ast::StmtImportFrom { + module, + names, + level, + .. + }) = &statement + && *level == 0 + && module.as_ref().map(|id| id.as_str()) == Some("__future__") + { + self.compile_future_features(names)?; } match &statement { @@ -3414,12 +3442,12 @@ impl<'warnings> Compiler<'warnings> { emit!(self, Instruction::PopTop); } } - self.store_name(alias.as_str())?; + self.store_name(alias.id())?; if !parts.is_empty() { emit!(self, Instruction::PopTop); } } else { - self.store_name(name.name.split('.').next().unwrap())? + self.store_name(&name.name.split('.').next().unwrap().into())? } } } @@ -3471,9 +3499,9 @@ impl<'warnings> Compiler<'warnings> { // Store module under proper name: if let Some(alias) = &name.asname { - self.store_name(alias.as_str())? + self.store_name(alias.id())? } else { - self.store_name(name.name.as_str())? + self.store_name(name.name.id())? } } @@ -3489,9 +3517,13 @@ impl<'warnings> Compiler<'warnings> { if !dominated_by_interactive && value.is_constant() { emit!(self, Instruction::Nop); } else { + let statement_range = self.current_source_range; self.compile_expression(value)?; if dominated_by_interactive { + // The printing belongs to the statement, not to whatever + // the expression left behind. + self.set_source_range(statement_range); emit!( self, Instruction::CallIntrinsic1 { @@ -3591,7 +3623,7 @@ impl<'warnings> Compiler<'warnings> { validate_duplicate_params(parameters).map_err(|e| self.error(e))?; self.compile_function_def( - name.as_str(), + name.id(), parameters, body, decorator_list, @@ -3609,7 +3641,7 @@ impl<'warnings> Compiler<'warnings> { arguments, .. }) => self.compile_class_def( - name.as_str(), + name.id(), body, decorator_list, type_params.as_deref(), @@ -3806,7 +3838,7 @@ impl<'warnings> Compiler<'warnings> { "type alias expect name".to_owned(), ))); }; - let name_string = name.id.to_string(); + let name_string = name.id(); if let Some(type_params) = type_params { self.set_source_range(*range); @@ -3826,10 +3858,10 @@ impl<'warnings> Compiler<'warnings> { self.set_source_range(*range); self.emit_load_const(ConstantData::Str { - value: name_string.clone().into(), + value: name_string.as_str().into(), }); self.compile_type_params(type_params)?; - self.compile_typealias_value_closure(&name_string, value, *range)?; + self.compile_typealias_value_closure(name_string, value, *range)?; self.set_source_range(*range); emit!(self, Instruction::BuildTuple { count: 3 }); emit!( @@ -3850,10 +3882,10 @@ impl<'warnings> Compiler<'warnings> { } else { self.set_source_range(*range); self.emit_load_const(ConstantData::Str { - value: name_string.clone().into(), + value: name_string.as_str().into(), }); self.emit_load_const(ConstantData::None); - self.compile_typealias_value_closure(&name_string, value, *range)?; + self.compile_typealias_value_closure(name_string, value, *range)?; self.set_source_range(*range); emit!(self, Instruction::BuildTuple { count: 3 }); emit!( @@ -3865,7 +3897,7 @@ impl<'warnings> Compiler<'warnings> { } self.set_source_range(*range); - self.store_name(&name_string)?; + self.store_name(name_string)?; } ast::Stmt::IpyEscapeCommand(stmt) => { return Err(self.error_ranged( @@ -3883,7 +3915,7 @@ impl<'warnings> Compiler<'warnings> { let result = (|| -> CompileResult<()> { match &expression { ast::Expr::Name(ast::ExprName { id, .. }) => { - self.compile_name(id.as_str(), NameUsage::Delete)? + self.compile_name(id, NameUsage::Delete)? } ast::Expr::Attribute(ast::ExprAttribute { value, attr, .. }) => { self.compile_expression(value)?; @@ -3988,10 +4020,7 @@ impl<'warnings> Compiler<'warnings> { // Enter scope with the type parameter name self.enter_scope(name, CompilerScope::TypeVariable, key, lineno)?; - self.current_code_info() - .metadata - .varnames - .insert(".format".to_owned()); + self.configure_annotation_format_parameter(); self.emit_format_validation(); @@ -4047,10 +4076,7 @@ impl<'warnings> Compiler<'warnings> { let key = self.symbol_table_stack.len() - 1; let lineno = self.get_source_line_number().get().to_u32(); self.enter_scope(alias_name, CompilerScope::TypeAlias, key, lineno)?; - self.current_code_info() - .metadata - .varnames - .insert(".format".to_owned()); + self.configure_annotation_format_parameter(); self.emit_format_validation(); let prev_ctx = self.ctx; @@ -4138,7 +4164,7 @@ impl<'warnings> Compiler<'warnings> { self.set_source_range(*range); emit!(self, Instruction::Copy { i: 1 }); - self.store_name(name.as_ref())?; + self.store_name(name.id())?; } ast::TypeParam::ParamSpec(ast::TypeParamParamSpec { name, @@ -4182,7 +4208,7 @@ impl<'warnings> Compiler<'warnings> { self.set_source_range(*range); emit!(self, Instruction::Copy { i: 1 }); - self.store_name(name.as_ref())?; + self.store_name(name.id())?; } ast::TypeParam::TypeVarTuple(ast::TypeParamTypeVarTuple { name, @@ -4227,7 +4253,7 @@ impl<'warnings> Compiler<'warnings> { self.set_source_range(*range); emit!(self, Instruction::Copy { i: 1 }); - self.store_name(name.as_ref())?; + self.store_name(name.id())?; } }; } @@ -4423,7 +4449,7 @@ impl<'warnings> Compiler<'warnings> { let cleanup_end = self.new_block(); let cleanup_body = self.new_block(); - self.store_name(alias.as_str())?; + self.store_name(alias.id())?; emit!(self, PseudoInstruction::SetupCleanup { delta: cleanup_end }); self.use_cpython_label_block(cleanup_body); @@ -4445,7 +4471,7 @@ impl<'warnings> Compiler<'warnings> { emit!(self, Instruction::PopExcept); self.set_no_location(); - self.emit_no_location_exception_name_cleanup(alias.as_str())?; + self.emit_no_location_exception_name_cleanup(alias.id())?; emit!( self, @@ -4454,7 +4480,7 @@ impl<'warnings> Compiler<'warnings> { self.set_no_location(); self.use_cpython_label_block(cleanup_end); - self.emit_no_location_exception_name_cleanup(alias.as_str())?; + self.emit_no_location_exception_name_cleanup(alias.id())?; emit!(self, Instruction::Reraise { depth: 1 }); self.set_no_location(); } else { @@ -4714,7 +4740,7 @@ impl<'warnings> Compiler<'warnings> { // Store match to name or pop if let Some(alias) = name { - self.store_name(alias.as_str())?; + self.store_name(alias.id())?; } else { emit!(self, Instruction::PopTop); // pop match } @@ -4750,7 +4776,7 @@ impl<'warnings> Compiler<'warnings> { // Cleanup name binding if let Some(alias) = name { - self.emit_no_location_exception_name_cleanup(alias.as_str())?; + self.emit_no_location_exception_name_cleanup(alias.id())?; } emit!( @@ -4768,7 +4794,7 @@ impl<'warnings> Compiler<'warnings> { // Cleanup name binding if let Some(alias) = name { - self.emit_no_location_exception_name_cleanup(alias.as_str())?; + self.emit_no_location_exception_name_cleanup(alias.id())?; } // LIST_APPEND(3) - append raised_exc to list @@ -4959,7 +4985,7 @@ impl<'warnings> Compiler<'warnings> { for (arg, default) in &kw_with_defaults { self.set_source_range(loc); self.emit_load_const(ConstantData::Str { - value: self.mangle(arg.name.as_str()).into_owned().into(), + value: self.mangle(arg.name().id()).as_str().into(), }); self.compile_expression(default)?; } @@ -5134,7 +5160,7 @@ impl<'warnings> Compiler<'warnings> { if let Some(annotation) = ¶m.annotation { self.set_source_range(func_range); self.emit_load_const(ConstantData::Str { - value: self.mangle(param.name.as_str()).into_owned().into(), + value: self.mangle(param.name.id()).as_str().into(), }); self.compile_annotation(annotation)?; } @@ -5299,10 +5325,7 @@ impl<'warnings> Compiler<'warnings> { // Keep the internal ".format" name; the final code object // exposes this parameter as "format". - self.current_code_info() - .metadata - .varnames - .insert(".format".to_owned()); + self.configure_annotation_format_parameter(); // Emit format validation: if format > VALUE_WITH_FAKE_GLOBALS: raise NotImplementedError self.emit_format_validation(); @@ -5321,7 +5344,7 @@ impl<'warnings> Compiler<'warnings> { } = stmt; let simple_name = if *simple { match target.as_ref() { - ast::Expr::Name(ast::ExprName { id, .. }) => Some(id.as_str()), + ast::Expr::Name(ast::ExprName { id, .. }) => Some(id), _ => None, } } else { @@ -5371,7 +5394,7 @@ impl<'warnings> Compiler<'warnings> { self.set_source_range(*range); emit!(self, Instruction::Copy { i: 2 }); self.emit_load_const(ConstantData::Str { - value: self.mangle(name).into_owned().into(), + value: self.mangle(name).as_str().into(), }); self.set_source_range(loc); emit!(self, Instruction::StoreSubscr); @@ -5416,9 +5439,10 @@ impl<'warnings> Compiler<'warnings> { "__annotate_func__" } else { "__annotate__" - }; + } + .into(); self.set_source_range(loc); - self.store_name(name)?; + self.store_name(&name)?; Ok(true) } @@ -5427,7 +5451,7 @@ impl<'warnings> Compiler<'warnings> { #[expect(clippy::too_many_arguments, reason = "ignore warning for now")] fn compile_function_def( &mut self, - name: &str, + name: &Name, parameters: &ast::Parameters, body: &[ast::Stmt], decorator_list: &[ast::Decorator], @@ -5439,7 +5463,8 @@ impl<'warnings> Compiler<'warnings> { // CPython's FunctionDef/AsyncFunctionDef LOC(s) starts at the // definition line even when decorators are present. let stmt_source_range = self.current_source_range; - let def_source_range = self.decorated_definition_range( + let def_source_range = crate::decorated_definition_range( + &self.source_file, stmt_source_range, decorator_list, if is_async { "async def " } else { "def " }, @@ -5503,14 +5528,15 @@ impl<'warnings> Compiler<'warnings> { }; // Add parameter names to varnames for the type params scope - // These will be passed as arguments when the closure is called + // These will be passed as arguments when the closure is called. + // `.defaults` is there whether or not the function has any: the + // symbol table gives every generic function's type params scope + // one. `.kwdefaults` only appears when it is really passed. let current_info = self.current_code_info(); - if funcflags.contains(&bytecode::MakeFunctionFlag::Defaults) { - current_info - .metadata - .varnames - .insert(".defaults".to_owned()); - } + current_info + .metadata + .varnames + .insert(".defaults".to_owned()); if funcflags.contains(&bytecode::MakeFunctionFlag::KwOnlyDefaults) { current_info .metadata @@ -5620,7 +5646,7 @@ impl<'warnings> Compiler<'warnings> { /// Determines if a variable should be CELL or FREE type // = get_ref_type - fn get_ref_type(&self, name: &str) -> Result { + fn get_ref_type(&self, name: &Name) -> Result { let table = self.symbol_table_stack.last().unwrap(); // Special handling for __class__, __classdict__, and __conditional_annotations__ in class scope @@ -5668,7 +5694,9 @@ impl<'warnings> Compiler<'warnings> { // well as by the normal name lookup logic. // Get reference type using our get_ref_type function - let ref_type = self.get_ref_type(var).map_err(|e| self.error(e))?; + let ref_type = self + .get_ref_type(&var.as_str().into()) + .map_err(|e| self.error(e))?; // Get parent code info let parent_code = self.code_stack.last().unwrap(); @@ -5831,26 +5859,26 @@ impl<'warnings> Compiler<'warnings> { self.set_source_range(class_body_prefix_range); // Load __name__ and store as __module__ - self.load_name("__name__")?; - self.store_name("__module__")?; + self.load_name(&"__name__".into())?; + self.store_name(&"__module__".into())?; // Store __qualname__ self.emit_load_const(ConstantData::Str { value: qualname.into(), }); - self.store_name("__qualname__")?; + self.store_name(&"__qualname__".into())?; // Store __firstlineno__ before __doc__ self.emit_load_const(ConstantData::Integer { value: BigInt::from(firstlineno), }); - self.store_name("__firstlineno__")?; + self.store_name(&"__firstlineno__".into())?; // Set __type_params__ from the enclosing type-params closure when // compiling a generic class body. if type_params.is_some() { - self.load_name(".type_params")?; - self.store_name("__type_params__")?; + self.load_name(&".type_params".into())?; + self.store_name(&"__type_params__".into())?; } // PEP 649: Initialize __classdict__ after synthetic generic-class @@ -5865,7 +5893,7 @@ impl<'warnings> Compiler<'warnings> { let annotations_used = self.current_symbol_table().annotations_used; if Self::scope_needs_conditional_annotations_cell(self.current_symbol_table()) { emit!(self, Instruction::BuildSet { count: 0 }); - self.store_name("__conditional_annotations__")?; + self.store_name(&"__conditional_annotations__".into())?; } if self.future_annotations && annotations_used { @@ -5877,7 +5905,7 @@ impl<'warnings> Compiler<'warnings> { let saved_range = self.current_source_range; self.set_source_range(range); self.emit_load_const(ConstantData::Str { value: doc.into() }); - self.store_name("__doc__")?; + self.store_name(&"__doc__".into())?; self.set_no_location(); self.set_source_range(saved_range); } @@ -5917,7 +5945,7 @@ impl<'warnings> Compiler<'warnings> { .collect(), }); self.set_no_location(); - self.store_name("__static_attributes__")?; + self.store_name(&"__static_attributes__".into())?; self.set_no_location(); } @@ -5926,7 +5954,7 @@ impl<'warnings> Compiler<'warnings> { let classdict_idx = u32::from(self.get_cell_var_index("__classdict__")); emit!(self, PseudoInstruction::LoadClosure { i: classdict_idx }); self.set_no_location(); - self.store_name("__classdictcell__")?; + self.store_name(&"__classdictcell__".into())?; self.set_no_location(); } @@ -5940,7 +5968,7 @@ impl<'warnings> Compiler<'warnings> { self.set_no_location(); emit!(self, Instruction::Copy { i: 1 }); self.set_no_location(); - self.store_name("__classcell__")?; + self.store_name(&"__classcell__".into())?; self.set_no_location(); } else { self.emit_load_const(ConstantData::None); @@ -5958,7 +5986,7 @@ impl<'warnings> Compiler<'warnings> { fn compile_class_def( &mut self, - name: &str, + name: &Name, body: &[ast::Stmt], decorator_list: &[ast::Decorator], type_params: Option<&ast::TypeParams>, @@ -5968,8 +5996,12 @@ impl<'warnings> Compiler<'warnings> { // CPython's ClassDef LOC(s) starts at the class line even when // decorators are present. let stmt_source_range = self.current_source_range; - let class_source_range = - self.decorated_definition_range(stmt_source_range, decorator_list, "class "); + let class_source_range = crate::decorated_definition_range( + &self.source_file, + stmt_source_range, + decorator_list, + "class ", + ); self.prepare_decorators(decorator_list)?; let is_generic = type_params.is_some(); @@ -6004,7 +6036,7 @@ impl<'warnings> Compiler<'warnings> { )?; // Set private name for name mangling - self.code_stack.last_mut().unwrap().private = Some(name.to_owned()); + self.code_stack.last_mut().unwrap().private = Some(name.as_str().to_owned()); // TypeParams scope is function-like self.ctx = CompileContext { @@ -6017,7 +6049,7 @@ impl<'warnings> Compiler<'warnings> { // generic class bodies close over. self.compile_type_params(type_params.unwrap())?; self.set_source_range(class_source_range); - self.store_name(".type_params")?; + self.store_name(&".type_params".into())?; } // Step 2: Compile class body (always done, whether generic or not) @@ -6043,12 +6075,14 @@ impl<'warnings> Compiler<'warnings> { // Create the class body function with the .type_params closure // captured through the class code object's freevars. self.make_closure(class_code, bytecode::MakeFunctionFlags::new())?; - self.emit_load_const(ConstantData::Str { value: name.into() }); + self.emit_load_const(ConstantData::Str { + value: name.as_str().into(), + }); // Create .generic_base after the class function and name are on the // stack so the remaining call shape matches CPython's ordering. self.set_source_range(class_source_range); - self.load_name(".type_params")?; + self.load_name(&".type_params".into())?; emit!( self, Instruction::CallIntrinsic1 { @@ -6056,7 +6090,7 @@ impl<'warnings> Compiler<'warnings> { } ); self.set_source_range(class_source_range); - self.store_name(".generic_base")?; + self.store_name(&".generic_base".into())?; let (bases, keywords) = arguments.map_or((&[][..], &[][..]), |args| { (&args.args[..], &args.keywords[..]) @@ -6067,7 +6101,7 @@ impl<'warnings> Compiler<'warnings> { keywords, class_source_range, None, - Some(".generic_base"), + Some(&".generic_base".into()), )?; // Return the created class @@ -6092,7 +6126,9 @@ impl<'warnings> Compiler<'warnings> { // Create class function with closure self.make_closure(class_code, bytecode::MakeFunctionFlags::new())?; - self.emit_load_const(ConstantData::Str { value: name.into() }); + self.emit_load_const(ConstantData::Str { + value: name.as_str().into(), + }); if let Some(arguments) = arguments { self.codegen_call_helper(2, arguments, class_source_range, None)?; @@ -6659,7 +6695,7 @@ impl<'warnings> Compiler<'warnings> { Some(name) => { // Ensure we don't store the same name twice. // TODO: maybe pc.stores should be a set? - if pc.stores.contains(&name.to_string()) { + if pc.stores.contains(name.id()) { return Err(self.error_ranged( CodegenErrorType::DuplicateStore(name.as_str().to_string()), loc, @@ -6671,7 +6707,7 @@ impl<'warnings> Compiler<'warnings> { self.pattern_helper_rotate(loc, rotations); // Append the name to the captured stores. - pc.stores.push(name.to_string()); + pc.stores.push(name.id().clone()); Ok(()) } } @@ -7433,7 +7469,7 @@ impl<'warnings> Compiler<'warnings> { let old_pc = pc.clone(); // Simulate Py_INCREF on pc.stores by cloning it. pc.stores = pc.stores.clone(); - let mut control: Option> = None; // Will hold the capture list of the first alternative. + let mut control: Option> = None; // Will hold the capture list of the first alternative. // Process each alternative. for (i, alt) in p.patterns.iter().enumerate() { @@ -8135,7 +8171,7 @@ impl<'warnings> Compiler<'warnings> { // Load the variable name self.set_source_range(loc); self.emit_load_const(ConstantData::Str { - value: self.mangle(id.as_str()).into_owned().into(), + value: self.mangle(id).as_str().into(), }); // Store: __annotations__[name] = annotation self.set_source_range(loc); @@ -8192,7 +8228,7 @@ impl<'warnings> Compiler<'warnings> { self.set_source_range(target.range()); let result = (|| -> CompileResult<()> { match &target { - ast::Expr::Name(ast::ExprName { id, .. }) => self.store_name(id.as_str())?, + ast::Expr::Name(ast::ExprName { id, .. }) => self.store_name(id)?, ast::Expr::Subscript(ast::ExprSubscript { value, slice, ctx, .. }) => { @@ -8282,7 +8318,7 @@ impl<'warnings> Compiler<'warnings> { let target_range = target.range(); enum AugAssignKind<'a> { Name { - id: &'a str, + id: &'a Name, }, Subscript { use_slice_opt: bool, @@ -8295,7 +8331,6 @@ impl<'warnings> Compiler<'warnings> { let kind = match &target { ast::Expr::Name(ast::ExprName { id, .. }) => { - let id = id.as_str(); self.set_source_range(target_range); self.compile_name(id, NameUsage::Load)?; AugAssignKind::Name { id } @@ -8920,7 +8955,7 @@ impl<'warnings> Compiler<'warnings> { self.emit_load_const(ConstantData::None); let _ = self.compile_yield_from_sequence(false); } - ast::Expr::Name(ast::ExprName { id, .. }) => self.load_name(id.as_str())?, + ast::Expr::Name(ast::ExprName { id, .. }) => self.load_name(id)?, ast::Expr::Lambda(ast::ExprLambda { parameters, body, @@ -8965,7 +9000,7 @@ impl<'warnings> Compiler<'warnings> { for (arg, default) in &kw_with_defaults { self.set_source_range(*range); self.emit_load_const(ConstantData::Str { - value: self.mangle(arg.name.as_str()).into_owned().into(), + value: self.mangle(arg.name().id()).as_str().into(), }); self.compile_expression(default)?; } @@ -9182,10 +9217,12 @@ impl<'warnings> Compiler<'warnings> { if self.current_code_info().in_inlined_comp && let ast::Expr::Name(ast::ExprName { id, .. }) = target.as_ref() { - let name = self.mangle(id.as_str()); + let name = self.mangle(id); let info = self.code_stack.last_mut().unwrap(); info.metadata.fast_hidden.insert(name.to_string(), false); - info.metadata.fast_hidden_final.swap_remove(name.as_ref()); + info.metadata + .fast_hidden_final + .swap_remove(name.into_owned().as_str()); } self.compile_expression(value)?; self.set_source_range(*range); @@ -9211,7 +9248,7 @@ impl<'warnings> Compiler<'warnings> { self.compile_expr_tstring(tstring)?; } ast::Expr::StringLiteral(string) => { - let value = self.compile_string_value(string); + let value = string_literal_value(&self.source_file, &string.value); self.emit_load_const(ConstantData::Str { value }); } ast::Expr::BytesLiteral(bytes) => { @@ -9252,7 +9289,12 @@ impl<'warnings> Compiler<'warnings> { Ok(()) } - fn cpython_sync_genexpr_call_name<'a>( + /// The called name of a `name(genexpr)` call, the shape + /// `maybe_optimize_function_call()` reserves a `skip_optimization` label + /// for. An `await` or an `async for` inside the generator does not + /// disqualify it: the inlined loop raises the same `TypeError` that + /// calling the builtin on an async generator would. + fn cpython_genexpr_call_name<'a>( &self, func: &'a ast::Expr, args: &ast::Arguments, @@ -9263,15 +9305,11 @@ impl<'warnings> Compiler<'warnings> { let [ast::Expr::Generator(ast::ExprGenerator { .. })] = &args.args[..] else { return None; }; - if !args.keywords.is_empty() || { - let table = self.current_symbol_table(); - table - .sub_tables - .get(table.next_sub_table) - .is_none_or(|generator_entry| generator_entry.is_coroutine) - } { + if !args.keywords.is_empty() { return None; } + let table = self.current_symbol_table(); + table.sub_tables.get(table.next_sub_table)?; Some(id.as_str()) } @@ -9280,7 +9318,7 @@ impl<'warnings> Compiler<'warnings> { func: &ast::Expr, args: &ast::Arguments, ) -> Option { - match self.cpython_sync_genexpr_call_name(func, args)? { + match self.cpython_genexpr_call_name(func, args)? { "tuple" => Some(BuiltinGeneratorCallKind::Tuple), "all" => Some(BuiltinGeneratorCallKind::All), "any" => Some(BuiltinGeneratorCallKind::Any), @@ -9332,11 +9370,7 @@ impl<'warnings> Compiler<'warnings> { } let symbol_table_cursors = self.current_symbol_table_cursors(); - if let Some(range) = self.cpython_implicit_call_generator_range(generator_expr) { - self.compile_expression_with_generator_range(generator_expr, range)?; - } else { - self.compile_expression(generator_expr)?; - } + self.compile_expression(generator_expr)?; self.set_symbol_table_cursors(symbol_table_cursors); let loop_block = self.new_block(); @@ -9433,17 +9467,8 @@ impl<'warnings> Compiler<'warnings> { call_range: TextRange, kw_names_range: TextRange, ) -> CompileResult<()> { - let implicit_generator_range = if args.args.len() == 1 && args.keywords.is_empty() { - self.cpython_implicit_call_generator_range(&args.args[0]) - } else { - None - }; for arg in &args.args { - if let Some(range) = implicit_generator_range { - self.compile_expression_with_generator_range(arg, range)?; - } else { - self.compile_expression(arg)?; - } + self.compile_expression(arg)?; } if args.keywords.is_empty() { @@ -9574,15 +9599,15 @@ impl<'warnings> Compiler<'warnings> { // `skip_normal_call`, even when `maybe_optimize_function_call()` // leaves it untargeted. let skip_normal_call = self.current_code_info().new_instr_sequence_label(); - let sync_genexpr_call_name = (!uses_ex_call) - .then(|| self.cpython_sync_genexpr_call_name(func, args)) + let genexpr_call_name = (!uses_ex_call) + .then(|| self.cpython_genexpr_call_name(func, args)) .flatten() .is_some(); self.check_caller(func)?; self.compile_expression(func)?; - if sync_genexpr_call_name { + if genexpr_call_name { // CPython `maybe_optimize_function_call()` creates and uses - // `skip_optimization` for every sync name(genexpr) shape after + // `skip_optimization` for every name(genexpr) shape after // loading the function, even when the name is not all/any/tuple. let skip_optimization = self.current_code_info().new_instr_sequence_label(); let result = self @@ -9698,7 +9723,7 @@ impl<'warnings> Compiler<'warnings> { keywords: &[ast::Keyword], call_range: TextRange, kw_names_range: Option, - injected_arg: Option<&str>, + injected_arg: Option<&Name>, ) -> CompileResult<()> { self.validate_keywords(keywords)?; @@ -9716,18 +9741,8 @@ impl<'warnings> Compiler<'warnings> { if !has_starred && !has_double_star && !too_big { // Simple call path: no * or ** args - let implicit_generator_range = - if additional_positional == 0 && nelts == 1 && nkwelts == 0 { - self.cpython_implicit_call_generator_range(&args[0]) - } else { - None - }; for arg in args { - if let Some(range) = implicit_generator_range { - self.compile_expression_with_generator_range(arg, range)?; - } else { - self.compile_expression(arg)?; - } + self.compile_expression(arg)?; } let injected_count = if let Some(injected_arg) = injected_arg { self.set_source_range(call_range); @@ -9862,122 +9877,6 @@ impl<'warnings> Compiler<'warnings> { }) } - fn compile_expression_with_generator_range( - &mut self, - expression: &ast::Expr, - range: TextRange, - ) -> CompileResult<()> { - if let ast::Expr::Generator(ast::ExprGenerator { - elt, generators, .. - }) = expression - { - self.set_source_range(range); - self.compile_generator_expression(elt, generators, range) - } else { - self.compile_expression(expression) - } - } - - fn cpython_implicit_call_generator_range(&self, expression: &ast::Expr) -> Option { - if !matches!(expression, ast::Expr::Generator(_)) { - return None; - } - let range = expression.range(); - let source = self.source_file.source_text().as_bytes(); - let start = range.start().to_usize(); - let end = range.end().to_usize(); - if source.get(start) == Some(&b'(') - && !Self::starts_with_parenthesized_generator_element(source, start, end) - { - return None; - } - - let mut open = start; - while open > 0 && source[open - 1].is_ascii_whitespace() { - open -= 1; - } - if open == 0 || source[open - 1] != b'(' { - return None; - } - - let mut close = end; - while close < source.len() && source[close].is_ascii_whitespace() { - close += 1; - } - if source.get(close) != Some(&b')') { - return None; - } - - let adjusted_start = u32::try_from(open - 1).ok()?; - let adjusted_end = u32::try_from(close + 1).ok()?; - Some(TextRange::new( - TextSize::from(adjusted_start), - TextSize::from(adjusted_end), - )) - } - - fn starts_with_parenthesized_generator_element( - source: &[u8], - start: usize, - end: usize, - ) -> bool { - let mut depth = 0usize; - let mut i = start; - while i < end { - match source[i] { - b'(' | b'[' | b'{' => depth += 1, - b')' | b']' | b'}' => { - if depth == 0 { - return false; - } - depth -= 1; - if depth == 0 { - return Self::next_token_is_for(source, i + 1, end); - } - } - b'\'' | b'"' => i = Self::skip_python_string_literal(source, i), - _ => {} - } - i += 1; - } - false - } - - fn skip_python_string_literal(source: &[u8], quote: usize) -> usize { - let quote_byte = source[quote]; - let triple = source.get(quote + 1) == Some("e_byte) - && source.get(quote + 2) == Some("e_byte); - let mut i = quote + if triple { 3 } else { 1 }; - while i < source.len() { - if source[i] == b'\\' { - i += 2; - continue; - } - if triple { - if source[i] == quote_byte - && source.get(i + 1) == Some("e_byte) - && source.get(i + 2) == Some("e_byte) - { - return i + 2; - } - } else if source[i] == quote_byte { - return i; - } - i += 1; - } - source.len().saturating_sub(1) - } - - fn next_token_is_for(source: &[u8], mut i: usize, end: usize) -> bool { - while i < end && source[i].is_ascii_whitespace() { - i += 1; - } - source.get(i..i + 3) == Some(b"for") - && source - .get(i + 3) - .is_none_or(|byte| !byte.is_ascii_alphanumeric() && *byte != b'_') - } - fn compile_generator_expression( &mut self, elt: &ast::Expr, @@ -10467,6 +10366,43 @@ impl<'warnings> Compiler<'warnings> { table.next_inlined_comprehension_block = cursors.inlined_comprehension_block; } + /// Advance the nested-scope cursors to the first scope that begins on or + /// after `line_number`. + /// + /// A statement list can be compiled more than once — `finally` bodies are + /// re-emitted on every path that leaves the try block early — and each copy + /// has to be handed the same scopes as the last. Positioning by line works + /// because `finally` is the last clause of its statement: every scope the + /// preceding clauses opened begins on an earlier line than the body being + /// re-compiled, and every scope that body opens begins on its own line or + /// later. + fn seek_symbol_table_cursors_to_line(&mut self, line_number: u32) { + fn seek(tables: &[SymbolTable], cursor: &mut usize, line_number: u32) { + while tables + .get(*cursor) + .is_some_and(|table| table.line_number < line_number) + { + *cursor += 1; + } + } + + let table = self + .symbol_table_stack + .last_mut() + .expect("no current symbol table"); + seek(&table.sub_tables, &mut table.next_sub_table, line_number); + seek( + &table.hidden_annotation_blocks, + &mut table.next_hidden_annotation_block, + line_number, + ); + seek( + &table.inlined_comprehension_blocks, + &mut table.next_inlined_comprehension_block, + line_number, + ); + } + fn lookup_comprehension_symbol_table_after_skipped_nested_scopes_in_expr( &mut self, expression: &ast::Expr, @@ -10542,6 +10478,7 @@ impl<'warnings> Compiler<'warnings> { | bytecode::CodeFlags::FUTURE_WITH_STATEMENT | bytecode::CodeFlags::FUTURE_PRINT_FUNCTION | bytecode::CodeFlags::FUTURE_UNICODE_LITERALS + | bytecode::CodeFlags::FUTURE_BARRY_AS_BDFL | bytecode::CodeFlags::FUTURE_GENERATOR_STOP | bytecode::CodeFlags::FUTURE_ANNOTATIONS)); info.metadata.argcount = arg_count; @@ -10893,7 +10830,7 @@ impl<'warnings> Compiler<'warnings> { }; self.current_code_info().in_inlined_comp = true; - let mut temp_symbols: IndexMap = IndexMap::default(); + let mut temp_symbols: IndexMap = IndexMap::default(); let mut changed_fast_hidden = Vec::new(); let result = (|| { @@ -10913,8 +10850,8 @@ impl<'warnings> Compiler<'warnings> { current_table.sub_tables.insert(insert_pos + i, st.clone()); } } - let mut pushed_locals: Vec = Vec::new(); - let mut fast_hidden_locals: Vec = Vec::new(); + let mut pushed_locals: Vec = Vec::new(); + let mut fast_hidden_locals: Vec = Vec::new(); for (name, sym) in &comp_table.symbols { if sym.flags.contains(SymbolFlags::DEF_PARAM) { continue; // skip .0 @@ -10966,11 +10903,11 @@ impl<'warnings> Compiler<'warnings> { self.current_code_info() .metadata .fast_hidden - .insert(name.clone(), true); + .insert(name.clone().into(), true); self.current_code_info() .metadata .fast_hidden_final - .insert(name.clone()); + .insert(name.clone().into()); changed_fast_hidden.push(name.clone()); } } @@ -11243,7 +11180,7 @@ impl<'warnings> Compiler<'warnings> { self.current_code_info() .metadata .fast_hidden - .insert(name, false); + .insert(name.into(), false); } self.current_code_info().in_inlined_comp = was_in_inlined_comp; @@ -11251,12 +11188,6 @@ impl<'warnings> Compiler<'warnings> { } fn compile_future_features(&mut self, features: &[ast::Alias]) -> Result<(), CodegenError> { - if let DoneWithFuture::Yes = self.done_with_future_stmts { - return Err(self.error(CodegenErrorType::InvalidFuturePlacement)); - } - - self.done_with_future_stmts = DoneWithFuture::DoneWithDoc; - for feature in features { let future_feature = feature.name.as_str().try_into().map_err(|name| { self.error_ranged(CodegenErrorType::InvalidFutureFeature(name), feature.range) @@ -11277,7 +11208,11 @@ impl<'warnings> Compiler<'warnings> { .insert(bytecode::CodeFlags::FUTURE_ANNOTATIONS); } FutureFeature::BarryAsFLUFL => { - // We do not support Barry-as-BDFL parser mode yet. This is a nop for now. + self.future_features + .insert(bytecode::CodeFlags::FUTURE_BARRY_AS_BDFL); + self.current_code_info() + .flags + .insert(bytecode::CodeFlags::FUTURE_BARRY_AS_BDFL); } FutureFeature::AbsoluteImport | FutureFeature::Division @@ -11481,59 +11416,6 @@ impl<'warnings> Compiler<'warnings> { // fn block_done() - /// Convert a string literal AST node to Wtf8Buf, handling surrogate literals correctly. - fn compile_string_value(&self, string: &ast::ExprStringLiteral) -> Wtf8Buf { - let value = string.value.to_str(); - if value.contains(char::REPLACEMENT_CHARACTER) { - // Might have a surrogate literal; reparse from source to preserve them. - string - .value - .iter() - .map(|lit| { - let source = self.source_file.slice(lit.range); - crate::string_parser::parse_string_literal(source, lit.flags.into()) - }) - .collect() - } else { - value.into() - } - } - - fn compile_fstring_literal_value( - &self, - string: &ast::InterpolatedStringLiteralElement, - flags: ast::FStringFlags, - ) -> Wtf8Buf { - if string.value.contains(char::REPLACEMENT_CHARACTER) { - let source = self.source_file.slice(string.range); - crate::string_parser::parse_fstring_literal_element(source.into(), flags.into()).into() - } else { - string.value.to_string().into() - } - } - - fn compile_tstring_literal_value( - &self, - string: &ast::InterpolatedStringLiteralElement, - flags: ast::TStringFlags, - ) -> Wtf8Buf { - if string.value.contains(char::REPLACEMENT_CHARACTER) { - let source = self.source_file.slice(string.range); - crate::string_parser::parse_fstring_literal_element(source.into(), flags.into()).into() - } else { - string.value.to_string().into() - } - } - - fn compile_fstring_part_literal_value(&self, string: &ast::StringLiteral) -> Wtf8Buf { - if string.value.contains(char::REPLACEMENT_CHARACTER) { - let source = self.source_file.slice(string.range); - crate::string_parser::parse_string_literal(source, string.flags.into()).into() - } else { - string.value.to_string().into() - } - } - fn arg_constant(&mut self, constant: ConstantData) -> oparg::ConstIdx { let info = self.current_code_info(); if let ConstantData::Code { code } = &constant @@ -11658,7 +11540,7 @@ impl<'warnings> Compiler<'warnings> { }, }, ast::Expr::StringLiteral(s) => ConstantData::Str { - value: self.compile_string_value(s), + value: string_literal_value(&self.source_file, &s.value), }, ast::Expr::BytesLiteral(b) => ConstantData::Bytes { value: b.value.bytes().collect(), @@ -11849,7 +11731,7 @@ impl<'warnings> Compiler<'warnings> { }, }, ast::Expr::StringLiteral(s) => ConstantData::Str { - value: self.compile_string_value(s), + value: string_literal_value(&self.source_file, &s.value), }, ast::Expr::BytesLiteral(b) => ConstantData::Bytes { value: b.value.bytes().collect(), @@ -12445,33 +12327,6 @@ impl<'warnings> Compiler<'warnings> { self.current_source_range = range; } - fn decorated_definition_range( - &self, - statement_range: TextRange, - decorator_list: &[ast::Decorator], - keyword: &str, - ) -> TextRange { - let Some(last_decorator) = decorator_list.last() else { - return statement_range; - }; - let search_start = last_decorator.expression.range().end(); - if search_start >= statement_range.end() { - return statement_range; - } - let search_range = TextRange::new(search_start, statement_range.end()); - let source = self.source_file.slice(search_range); - let Some(keyword_offset) = source.find(keyword) else { - return statement_range; - }; - let Ok(keyword_offset) = u32::try_from(keyword_offset) else { - return statement_range; - }; - TextRange::new( - search_start + TextSize::new(keyword_offset), - statement_range.end(), - ) - } - fn update_start_location_to_match_attr( &self, loc_range: TextRange, @@ -12702,7 +12557,7 @@ impl<'warnings> Compiler<'warnings> { ) -> CompileResult<()> { match part { ast::FStringPart::Literal(string) => { - let value = self.compile_fstring_part_literal_value(string); + let value = string_literal_part_value(&self.source_file, string); if pending_literal.is_none() { *pending_literal_range = Some(string.range); *pending_literal_no_location = string.range == TextRange::default(); @@ -12733,13 +12588,11 @@ impl<'warnings> Compiler<'warnings> { mut element_count: u32, fstring_range: Option, ) { - let keep_empty = element_count == 0; self.emit_pending_fstring_literal( &mut pending_literal, &mut pending_literal_range, &mut pending_literal_no_location, &mut element_count, - keep_empty, None, ); @@ -12771,13 +12624,11 @@ impl<'warnings> Compiler<'warnings> { mut element_count: u32, fstring_range: TextRange, ) { - let keep_empty = element_count == 0; self.emit_pending_fstring_literal( &mut pending_literal, &mut pending_literal_range, &mut pending_literal_no_location, &mut element_count, - keep_empty, Some(fstring_range), ); self.set_source_range(fstring_range); @@ -12790,7 +12641,6 @@ impl<'warnings> Compiler<'warnings> { pending_literal_range: &mut Option, pending_literal_no_location: &mut bool, element_count: &mut u32, - keep_empty: bool, join_append_range: Option, ) { let Some(value) = pending_literal.take() else { @@ -12800,10 +12650,10 @@ impl<'warnings> Compiler<'warnings> { let no_location = *pending_literal_no_location; *pending_literal_no_location = false; - // CPython drops empty literal fragments when they are adjacent to - // formatted values, but still emits an empty string for a fully-empty - // f-string. - if value.is_empty() && (!keep_empty || *element_count > 0) { + // An empty literal fragment contributes nothing, so it is dropped. An + // f-string left with no fragments at all still loads an empty string, + // positioned at the whole f-string rather than at any one fragment. + if value.is_empty() { return; } @@ -12839,8 +12689,7 @@ impl<'warnings> Compiler<'warnings> { for part in fstring { self.count_fstring_part_into(part, &mut pending_literal, &mut element_count); } - let keep_empty = element_count == 0; - Self::count_pending_fstring_literal(&mut pending_literal, &mut element_count, keep_empty); + Self::count_pending_fstring_literal(&mut pending_literal, &mut element_count); element_count } @@ -12852,7 +12701,7 @@ impl<'warnings> Compiler<'warnings> { ) { match part { ast::FStringPart::Literal(string) => { - let value = self.compile_fstring_part_literal_value(string); + let value = string_literal_part_value(&self.source_file, string); if let Some(pending) = pending_literal.as_mut() { pending.push_wtf8(value.as_ref()); } else { @@ -12871,13 +12720,12 @@ impl<'warnings> Compiler<'warnings> { fn count_pending_fstring_literal( pending_literal: &mut Option, element_count: &mut u32, - keep_empty: bool, ) { let Some(value) = pending_literal.take() else { return; }; - if value.is_empty() && (!keep_empty || *element_count > 0) { + if value.is_empty() { return; } @@ -12979,7 +12827,8 @@ impl<'warnings> Compiler<'warnings> { for element in fstring_elements { match element { ast::InterpolatedStringElement::Literal(string) => { - let value = self.compile_fstring_literal_value(string, flags); + let value = + interpolated_string_literal_value(&self.source_file, string, flags.into()); if pending_literal.is_none() { *pending_literal_range = Some(string.range); *pending_literal_no_location = string.range == TextRange::default(); @@ -12999,40 +12848,17 @@ impl<'warnings> Compiler<'warnings> { }; if let Some(debug_text) = &fstring_expr.debug_text { - let leading = debug_text.leading.as_str(); - let trailing = debug_text.trailing.as_str(); - self.emit_pending_fstring_literal( - pending_literal, - pending_literal_range, - pending_literal_no_location, - element_count, - false, - join_append_range, + let (text, debug_text_range) = interpolation_debug_text( + &self.source_file, + debug_text, + fstring_expr.expression.range(), ); - - let range = fstring_expr.expression.range(); - let leading = strip_fstring_debug_comments(leading); - let trailing = strip_fstring_debug_comments(trailing); - let source = self.source_file.slice(range); - let text = [leading.as_str(), source, trailing.as_str()].concat(); - let debug_text_range = TextRange::new( - range.start() - - TextSize::new( - u32::try_from(leading.len()) - .expect("debug f-string leading text too long"), - ), - range.end() - + TextSize::new( - u32::try_from(trailing.len()) - .expect("debug f-string trailing text too long"), - ), - ); - let text: Wtf8Buf = text.into(); - *pending_literal_range = Some(debug_text_range); + Self::extend_pending_literal_range(pending_literal_range, debug_text_range); *pending_literal_no_location = false; - *pending_literal = Some(Wtf8Buf::new()); - pending_literal.as_mut().unwrap().push_wtf8(text.as_ref()); + pending_literal + .get_or_insert_with(Wtf8Buf::new) + .push_wtf8(text.as_ref()); // If debug text is present, apply repr conversion when no `format_spec` specified. // See action_helpers.c: fstring_find_expr_replacement @@ -13049,7 +12875,6 @@ impl<'warnings> Compiler<'warnings> { pending_literal_range, pending_literal_no_location, element_count, - false, join_append_range, ); @@ -13119,8 +12944,7 @@ impl<'warnings> Compiler<'warnings> { &mut pending_literal, &mut element_count, ); - let keep_empty = element_count == 0; - Self::count_pending_fstring_literal(&mut pending_literal, &mut element_count, keep_empty); + Self::count_pending_fstring_literal(&mut pending_literal, &mut element_count); element_count } @@ -13134,7 +12958,8 @@ impl<'warnings> Compiler<'warnings> { for element in fstring_elements { match element { ast::InterpolatedStringElement::Literal(string) => { - let value = self.compile_fstring_literal_value(string, flags); + let value = + interpolated_string_literal_value(&self.source_file, string, flags.into()); if let Some(pending) = pending_literal.as_mut() { pending.push_wtf8(value.as_ref()); } else { @@ -13143,25 +12968,18 @@ impl<'warnings> Compiler<'warnings> { } ast::InterpolatedStringElement::Interpolation(fstring_expr) => { if let Some(debug_text) = &fstring_expr.debug_text { - let leading = debug_text.leading.as_str(); - let trailing = debug_text.trailing.as_str(); - Self::count_pending_fstring_literal(pending_literal, element_count, false); - let range = fstring_expr.expression.range(); - let source = self.source_file.slice(range); - let text = [ - strip_fstring_debug_comments(leading).as_str(), - source, - strip_fstring_debug_comments(trailing).as_str(), - ] - .concat(); - + let (text, _) = interpolation_debug_text( + &self.source_file, + debug_text, + fstring_expr.expression.range(), + ); let text: Wtf8Buf = text.into(); - let mut debug_text = Wtf8Buf::new(); - debug_text.push_wtf8(text.as_ref()); - *pending_literal = Some(debug_text); + pending_literal + .get_or_insert_with(Wtf8Buf::new) + .push_wtf8(text.as_ref()); } - Self::count_pending_fstring_literal(pending_literal, element_count, false); + Self::count_pending_fstring_literal(pending_literal, element_count); *element_count += 1; } } @@ -13370,32 +13188,18 @@ impl<'warnings> Compiler<'warnings> { } else { Self::extend_pending_literal_range(current_string_range, lit.range); } - current_string - .push_wtf8(&self.compile_tstring_literal_value(lit, tstring.flags)); + current_string.push_wtf8(&interpolated_string_literal_value( + &self.source_file, + lit, + tstring.flags.into(), + )); } ast::InterpolatedStringElement::Interpolation(interp) => { if let Some(debug_text) = &interp.debug_text { - let leading = debug_text.leading.as_str(); - let trailing = debug_text.trailing.as_str(); - let range = interp.expression.range(); - let source = self.source_file.slice(range); - let text = [ - strip_fstring_debug_comments(leading).as_str(), - source, - strip_fstring_debug_comments(trailing).as_str(), - ] - .concat(); - let debug_text_range = TextRange::new( - range.start() - - TextSize::new( - u32::try_from(leading.len()) - .expect("debug t-string leading text too long"), - ), - range.end() - + TextSize::new( - u32::try_from(trailing.len()) - .expect("debug t-string trailing text too long"), - ), + let (text, debug_text_range) = interpolation_debug_text( + &self.source_file, + debug_text, + interp.expression.range(), ); if current_string_range.is_none() { *current_string_range = Some(debug_text_range); @@ -13612,17 +13416,6 @@ fn split_doc<'a>(body: &'a [ast::Stmt], opts: &CompileOpts) -> (Option, (doc.map(|(doc, _)| doc), body) } -fn is_docstring_expr(expr: &ast::Expr) -> bool { - matches!( - expr, - ast::Expr::StringLiteral(_) - | ast::Expr::Constant(ast::ExprConstant { - value: ast::ConstantValue::Str(_), - .. - }) - ) -} - pub fn ruff_int_to_bigint(int: &ast::Int) -> Result { if let Some(small) = int.as_u64() { Ok(BigInt::from(small)) @@ -13673,27 +13466,6 @@ impl ToU32 for usize { } } -/// Strip Python comments from f-string debug text (leading/trailing around `=`). -/// A comment starts with `#` and extends to the end of the line. -/// The newline character itself is preserved. -fn strip_fstring_debug_comments(text: &str) -> String { - let mut result = String::with_capacity(text.len()); - let mut in_comment = false; - for ch in text.chars() { - if in_comment { - if ch == '\n' { - in_comment = false; - result.push(ch); - } - } else if ch == '#' { - in_comment = true; - } else { - result.push(ch); - } - } - result -} - #[cfg(test)] mod ruff_tests { use super::*; @@ -14022,6 +13794,7 @@ mod tests { warning = Some(message.clone()); Err(CodegenError { location: Some(location), + end_location: None, error: CodegenErrorType::SyntaxError(message), source_path: "source_path".to_owned(), }) @@ -14051,6 +13824,7 @@ mod tests { warning = Some(message.clone()); Err(CodegenError { location: Some(location), + end_location: None, error: CodegenErrorType::SyntaxError(message), source_path: "source_path".to_owned(), }) @@ -14206,7 +13980,7 @@ mod tests { .unwrap(); assert!( - table.lookup("frozenset").is_none(), + table.lookup(&"frozenset".into()).is_none(), "CPython symtable Constant_kind does not visit the lowered frozenset() expression" ); } @@ -16647,6 +16421,28 @@ def f(buffer, pos, last_char): ); } + fn location_range( + locations: &(SourceLocation, SourceLocation), + ) -> (usize, usize, usize, usize) { + let (location, end_location) = locations; + ( + location.line.get(), + location.character_offset.get(), + end_location.line.get(), + end_location.character_offset.get(), + ) + } + + fn instruction_range( + code: &CodeObject, + matches: impl Fn(&Instruction) -> bool, + ) -> Option<(usize, usize, usize, usize)> { + code.instructions + .iter() + .zip(&code.locations) + .find_map(|(unit, locations)| matches(&unit.op).then(|| location_range(locations))) + } + fn find_code<'a>(code: &'a CodeObject, name: &str) -> Option<&'a CodeObject> { if code.obj_name == name { return Some(code); @@ -17463,6 +17259,53 @@ class C: ); } + #[test] + #[expect( + clippy::literal_string_with_formatting_args, + reason = "the literal is the expected t-string annotation" + )] + fn future_tstring_annotation_preserves_interpolation_source_like_cpython() { + let code = compile_exec( + "from __future__ import annotations\nx: t'{a + b}'\ny: t'{ a + b }'\nz: f'{a + b =}'\nu: t'{a + b =}'\nv: t'{a + b =:>10}'\np: t'{(a)}'\nq: t'{((a))!r}'\nr: t'{ ((a)) = !r:>10}'\ns: t'{(a)=}'\nt: t'{a == b = }'\na1: t'''{a= # x=y\n}'''\na2: t'''{a # x=y\n}'''\na3: t'''{(a # x=y\n)}'''\na4: t'''{a # x=y\n!r}'''\na5: t'''{a # x=y\n:>10}'''\na6: t'''{'#'}'''\na7: t'''{('#', a) # c=d\n}'''\n", + ); + let annotation_strings = code + .constants + .iter() + .filter_map(|constant| match constant { + ConstantData::Str { value } + if value.starts_with("t'") + || value.starts_with("t\"") + || value.starts_with("f'") => + { + Some(value.to_string()) + } + _ => None, + }) + .collect::>(); + assert_eq!( + annotation_strings, + [ + "t'{a + b}'", + "t'{ a + b}'", + "f'a + b ={a + b!r}'", + "t'a + b ={a + b!r}'", + "t'a + b ={a + b:>10}'", + "t'{(a)}'", + "t'{((a))!r}'", + "t' ((a)) = { ((a))!r:>10}'", + "t'(a)={(a)!r}'", + "t'a == b = {a == b!r}'", + "t'a= \\n{a!r}'", + "t'{a}'", + "t'{(a \\n)}'", + "t'{a!r}'", + "t'{a:>10}'", + "t\"{'#'}\"", + "t\"{('#', a)}\"", + ] + ); + } + #[test] fn lambda_dict_literal_ops_use_dict_location_like_cpython() { let code = compile_exec( @@ -19256,6 +19099,61 @@ def explicit_gen(xs): ); } + #[test] + fn implicit_call_genexpr_operator_element_range_like_cpython() { + // The element opens with a parenthesized group that the rest of the + // expression continues, so the call's own parentheses are the only + // ones that bound the generator. + let code = compile_exec( + "\ +def f(p, q): + return sum((px - qx) ** 2.0 for px, qx in zip(p, q)) +", + ); + let f = find_code(&code, "f").expect("missing f code"); + let genexpr = find_code(f, "").expect("missing genexpr code"); + + // Columns are one-based here, so these are `dis`'s 14..56. + assert_eq!( + instruction_range(f, |op| matches!(op, Instruction::MakeFunction)), + Some((2, 15, 2, 57)) + ); + assert_eq!( + instruction_range(genexpr, |op| matches!(op, Instruction::LoadFast { .. })), + Some((2, 15, 2, 57)) + ); + } + + #[test] + fn fstring_concatenation_without_content_uses_whole_range_like_cpython() { + // Every fragment is empty, so none of them is kept and the empty string + // that replaces them belongs to the whole concatenation. The last line + // keeps its one fragment and stays at that fragment. + let code = compile_exec( + "\ +x = '' f'' +y = f'' '' +z = '' f'' '' f'' +w = f'' 'a' f'' +", + ); + + let ranges: Vec<_> = code + .instructions + .iter() + .zip(&code.locations) + .filter(|(unit, _)| matches!(unit.op, Instruction::LoadConst { .. })) + .map(|(_, locations)| location_range(locations)) + .take(4) + .collect(); + // Columns are one-based here, so these are `dis`'s 4..10, 4..10, + // 4..17 and 8..11. + assert_eq!( + ranges, + vec![(1, 5, 1, 11), (2, 5, 2, 11), (3, 5, 3, 18), (4, 9, 4, 12)] + ); + } + #[test] fn genexpr_filter_cleanup_jumps_use_element_location_like_cpython() { let code = compile_exec( @@ -19518,7 +19416,7 @@ def spec(x): } #[test] - fn debug_fstring_literal_location_like_cpython() { + fn debug_fstring_literal_merging_and_location_like_cpython() { fn string_load_position(code: &CodeObject, expected: &str) -> (usize, usize, usize, usize) { code.instructions .iter() @@ -19541,16 +19439,20 @@ def spec(x): } let code = compile_exec( - "\ -def simple(x): + r#"def simple(x): return f'{x=}' def prefixed(x): return f'a {x=} b' -", + +def commented(x): + return f"""{ # comment +x=}""" +"#, ); let simple = find_code(&code, "simple").expect("missing simple code"); let prefixed = find_code(&code, "prefixed").expect("missing prefixed code"); + let commented = find_code(&code, "commented").expect("missing commented code"); assert_eq!( string_load_position(simple, "x="), @@ -19558,9 +19460,14 @@ def prefixed(x): "CPython represents f'{{x=}}' debug text as a literal at the expression/debug-text location" ); assert_eq!( - string_load_position(prefixed, "x="), - (5, 17, 5, 19), - "CPython keeps debug text as a separate JoinedStr Constant instead of merging it with the preceding literal" + string_load_position(prefixed, "a x="), + (5, 14, 5, 19), + "CPython merges debug text with the preceding JoinedStr literal" + ); + assert_eq!( + string_load_position(commented, " \nx="), + (8, 17, 9, 3), + "a stripped comment shortens the debug text but not the source range it spans" ); } @@ -20580,25 +20487,32 @@ def f(xs): } #[test] - fn builtin_any_async_genexpr_call_is_not_optimized() { - let code = compile_exec( - "\ -async def f(xs): - return any(x async for x in xs) -", - ); - let f = find_code(&code, "f").expect("missing function code"); + fn builtin_any_async_genexpr_call_is_optimized_like_cpython() { + for source in [ + "async def f(xs):\n return any(x async for x in xs)\n", + "async def f(xs):\n return any(await x for x in xs)\n", + ] { + let code = compile_exec(source); + let f = find_code(&code, "f").expect("missing function code"); - assert!( - !has_common_constant(f, bytecode::CommonConstant::BuiltinAny), - "CPython maybe_optimize_function_call() skips coroutine generator expressions" - ); - assert!( - f.instructions - .iter() - .any(|unit| matches!(unit.op, Instruction::Call { .. })), - "async genexpr any() should stay on the normal call path" - ); + assert!( + has_common_constant(f, bytecode::CommonConstant::BuiltinAny), + "maybe_optimize_function_call() guards any(genexpr) whether or not the \ + generator is a coroutine: {source}" + ); + assert!( + f.instructions + .iter() + .any(|unit| matches!(unit.op, Instruction::ForIter { .. })), + "the guarded path inlines the loop: {source}" + ); + assert!( + f.instructions + .iter() + .any(|unit| matches!(unit.op, Instruction::Call { .. })), + "the fallback still calls the name it loaded: {source}" + ); + } } #[test] @@ -26980,6 +26894,43 @@ class C: ); } + #[test] + fn explicit_class_dunder_class_store_uses_namespace_like_cpython() { + let code = compile_exec( + "\ +class C: + def method(self): + return __class__ + __class__ = 413 +", + ); + let class_code = find_code(&code, "C").expect("missing class code"); + let class_name_index = class_code + .names + .iter() + .position(|name| name.as_str() == "__class__") + .expect("missing __class__ name"); + + assert!(class_code.instructions.iter().any(|unit| { + matches!( + unit.op, + Instruction::StoreName { namei } + if namei.get(OpArg::new(u32::from(u8::from(unit.arg)))) as usize + == class_name_index + ) + })); + assert!(!class_code.instructions.iter().any(|unit| { + matches!( + unit.op, + Instruction::StoreDeref { i } + if class_code.cellvars + [usize::from(i.get(OpArg::new(u32::from(u8::from(unit.arg)))))] + .as_str() + == "__class__" + ) + })); + } + #[test] fn conditional_class_body_duplicates_no_location_exit_tail() { let code = compile_exec( @@ -27528,7 +27479,7 @@ def f(): } #[test] - fn future_barry_as_flufl_is_accepted_but_ignored() { + fn future_barry_as_flufl_sets_module_and_nested_code_flags() { let code = compile_exec( "\ from __future__ import barry_as_FLUFL @@ -27537,16 +27488,48 @@ def f(): pass ", ); - let future_flags = bytecode::CodeFlags::FUTURE_DIVISION - | bytecode::CodeFlags::FUTURE_ABSOLUTE_IMPORT - | bytecode::CodeFlags::FUTURE_WITH_STATEMENT - | bytecode::CodeFlags::FUTURE_PRINT_FUNCTION - | bytecode::CodeFlags::FUTURE_UNICODE_LITERALS - | bytecode::CodeFlags::FUTURE_GENERATOR_STOP - | bytecode::CodeFlags::FUTURE_ANNOTATIONS; - assert!((code.flags & future_flags).is_empty()); + assert!( + code.flags + .contains(bytecode::CodeFlags::FUTURE_BARRY_AS_BDFL) + ); let f = find_code(&code, "f").expect("missing f code"); - assert!((f.flags & future_flags).is_empty()); + assert!(f.flags.contains(bytecode::CodeFlags::FUTURE_BARRY_AS_BDFL)); + } + + #[test] + fn function_annotation_qualnames_include_the_annotated_function() { + let code = compile_exec( + "\ +def f(x: int): + pass +class C: + def m(self, x: int): + pass +def outer(): + def inner(x: int): + pass +", + ); + let mut qualnames = Vec::new(); + fn collect(code: &CodeObject, qualnames: &mut Vec) { + for constant in code.constants.iter() { + if let ConstantData::Code { code } = constant { + if code.obj_name == "__annotate__" { + qualnames.push(code.qualname.clone()); + } + collect(code.as_ref(), qualnames); + } + } + } + collect(&code, &mut qualnames); + assert_eq!( + qualnames, + [ + "f.__annotate__", + "C.m.__annotate__", + "outer..inner.__annotate__" + ] + ); } #[test] @@ -27560,6 +27543,20 @@ x: int assert!(!code.flags.contains(bytecode::CodeFlags::FUTURE_ANNOTATIONS)); } + #[test] + fn future_import_after_extra_string_is_rejected_like_cpython() { + assert_eq!( + compile_exec_error_message( + "\ +\"\"\"Docstring\"\"\" +\"this is not a docstring\" +from __future__ import nested_scopes +", + ), + "from __future__ imports must occur at the beginning of the file" + ); + } + #[test] fn future_braces_uses_cpython_special_error() { assert_eq!( @@ -27729,6 +27726,31 @@ class C: ); } + #[test] + fn nested_class_body_loads_outer_dunder_class_while_methods_use_own_cell() { + let code = compile_exec( + "\ +class Outer: + def method(self): + class Inner: + value = __class__ + def nested(): + return __class__ +", + ); + let inner = find_code(&code, "Inner").expect("missing nested class code"); + + assert!(inner.cellvars.iter().any(|name| name == "__class__")); + assert!(inner.freevars.iter().any(|name| name == "__class__")); + assert!( + inner + .instructions + .iter() + .any(|unit| matches!(unit.op, Instruction::LoadFromDictOrDeref { .. })), + "the class body must resolve __class__ from the enclosing method while the nested method closes over the new class cell" + ); + } + #[test] fn nested_closure_parameter_class_does_not_create_outer_class_closure() { let code = compile_exec( @@ -31236,6 +31258,16 @@ class C: .map(|name| name.as_str()) .collect::>(); assert_eq!(varnames, vec!["format"]); + assert!(annotate.instructions.iter().any(|unit| matches!( + unit.op, + Instruction::LoadFastBorrow { var_num } + if usize::from(var_num.get(OpArg::new(u32::from(u8::from(unit.arg))))) == 0 + ))); + assert!(!annotate.instructions.iter().any(|unit| matches!( + unit.op, + Instruction::LoadFastCheck { var_num } + if usize::from(var_num.get(OpArg::new(u32::from(u8::from(unit.arg))))) == 0 + ))); } #[test] @@ -31259,6 +31291,39 @@ def f(x: T): pass ); } + #[test] + fn future_generic_class_annotations_do_not_capture_type_params_like_cpython() { + let code = compile_exec( + "\ +from __future__ import annotations +class A[T, *Ts, **P]: + x: T + y: tuple[*Ts] + z: Callable[P, str] +", + ); + let type_params = + find_code(&code, "").expect("missing type parameter scope"); + let class = find_direct_child_code(type_params, "A").expect("missing class body"); + + assert_eq!( + type_params + .cellvars + .iter() + .map(|name| name.as_str()) + .collect::>(), + [".type_params"] + ); + assert_eq!( + class + .freevars + .iter() + .map(|name| name.as_str()) + .collect::>(), + [".type_params"] + ); + } + #[test] fn future_unannotated_function_does_not_hide_next_annotation_block() { let code = compile_exec( @@ -31567,7 +31632,7 @@ def func[T](a: T = 'a', *, b: T = 'b'): } #[test] - fn generic_function_type_params_omit_defaults_without_defaults_like_cpython() { + fn generic_function_type_params_reserve_defaults_like_cpython() { let code = compile_exec( "\ def func[T](): @@ -31576,6 +31641,7 @@ def func[T](): ); let type_params = find_code(&code, "").expect("missing type params code"); + // The slot is reserved even though nothing is passed into it. assert_eq!(type_params.arg_count, 0); assert_eq!( type_params @@ -31583,7 +31649,7 @@ def func[T](): .iter() .map(String::as_str) .collect::>(), - vec!["T"] + vec![".defaults", "T"] ); } @@ -31602,10 +31668,24 @@ def with_kw[U](*, a: U = 1): let with_kw = find_code(&code, "").expect("missing type params code"); - assert!(with_pos.varnames.iter().any(|name| name == ".defaults")); - assert!(!with_pos.varnames.iter().any(|name| name == ".kwdefaults")); - assert!(!with_kw.varnames.iter().any(|name| name == ".defaults")); - assert!(with_kw.varnames.iter().any(|name| name == ".kwdefaults")); + assert_eq!( + with_pos + .varnames + .iter() + .map(String::as_str) + .collect::>(), + vec![".defaults"] + ); + assert_eq!(with_pos.arg_count, 1); + assert_eq!( + with_kw + .varnames + .iter() + .map(String::as_str) + .collect::>(), + vec![".defaults", ".kwdefaults"] + ); + assert_eq!(with_kw.arg_count, 1); } #[test] @@ -33178,7 +33258,7 @@ async def f(): ", ); let genexpr = - find_symbol_table(&symbol_table, "").expect("missing genexpr symbol table"); + find_symbol_table(&symbol_table, "genexpr").expect("missing genexpr symbol table"); assert!(genexpr.is_generator, "expected genexpr symbol table"); assert!( genexpr.is_coroutine, @@ -33200,7 +33280,7 @@ deoptmap = { for name in ["base", "family", "specialized"] { let symbol = symbol_table - .lookup(name) + .lookup(&name.into()) .unwrap_or_else(|| panic!("missing module symbol {name}")); assert_eq!( symbol.scope, @@ -33216,7 +33296,7 @@ deoptmap = { assert!(comp.comp_inlined, "expected comprehension to be inlined"); for name in ["base", "family", "specialized"] { let symbol = comp - .lookup(name) + .lookup(&name.into()) .unwrap_or_else(|| panic!("missing comprehension symbol {name}")); assert_eq!( symbol.scope, diff --git a/crates/codegen/src/error.rs b/crates/codegen/src/error.rs index 668ceb605dc..7092b6bb271 100644 --- a/crates/codegen/src/error.rs +++ b/crates/codegen/src/error.rs @@ -8,6 +8,7 @@ use thiserror::Error; #[derive(Error, Debug)] pub struct CodegenError { pub location: Option, + pub end_location: Option, #[source] pub error: CodegenErrorType, pub source_path: String, diff --git a/crates/codegen/src/ir.rs b/crates/codegen/src/ir.rs index 12fba37f6c3..bc25ca16262 100644 --- a/crates/codegen/src/ir.rs +++ b/crates/codegen/src/ir.rs @@ -4035,7 +4035,8 @@ impl CodeInfo { obj_name: obj_name.clone(), qualname: qualname.unwrap_or(obj_name), - max_stackdepth, + // Room for one value is always reserved, even where nothing is pushed. + max_stackdepth: max_stackdepth.max(1), instructions: CodeUnits::from(assembled.instructions), locations, constants: constants.into_iter().collect(), diff --git a/crates/codegen/src/lib.rs b/crates/codegen/src/lib.rs index a7349a5762f..b7ddb357e3c 100644 --- a/crates/codegen/src/lib.rs +++ b/crates/codegen/src/lib.rs @@ -8,6 +8,7 @@ extern crate log; extern crate alloc; +use alloc::{string::String, vec::Vec}; use rustpython_compiler_core::bytecode::ConstantData; type IndexMap = indexmap::IndexMap; @@ -23,6 +24,9 @@ mod unparse; pub use compile::CompileOpts; use ruff_python_ast as ast; +use ruff_text_size::{Ranged, TextRange, TextSize}; +use rustpython_compiler_core::SourceFile; +use rustpython_wtf8::Wtf8Buf; pub(crate) use compile::InternalResult; @@ -93,6 +97,174 @@ pub(crate) fn ast_constant_value_to_constant_data(value: ast::ConstantValue) -> } } +/// The range a decorated definition covers from its `def`/`class` keyword on. +/// +/// The parser hands over a statement that starts at the first decorator, while a +/// definition is located at the keyword that introduces it. +#[must_use] +pub fn decorated_definition_range( + source_file: &SourceFile, + statement_range: TextRange, + decorator_list: &[ast::Decorator], + keyword: &str, +) -> TextRange { + let Some(last_decorator) = decorator_list.last() else { + return statement_range; + }; + let search_start = last_decorator.expression.range().end(); + if search_start >= statement_range.end() { + return statement_range; + } + let search_range = TextRange::new(search_start, statement_range.end()); + let source = source_file.slice(search_range); + let Some(keyword_offset) = source.find(keyword) else { + return statement_range; + }; + let Ok(keyword_offset) = u32::try_from(keyword_offset) else { + return statement_range; + }; + TextRange::new( + search_start + TextSize::new(keyword_offset), + statement_range.end(), + ) +} + +/// The value of a string literal. +/// +/// The parser has nowhere to keep a lone surrogate in the value it hands over, +/// and leaves a replacement character standing in for one, so a literal that +/// carries any is read again from the source it was written in. +#[must_use] +pub fn string_literal_value(source_file: &SourceFile, string: &ast::StringLiteralValue) -> Wtf8Buf { + let value = string.to_str(); + if value.contains(char::REPLACEMENT_CHARACTER) { + string + .iter() + .map(|part| string_literal_part_value(source_file, part)) + .collect() + } else { + value.into() + } +} + +/// The value of one of the literals a string literal is written as. +#[must_use] +pub fn string_literal_part_value(source_file: &SourceFile, string: &ast::StringLiteral) -> Wtf8Buf { + if string.value.contains(char::REPLACEMENT_CHARACTER) { + let source = source_file.slice(string.range); + string_parser::parse_string_literal(source, string.flags.into()).into() + } else { + string.value.to_string().into() + } +} + +/// The value of a literal written between the interpolations of an f-string or +/// a t-string. +#[must_use] +pub fn interpolated_string_literal_value( + source_file: &SourceFile, + element: &ast::InterpolatedStringLiteralElement, + flags: ast::AnyStringFlags, +) -> Wtf8Buf { + if element.value.contains(char::REPLACEMENT_CHARACTER) { + let source = source_file.slice(element.range); + string_parser::parse_fstring_literal_element(source.into(), flags).into() + } else { + element.value.to_string().into() + } +} + +/// The text a `{expr=}` interpolation puts in front of its value, and the range +/// that text covers. +/// +/// The text is the expression as it is written plus whatever the parser found +/// around it inside the braces, with comments taken out. The range covers that +/// surrounding text as it stands, comments included. +#[must_use] +pub fn interpolation_debug_text( + source_file: &SourceFile, + debug_text: &ast::DebugText, + expression_range: TextRange, +) -> (String, TextRange) { + let leading = debug_text.leading.as_str(); + let trailing = debug_text.trailing.as_str(); + let text = [ + strip_python_comments(leading).as_str(), + source_file.slice(expression_range), + strip_python_comments(trailing).as_str(), + ] + .concat(); + let width = + |len: usize| TextSize::new(u32::try_from(len).expect("debug interpolation text too long")); + let range = TextRange::new( + expression_range.start() - width(leading.len()), + expression_range.end() + width(trailing.len()), + ); + (text, range) +} + +fn strip_python_comments(text: &str) -> String { + let chars = text.chars().collect::>(); + let mut result = String::with_capacity(text.len()); + let mut quote = None; + let mut triple_quoted = false; + let mut escaped = false; + let mut in_comment = false; + let mut index = 0; + + while index < chars.len() { + let ch = chars[index]; + if in_comment { + if matches!(ch, '\n' | '\r') { + in_comment = false; + result.push(ch); + } + index += 1; + continue; + } + + if let Some(delimiter) = quote { + result.push(ch); + if escaped { + escaped = false; + } else if ch == '\\' { + escaped = true; + } else if triple_quoted + && ch == delimiter + && chars.get(index + 1) == Some(&delimiter) + && chars.get(index + 2) == Some(&delimiter) + { + result.push(delimiter); + result.push(delimiter); + quote = None; + index += 2; + } else if !triple_quoted && ch == delimiter { + quote = None; + } + index += 1; + continue; + } + + match ch { + '#' => in_comment = true, + '\'' | '"' => { + quote = Some(ch); + triple_quoted = + chars.get(index + 1) == Some(&ch) && chars.get(index + 2) == Some(&ch); + result.push(ch); + if triple_quoted { + result.push(ch); + result.push(ch); + index += 2; + } + } + _ => result.push(ch), + } + index += 1; + } + result +} + pub trait ToPythonName { /// Returns a short name for the node suitable for use in error messages. fn python_name(&self) -> &'static str; diff --git a/crates/codegen/src/preprocess.rs b/crates/codegen/src/preprocess.rs index 084b72c87f7..466d8f35ebe 100644 --- a/crates/codegen/src/preprocess.rs +++ b/crates/codegen/src/preprocess.rs @@ -257,7 +257,7 @@ pub fn checked_future_features_in_body( future_features.insert(bytecode::CodeFlags::FUTURE_ANNOTATIONS) } FutureFeature::BarryAsFLUFL => { - // We do not support Barry-as-BDFL parser mode yet. This is a nop for now. + future_features.insert(bytecode::CodeFlags::FUTURE_BARRY_AS_BDFL) } FutureFeature::AbsoluteImport | FutureFeature::Division @@ -392,6 +392,7 @@ impl Transformer for AstPreprocessor { fn visit_expr(&self, expr: &mut Expr) { transformer::walk_expr(self, expr); + widen_implicit_call_generator_range(expr); if self.constant_folding { if let Some(optimized) = optimize_format(expr) { *expr = optimized; @@ -402,6 +403,24 @@ impl Transformer for AstPreprocessor { } } +/// Give a generator expression written straight into a call's parentheses the +/// range of those parentheses. +/// +/// `genexp` is a grammar rule of its own that consumes the parentheses it is +/// written in, so every position taken from the node covers them. The parser +/// here leaves the node spanning only the element through the last iterable. +fn widen_implicit_call_generator_range(expr: &mut Expr) { + let Expr::Call(call) = expr else { + return; + }; + let [Expr::Generator(generator)] = &mut *call.arguments.args else { + return; + }; + if !generator.parenthesized { + generator.range = call.arguments.range; + } +} + fn fold_debug_constant(expr: &Expr, optimize: u8) -> Option { let Expr::Name(name) = expr else { return None; diff --git a/crates/codegen/src/symboltable.rs b/crates/codegen/src/symboltable.rs index a771e19d36f..173921654d7 100644 --- a/crates/codegen/src/symboltable.rs +++ b/crates/codegen/src/symboltable.rs @@ -13,7 +13,7 @@ use crate::{ }; use alloc::{borrow::Cow, fmt}; use bitflags::bitflags; -use ruff_python_ast as ast; +use ruff_python_ast::{self as ast, name::Name}; use ruff_text_size::{Ranged, TextRange}; use rustpython_compiler_core::{PositionEncoding, SourceFile, SourceLocation}; @@ -24,7 +24,7 @@ const RECURSION_ERROR: &str = "maximum recursion depth exceeded during compilati #[derive(Clone)] pub struct SymbolTable { /// The name of this symbol table. Often the name of the class or function. - pub name: String, + pub name: Name, /// The type of symbol table pub typ: CompilerScope, @@ -32,6 +32,9 @@ pub struct SymbolTable { /// The line number in the source code where this symboltable begins. pub line_number: u32, + /// Monotonic creation order used by public symtable children. + pub block_index: usize, + // Return True if the block is a nested class or function pub is_nested: bool, @@ -39,7 +42,7 @@ pub struct SymbolTable { pub is_method: bool, /// A set of symbols present on this scope level. - pub symbols: IndexMap, + pub symbols: IndexMap, /// A list of sub-scopes in the order as found in the /// AST nodes. @@ -63,7 +66,7 @@ pub struct SymbolTable { pub next_sub_table: usize, /// Variable names in definition order (parameters first, then locals) - pub varnames: Vec, + pub varnames: Vec, /// Whether this class scope needs an implicit __class__ cell pub needs_class_closure: bool, @@ -116,15 +119,22 @@ pub struct SymbolTable { /// Names of type parameters that should still be mangled in type param scopes. /// When Some, only names in this set are mangled; other names are left unmangled. /// Set on type param blocks for generic classes; inherited by non-class child scopes. - pub mangled_names: Option>, + pub mangled_names: Option>, } impl SymbolTable { - fn new(name: String, typ: CompilerScope, line_number: u32, is_nested: bool) -> Self { + fn new( + name: Name, + typ: CompilerScope, + line_number: u32, + is_nested: bool, + block_index: usize, + ) -> Self { Self { name, typ, line_number, + block_index, is_nested, is_method: false, symbols: IndexMap::default(), @@ -154,16 +164,16 @@ impl SymbolTable { } fn add_format_parameter(&mut self) { - let name = ".format"; + let name = Name::new_static(".format"); let symbol = self .symbols - .entry(name.to_owned()) - .or_insert_with(|| Symbol::new(name)); + .entry(name.clone()) + .or_insert_with(|| Symbol::new(name.clone())); symbol .flags .insert(SymbolFlags::DEF_PARAM | SymbolFlags::USE); - if !self.varnames.iter().any(|varname| varname == name) { - self.varnames.push(name.to_owned()); + if !self.varnames.contains(&name) { + self.varnames.push(name); } } @@ -213,7 +223,7 @@ impl SymbolTable { } #[must_use] - pub fn lookup(&self, name: &str) -> Option<&Symbol> { + pub fn lookup(&self, name: &Name) -> Option<&Symbol> { self.symbols.get(name) } } @@ -321,20 +331,22 @@ bitflags! { /// of the symbol, and also the various uses of the symbol. #[derive(Debug, Clone)] pub struct Symbol { - pub name: String, + pub name: Name, pub scope: SymbolScope, pub flags: SymbolFlags, pub location: Option, + pub end_location: Option, } impl Symbol { - fn new(name: &str) -> Self { + fn new(name: Name) -> Self { Self { - name: name.to_owned(), + name, // table, scope: SymbolScope::Unknown, flags: SymbolFlags::empty(), location: None, + end_location: None, } } @@ -361,6 +373,7 @@ impl Symbol { pub struct SymbolTableError { error: String, location: Option, + end_location: Option, } impl SymbolTableError { @@ -373,6 +386,7 @@ impl SymbolTableError { }; CodegenError { location: self.location, + end_location: self.end_location, error, source_path, } @@ -411,7 +425,7 @@ fn analyze_symbol_table(symbol_table: &mut SymbolTable) -> SymbolTableResult { `newfree` set (which contains free variables collected from all child scopes) and sets the corresponding flags on the class's symbol table entry. */ -fn drop_class_free(symbol_table: &mut SymbolTable, newfree: &mut IndexSet) { +fn drop_class_free(symbol_table: &mut SymbolTable, newfree: &mut IndexSet) { // Check if __class__ is in the free variables collected from children // If found, it means a child scope (method) references __class__ if newfree.shift_remove("__class__") { @@ -435,10 +449,10 @@ fn drop_class_free(symbol_table: &mut SymbolTable, newfree: &mut IndexSet, - inlined_cells: &mut IndexSet, + comp_free: &mut IndexSet, + inlined_cells: &mut IndexSet, parent_type: CompilerScope, -) -> IndexSet { +) -> IndexSet { let mut removed_class_implicits = IndexSet::default(); for (name, sub_symbol) in &comp.symbols { // Skip the .0 parameter @@ -453,8 +467,11 @@ fn inline_comprehension( inlined_cells.insert(name.clone()); } - // __class__, __classdict__ and __conditional_annotations__ are never - // allowed to be free through a class scope. + // `__class__` is never allowed to be free through a class scope, see + // drop_class_free(). `__classdict__` and `__conditional_annotations__` + // have no binding to reach either, and unlike CPython -- which fails with + // an internal error while compiling such a class -- they resolve as + // globals here. let scope = if sub_symbol.scope == SymbolScope::Free && parent_type == CompilerScope::Class && matches!( @@ -476,7 +493,18 @@ fn inline_comprehension( sub_symbol.scope }; - if let Some(existing) = parent_symbols.get(name) { + if let Some(existing) = parent_symbols.get_mut(name) { + // A name the parent only learned about as a free variable of this + // comprehension carries no definition of its own; the comprehension's + // flags are what describe it. + if existing + .flags + .difference(SymbolFlags::DEF_FREE_CLASS) + .is_empty() + { + existing.flags.insert(sub_symbol.flags); + existing.scope = scope; + } // Name exists in parent if existing.is_bound() && parent_type != CompilerScope::Class { // Check if the name is free in any child of the comprehension @@ -502,7 +530,7 @@ fn inline_comprehension( removed_class_implicits } -type SymbolMap = IndexMap; +type SymbolMap = IndexMap; mod stack { use alloc::vec::Vec; @@ -585,7 +613,7 @@ impl SymbolTableAnalyzer { &mut self, symbol_table: &mut SymbolTable, class_entry: Option<&SymbolMap>, - ) -> SymbolTableResult> { + ) -> SymbolTableResult> { let symbols = core::mem::take(&mut symbol_table.symbols); let sub_tables = &mut *symbol_table.sub_tables; @@ -613,8 +641,8 @@ impl SymbolTableAnalyzer { // Collect (child_free, is_inlined) pairs from child scopes. // We need to process inlined comprehensions after the closure // when we have access to symbol_table.symbols. - let mut child_frees: Vec<(IndexSet, bool)> = Vec::new(); - let mut annotation_free: Option> = None; + let mut child_frees: Vec<(IndexSet, bool)> = Vec::new(); + let mut annotation_free: Option> = None; let mut info = ( symbols, @@ -653,7 +681,7 @@ impl SymbolTableAnalyzer { // PEP 709: Process inlined comprehensions. // Merge symbols from inlined comps into parent scope without bail-out. - let mut inlined_cells: IndexSet = IndexSet::default(); + let mut inlined_cells: IndexSet = IndexSet::default(); let mut newfree = IndexSet::default(); for (idx, (mut child_free, is_inlined)) in child_frees.into_iter().enumerate() { if is_inlined { @@ -781,7 +809,9 @@ impl SymbolTableAnalyzer { class_entry: Option<&SymbolMap>, ) -> SymbolTableResult { match symbol.scope { - SymbolScope::Free => { + // Only an explicit `nonlocal` has to name a binding. Every other free + // variable was already resolved by the scope it travelled up from. + SymbolScope::Free if symbol.flags.contains(SymbolFlags::DEF_NONLOCAL) => { if !self.tables.as_ref().is_empty() { let scope_depth = self.tables.as_ref().len(); // check if the name is already defined in any outer scope @@ -795,24 +825,24 @@ impl SymbolTableAnalyzer { return Err(SymbolTableError { error: format!("no binding for nonlocal '{}' found", symbol.name), location: symbol.location, + end_location: symbol.end_location, }); } // Check if the nonlocal binding refers to a type parameter - if symbol.flags.contains(SymbolFlags::DEF_NONLOCAL) { - for (symbols, _typ, _skip) in self.tables.iter().rev() { - if let Some(sym) = symbols.get(&symbol.name) { - if sym.flags.contains(SymbolFlags::DEF_TYPE_PARAM) { - return Err(SymbolTableError { - error: format!( - "nonlocal binding not allowed for type parameter '{}'", - symbol.name - ), - location: symbol.location, - }); - } - if sym.is_bound() { - break; - } + for (symbols, _typ, _skip) in self.tables.iter().rev() { + if let Some(sym) = symbols.get(&symbol.name) { + if sym.flags.contains(SymbolFlags::DEF_TYPE_PARAM) { + return Err(SymbolTableError { + error: format!( + "nonlocal binding not allowed for type parameter '{}'", + symbol.name + ), + location: symbol.location, + end_location: symbol.end_location, + }); + } + if sym.is_bound() { + break; } } } @@ -823,9 +853,11 @@ impl SymbolTableAnalyzer { symbol.name ), location: symbol.location, + end_location: symbol.end_location, }); } } + SymbolScope::Free => {} SymbolScope::GlobalExplicit | SymbolScope::GlobalImplicit => {} SymbolScope::Local | SymbolScope::Cell => {} SymbolScope::Unknown => { @@ -864,11 +896,8 @@ impl SymbolTableAnalyzer { { // If found in enclosing scope (function/TypeParams), use that scope - } else if self.tables.is_empty() { - // Don't make assumptions when we don't know. - SymbolScope::Unknown } else { - // If there are scopes above we assume global. + // A name bound nowhere is global. SymbolScope::GlobalImplicit }; symbol.scope = scope; @@ -879,7 +908,7 @@ impl SymbolTableAnalyzer { fn found_in_outer_scope( &mut self, - name: &str, + name: &Name, st_typ: CompilerScope, skip_enclosing_function_scope: bool, ) -> Option { @@ -924,7 +953,9 @@ impl SymbolTableAnalyzer { if let Some(sym) = symbols.get(name) { match sym.scope { - SymbolScope::GlobalExplicit => return Some(SymbolScope::GlobalExplicit), + // A global declaration binds nothing, so a name it covers is + // global here only by not being found anywhere else. + SymbolScope::GlobalExplicit => return Some(SymbolScope::GlobalImplicit), SymbolScope::GlobalImplicit => {} _ => { if sym.is_bound() { @@ -950,7 +981,7 @@ impl SymbolTableAnalyzer { if let Some(free_class) = table.get_mut(name) { free_class.flags.insert(SymbolFlags::DEF_FREE_CLASS) } else { - let mut symbol = Symbol::new(name); + let mut symbol = Symbol::new(name.clone()); symbol.flags.insert(SymbolFlags::DEF_FREE_CLASS); symbol.scope = SymbolScope::Free; table.insert(name.to_owned(), symbol); @@ -966,7 +997,7 @@ impl SymbolTableAnalyzer { // Skip: don't add __classdict__/__conditional_annotations__ // as free vars in regular functions — only annotation/type scopes need them } else if !table.contains_key(name) { - let mut symbol = Symbol::new(name); + let mut symbol = Symbol::new(name.clone()); symbol.scope = SymbolScope::Free; table.insert(name.to_owned(), symbol); } @@ -979,7 +1010,7 @@ impl SymbolTableAnalyzer { fn found_in_inner_scope( &self, sub_tables: &[SymbolTable], - name: &str, + name: &Name, st_typ: CompilerScope, ) -> Option { sub_tables.iter().find_map(|st| { @@ -993,7 +1024,7 @@ impl SymbolTableAnalyzer { || (sym.flags.contains(SymbolFlags::DEF_FREE_CLASS) && !matches!(st_typ, CompilerScope::Module)) { - if st_typ == CompilerScope::Class && name != "__class__" { + if st_typ == CompilerScope::Class { None } else { Some(SymbolScope::Cell) @@ -1018,22 +1049,21 @@ enum SymbolUsage { Imported, AnnotationAssigned, Parameter, - AnnotationParameter, Iter, TypeParam, } struct SymbolTableBuilder { - class_name: Option, + class_name: Option, // Scope stack. tables: Vec, future_annotations: bool, allow_top_level_await: bool, source_file: SourceFile, // Current scope's varnames being collected (temporary storage) - current_varnames: Vec, + current_varnames: Vec, // Stack to preserve parent varnames when entering nested scopes - varnames_stack: Vec>, + varnames_stack: Vec>, // Track if we're inside an iterable definition expression (for nested comprehensions) in_iter_def_exp: bool, // yield/yield from inside comprehension scopes is rejected with a @@ -1044,6 +1074,16 @@ struct SymbolTableBuilder { // Mirrors symtable ENTER_RECURSIVE guards during compilation. recursion_depth: usize, recursion_limit: usize, + next_block_index: usize, + done_with_future_stmts: DoneWithFuture, +} + +/// How far past the point where `from __future__ import` is still accepted the +/// module body has been scanned. +enum DoneWithFuture { + No, + DoneWithDoc, + Yes, } /// Enum to indicate in what mode an expression @@ -1074,8 +1114,10 @@ impl SymbolTableBuilder { in_conditional_block: false, recursion_depth: 0, recursion_limit: DEFAULT_RECURSION_LIMIT, + next_block_index: 0, + done_with_future_stmts: DoneWithFuture::No, }; - this.enter_scope("top", CompilerScope::Module, 0); + this.enter_scope(&"top".into(), CompilerScope::Module, 0); this } @@ -1134,7 +1176,7 @@ impl SymbolTableBuilder { Ok(symbol_table) } - fn enter_scope(&mut self, name: &str, typ: CompilerScope, line_number: u32) { + fn enter_scope(&mut self, name: &Name, typ: CompilerScope, line_number: u32) { let parent = self.tables.last(); let is_nested = parent.is_some_and(|table| table.is_nested || Self::is_function_like_scope(table.typ)); @@ -1154,7 +1196,9 @@ impl SymbolTableBuilder { .last() .and_then(|t| t.mangled_names.clone()) .filter(|_| typ != CompilerScope::Class); - let mut table = SymbolTable::new(name.to_owned(), typ, line_number, is_nested); + let block_index = self.next_block_index; + self.next_block_index += 1; + let mut table = SymbolTable::new(name.to_owned(), typ, line_number, is_nested, block_index); table.is_method = is_method; table.future_annotations = self.future_annotations; table.mangled_names = inherited_mangled_names; @@ -1166,7 +1210,7 @@ impl SymbolTableBuilder { fn enter_type_param_block( &mut self, - name: &str, + name: &Name, range: TextRange, for_class: bool, has_defaults: bool, @@ -1196,22 +1240,22 @@ impl SymbolTableBuilder { // Add __classdict__ as a USE symbol in type param scope if in class if in_class { - self.register_name("__classdict__", SymbolUsage::Used, range)?; + self.register_name(&"__classdict__".into(), SymbolUsage::Used, range)?; } if for_class { // It gets set when we create the type params tuple and used when // we build up the bases. - self.register_name(".type_params", SymbolUsage::Assigned, range)?; - self.register_name(".type_params", SymbolUsage::Used, range)?; - self.register_name(".generic_base", SymbolUsage::Assigned, range)?; - self.register_name(".generic_base", SymbolUsage::Used, range)?; + self.register_name(&".type_params".into(), SymbolUsage::Assigned, range)?; + self.register_name(&".type_params".into(), SymbolUsage::Used, range)?; + self.register_name(&".generic_base".into(), SymbolUsage::Assigned, range)?; + self.register_name(&".generic_base".into(), SymbolUsage::Used, range)?; } if has_defaults { - self.register_name(".defaults", SymbolUsage::Parameter, range)?; + self.register_name(&".defaults".into(), SymbolUsage::Parameter, range)?; } if has_kwdefaults { - self.register_name(".kwdefaults", SymbolUsage::Parameter, range)?; + self.register_name(&".kwdefaults".into(), SymbolUsage::Parameter, range)?; } Ok(()) @@ -1235,6 +1279,17 @@ impl SymbolTableBuilder { table } + fn resolve_future_annotation_names_as_globals(table: &mut SymbolTable) { + for symbol in table.symbols.values_mut() { + if symbol.scope == SymbolScope::Unknown + && symbol.flags.contains(SymbolFlags::USE) + && !symbol.is_bound() + { + symbol.scope = SymbolScope::GlobalImplicit; + } + } + } + /// Enter annotation scope (PEP 649) /// Creates or reuses the annotation block for the current scope fn enter_annotation_scope( @@ -1243,29 +1298,42 @@ impl SymbolTableBuilder { include_classdict_with_future: bool, include_conditional_annotations: bool, ) { - let current = self.tables.last_mut().unwrap(); - let can_see_class_scope = - current.typ == CompilerScope::Class || current.can_see_class_scope; - let has_conditional = current.has_conditional_annotations; - let is_nested = current.is_nested || Self::is_function_like_scope(current.typ); + let (can_see_class_scope, has_conditional, is_nested, needs_annotation_block) = { + let current = self.tables.last().unwrap(); + ( + current.typ == CompilerScope::Class || current.can_see_class_scope, + current.has_conditional_annotations, + current.is_nested || Self::is_function_like_scope(current.typ), + current.annotation_block.is_none(), + ) + }; // Create annotation block if not exists - if current.annotation_block.is_none() { + if needs_annotation_block { + let block_index = self.next_block_index; + self.next_block_index += 1; let mut annotation_table = SymbolTable::new( - "__annotate__".to_owned(), + Name::new_static("__annotate__"), CompilerScope::Annotation, line_number, is_nested, + block_index, ); // Annotation scope in class can see class scope annotation_table.can_see_class_scope = can_see_class_scope; annotation_table.skip_enclosing_function_scope = true; annotation_table.add_format_parameter(); - current.annotation_block = Some(Box::new(annotation_table)); + self.tables.last_mut().unwrap().annotation_block = Some(Box::new(annotation_table)); } // Take the annotation block and push to stack for processing - let annotation_table = current.annotation_block.take().unwrap(); + let annotation_table = self + .tables + .last_mut() + .unwrap() + .annotation_block + .take() + .unwrap(); self.tables.push(*annotation_table); // Save parent's varnames and seed with existing annotation varnames (e.g., "format") self.varnames_stack @@ -1274,9 +1342,10 @@ impl SymbolTableBuilder { if can_see_class_scope && (include_classdict_with_future || !self.future_annotations) { self.add_classdict_freevar(); - // Also add __conditional_annotations__ as free var if parent has conditional annotations + // The `__conditional_annotations__` cell is cooked up by the compiler, + // so the block only records that it reads one. if include_conditional_annotations && has_conditional { - self.add_conditional_annotations_freevar(); + self.tables.last_mut().unwrap().has_conditional_annotations = true; } } } @@ -1287,6 +1356,9 @@ impl SymbolTableBuilder { let mut table = self.tables.pop().unwrap(); // Save the collected varnames to the symbol table table.varnames = core::mem::take(&mut self.current_varnames); + if self.future_annotations { + Self::resolve_future_annotation_names_as_globals(&mut table); + } // Store back to parent's annotation_block (not sub_tables) let parent = self.tables.last_mut().unwrap(); parent.annotation_block = Some(Box::new(table)); @@ -1296,10 +1368,10 @@ impl SymbolTableBuilder { fn add_classdict_freevar(&mut self) { let table = self.tables.last_mut().unwrap(); - let name = "__classdict__"; + let name = Name::new_static("__classdict__"); let symbol = table .symbols - .entry(name.to_owned()) + .entry(name.clone()) .or_insert_with(|| Symbol::new(name)); symbol.scope = SymbolScope::Free; symbol @@ -1307,17 +1379,11 @@ impl SymbolTableBuilder { .insert(SymbolFlags::USE | SymbolFlags::DEF_FREE_CLASS); } - fn add_conditional_annotations_freevar(&mut self) { - let table = self.tables.last_mut().unwrap(); - let name = "__conditional_annotations__"; - let symbol = table - .symbols - .entry(name.to_owned()) - .or_insert_with(|| Symbol::new(name)); - symbol.scope = SymbolScope::Free; - symbol - .flags - .insert(SymbolFlags::USE | SymbolFlags::DEF_FREE_CLASS); + fn add_format_parameter(&mut self) { + self.tables.last_mut().unwrap().add_format_parameter(); + if !self.current_varnames.iter().any(|name| name == ".format") { + self.current_varnames.push(".format".into()); + } } /// Walk up the scope chain to determine if we're inside an async function. @@ -1372,29 +1438,19 @@ impl SymbolTableBuilder { } fn scan_parameter(&mut self, parameter: &ast::Parameter) -> SymbolTableResult { - let usage = if parameter.annotation.is_some() { - SymbolUsage::AnnotationParameter - } else { - SymbolUsage::Parameter - }; - // Check for duplicate parameter names let table = self.tables.last().unwrap(); if table.symbols.contains_key(parameter.name.as_str()) { - return Err(SymbolTableError { - error: format!( + return Err(self.error_ranged( + format!( "duplicate argument '{}' in function definition", parameter.name ), - location: Some( - self.source_file - .to_source_code() - .source_location(parameter.name.range.start(), PositionEncoding::Utf8), - ), - }); + parameter.name.range, + )); } - self.register_ident(¶meter.name, usage) + self.register_ident(¶meter.name, SymbolUsage::Parameter) } /// Scan an annotation from an AnnAssign statement (can be conditional) @@ -1411,11 +1467,19 @@ impl SymbolTableBuilder { let current = self.tables.last().unwrap(); let can_see_class_scope = current.typ == CompilerScope::Class || current.can_see_class_scope; - self.enter_scope("__annotate__", CompilerScope::Annotation, line_number); + self.enter_scope( + &"__annotate__".into(), + CompilerScope::Annotation, + line_number, + ); self.tables.last_mut().unwrap().can_see_class_scope = can_see_class_scope; - self.tables.last_mut().unwrap().add_format_parameter(); + self.add_format_parameter(); if can_see_class_scope { - self.register_name("__classdict__", SymbolUsage::Used, TextRange::default())?; + self.register_name( + &"__classdict__".into(), + SymbolUsage::Used, + TextRange::default(), + )?; } let was_in_unevaluated_annotation = self.tables.last().unwrap().in_unevaluated_annotation; @@ -1464,7 +1528,8 @@ impl SymbolTableBuilder { self.tables.last_mut().unwrap().in_unevaluated_annotation = was_in_unevaluated_annotation; if self.future_annotations { - let annotation_block = self.discard_scope(); + let mut annotation_block = self.discard_scope(); + Self::resolve_future_annotation_names_as_globals(&mut annotation_block); self.tables .last_mut() .unwrap() @@ -1504,7 +1569,7 @@ impl SymbolTableBuilder { if should_register_conditional_annotations { self.register_name( - "__conditional_annotations__", + &"__conditional_annotations__".into(), SymbolUsage::Used, annotation.range(), )?; @@ -1526,29 +1591,56 @@ impl SymbolTableBuilder { result } + /// Reject a `from __future__ import` that no longer opens the module. + /// + /// Only a docstring and other future statements may come first. + // = future_parse + fn track_future_statement(&mut self, statement: &ast::Stmt) -> SymbolTableResult { + match statement { + ast::Stmt::ImportFrom(ast::StmtImportFrom { module, level, .. }) + if *level == 0 && module.as_ref().map(|id| id.as_str()) == Some("__future__") => + { + if matches!(self.done_with_future_stmts, DoneWithFuture::Yes) { + return Err(self.error_ranged( + "from __future__ imports must occur at the beginning of the file" + .to_owned(), + statement.range(), + )); + } + self.done_with_future_stmts = DoneWithFuture::DoneWithDoc; + } + ast::Stmt::Expr(ast::StmtExpr { value, .. }) + if is_docstring_expr(value) + && matches!(self.done_with_future_stmts, DoneWithFuture::No) => + { + self.done_with_future_stmts = DoneWithFuture::DoneWithDoc; + } + _ => self.done_with_future_stmts = DoneWithFuture::Yes, + } + Ok(()) + } + fn scan_statement(&mut self, statement: &ast::Stmt) -> SymbolTableResult { if self.recursion_depth >= self.recursion_limit { return Err(SymbolTableError { error: RECURSION_ERROR.to_owned(), location: None, + end_location: None, }); } self.recursion_depth += 1; let result = (|| { use ast::*; + self.track_future_statement(statement)?; match &statement { Stmt::Global(StmtGlobal { names, .. }) => { for name in names { - self.register_name(name.as_str(), SymbolUsage::Global, statement.range())?; + self.register_name(name.id(), SymbolUsage::Global, statement.range())?; } } Stmt::Nonlocal(StmtNonlocal { names, .. }) => { for name in names { - self.register_name( - name.as_str(), - SymbolUsage::Nonlocal, - statement.range(), - )?; + self.register_name(name.id(), SymbolUsage::Nonlocal, statement.range())?; } } Stmt::FunctionDef(StmtFunctionDef { @@ -1562,7 +1654,14 @@ impl SymbolTableBuilder { is_async, .. }) => { - self.register_name(name.as_str(), SymbolUsage::Assigned, *range)?; + self.register_name(name.id(), SymbolUsage::Assigned, *range)?; + + let def_range = crate::decorated_definition_range( + &self.source_file, + *range, + decorator_list, + if *is_async { "async def " } else { "def " }, + ); self.scan_parameter_defaults(parameters)?; self.scan_decorators(decorator_list, ExpressionContext::Load)?; @@ -1571,18 +1670,21 @@ impl SymbolTableBuilder { // annotation scopes are nested inside and can see type parameters. if let Some(type_params) = type_params { self.enter_type_param_block( - name.as_str(), - *range, + name.id(), + def_range, false, - Self::has_positional_defaults(parameters), + // A generic function's type params scope always + // takes `.defaults`, even with no default anywhere + // in the signature. + true, Self::has_kwonlydefaults(parameters), )?; self.scan_type_params(type_params)?; } self.enter_scope_with_parameters( - name.as_str(), + name.id(), parameters, - self.line_index_start(*range), + self.line_index_start(def_range), returns.as_deref(), if *is_async { CompilerScope::AsyncFunction @@ -1611,19 +1713,27 @@ impl SymbolTableBuilder { .. }) => { let prev_class = self.class_name.clone(); - self.register_name(name.as_str(), SymbolUsage::Assigned, *range)?; + self.register_name(name.id(), SymbolUsage::Assigned, *range)?; + + let def_range = crate::decorated_definition_range( + &self.source_file, + *range, + decorator_list, + "class ", + ); + self.scan_decorators(decorator_list, ExpressionContext::Load)?; if let Some(type_params) = type_params { self.enter_type_param_block( - name.as_str(), - *range, + name.id(), + def_range, true, // for_class: enable selective mangling false, false, )?; // Set class_name for mangling in type param scope - self.class_name = Some(name.to_string()); + self.class_name = Some(name.id().clone()); self.scan_type_params(type_params)?; } @@ -1635,11 +1745,7 @@ impl SymbolTableBuilder { self.scan_expressions(&arguments.args, ExpressionContext::Load)?; for keyword in &arguments.keywords { if let Some(arg) = &keyword.arg { - self.check_name( - arg.as_str(), - ExpressionContext::Store, - keyword.range, - )?; + self.check_name(arg.id(), ExpressionContext::Store, keyword.range)?; } } for keyword in &arguments.keywords { @@ -1648,17 +1754,21 @@ impl SymbolTableBuilder { } self.enter_scope( - name.as_str(), + name.id(), CompilerScope::Class, - self.line_index_start(*range), + self.line_index_start(def_range), ); // Reset in_conditional_block for new class scope let saved_in_conditional = self.in_conditional_block; self.in_conditional_block = false; - self.class_name = Some(name.to_string()); + self.class_name = Some(name.id().clone()); if type_params.is_some() { - self.register_name(".type_params", SymbolUsage::Used, *range)?; - self.register_name("__type_params__", SymbolUsage::Assigned, *range)?; + self.register_name( + &"__type_params__".into(), + SymbolUsage::Assigned, + *range, + )?; + self.register_name(&".type_params".into(), SymbolUsage::Used, *range)?; } self.scan_statements(body)?; self.leave_scope(); @@ -1703,13 +1813,10 @@ impl SymbolTableBuilder { self.tables.last_mut().unwrap().is_coroutine = true; } if *is_async && !self.tables.last().unwrap().is_coroutine { - return Err(SymbolTableError { - error: "'async for' outside async function".to_owned(), - location: Some(self.source_file.to_source_code().source_location( - statement.range().start(), - PositionEncoding::Utf8, - )), - }); + return Err(self.error_ranged( + "'async for' outside async function".to_owned(), + statement.range(), + )); } self.scan_expression(target, ExpressionContext::Store)?; self.scan_expression(iter, ExpressionContext::Load)?; @@ -1739,35 +1846,26 @@ impl SymbolTableBuilder { for name in names { if let Some(alias) = &name.asname { // `import my_module as my_alias` - self.register_name( - alias.as_str(), - SymbolUsage::Imported, - name.name.range, - )?; + self.register_name(alias.id(), SymbolUsage::Imported, name.name.range)?; } else if name.name.as_str() == "*" { // Star imports are only allowed at module level if self.tables.last().unwrap().typ != CompilerScope::Module { - return Err(SymbolTableError { - error: "import * only allowed at module level".to_string(), - location: Some( - self.source_file.to_source_code().source_location( - name.name.range.start(), - PositionEncoding::Utf8, - ), - ), - }); + return Err(self.error_ranged( + "import * only allowed at module level".to_string(), + name.name.range, + )); } // Don't register star imports as symbols } else { // `import module` or `from x import name` - let imported_name = name.name.split('.').next().unwrap(); + let imported_name = name.name.split('.').next().unwrap().into(); self.check_name( - imported_name, + &imported_name, ExpressionContext::Store, name.name.range, )?; self.register_name( - imported_name, + &imported_name, SymbolUsage::Imported, name.name.range, )?; @@ -1813,14 +1911,12 @@ impl SymbolTableBuilder { range: target_range, .. }) => { - let id_str = id.as_str(); - if *simple { let existing_flags = self.tables.last().and_then(|table| { let name = maybe_mangle_name( - self.class_name.as_deref(), + self.class_name.as_ref(), table.mangled_names.as_ref(), - id_str, + id, ); table.symbols.get(name.as_ref()).map(|symbol| symbol.flags) }); @@ -1838,45 +1934,19 @@ impl SymbolTableBuilder { } else { "nonlocal" }; - return Err(SymbolTableError { - error: format!( - "annotated name '{id_str}' can't be {usage}" - ), - location: Some( - self.source_file.to_source_code().source_location( - range.start(), - PositionEncoding::Utf8, - ), - ), - }); + return Err(self.error_ranged( + format!("annotated name '{id}' can't be {usage}"), + *range, + )); } self.register_name( - id_str, + id, SymbolUsage::AnnotationAssigned, *target_range, )?; - // PEP 649: Register annotate function in module/class scope - let current_scope = self.tables.last().map(|t| t.typ); - match current_scope { - Some(CompilerScope::Module) => { - self.register_name( - "__annotate__", - SymbolUsage::Assigned, - *range, - )?; - } - Some(CompilerScope::Class) => { - self.register_name( - "__annotate_func__", - SymbolUsage::Assigned, - *range, - )?; - } - _ => {} - } } else if value.is_some() { - self.register_name(id_str, SymbolUsage::Assigned, *target_range)?; + self.register_name(id, SymbolUsage::Assigned, *target_range)?; } } _ => { @@ -1898,13 +1968,10 @@ impl SymbolTableBuilder { self.tables.last_mut().unwrap().is_coroutine = true; } if *is_async && !self.tables.last().unwrap().is_coroutine { - return Err(SymbolTableError { - error: "'async with' outside async function".to_owned(), - location: Some(self.source_file.to_source_code().source_location( - statement.range().start(), - PositionEncoding::Utf8, - )), - }); + return Err(self.error_ranged( + "'async with' outside async function".to_owned(), + statement.range(), + )); } // PEP 649: Track conditional block for annotations let saved_in_conditional_block = self.in_conditional_block; @@ -1940,11 +2007,7 @@ impl SymbolTableBuilder { self.scan_expression(expression, ExpressionContext::Load)?; } if let Some(name) = name { - self.register_name( - name.as_str(), - SymbolUsage::Assigned, - handler.range(), - )?; + self.register_name(name.id(), SymbolUsage::Assigned, handler.range())?; } self.scan_statements(body)?; } @@ -1982,16 +2045,11 @@ impl SymbolTableBuilder { .. }) => { let Some(name_expr) = name.as_name_expr() else { - return Err(SymbolTableError { - error: "type alias expects name".to_owned(), - location: Some( - self.source_file - .to_source_code() - .source_location(name.range().start(), PositionEncoding::Utf8), - ), - }); + return Err( + self.error_ranged("type alias expects name".to_owned(), name.range()) + ); }; - let alias_name = name_expr.id.to_string(); + let alias_name = name_expr.id(); self.scan_expression(name, ExpressionContext::Store)?; // Check before entering any sub-scopes let in_class = self @@ -2000,23 +2058,27 @@ impl SymbolTableBuilder { .is_some_and(|t| t.typ == CompilerScope::Class); let is_generic = type_params.is_some(); if let Some(type_params) = type_params { - self.enter_type_param_block(&alias_name, *range, false, false, false)?; + self.enter_type_param_block(alias_name, *range, false, false, false)?; self.scan_type_params(type_params)?; } // Value scope for lazy evaluation self.enter_scope( - &alias_name, + alias_name, CompilerScope::TypeAlias, self.line_index_start(*range), ); // Evaluator takes a format parameter - self.register_name(".format", SymbolUsage::Parameter, *range)?; - self.register_name(".format", SymbolUsage::Used, *range)?; + self.register_name(&".format".into(), SymbolUsage::Parameter, *range)?; + self.register_name(&".format".into(), SymbolUsage::Used, *range)?; if in_class { if let Some(table) = self.tables.last_mut() { table.can_see_class_scope = true; } - self.register_name("__classdict__", SymbolUsage::Used, value.range())?; + self.register_name( + &"__classdict__".into(), + SymbolUsage::Used, + value.range(), + )?; } self.scan_expression(value, ExpressionContext::Load)?; self.leave_scope(); @@ -2025,14 +2087,7 @@ impl SymbolTableBuilder { } } Stmt::IpyEscapeCommand(stmt) => { - return Err(SymbolTableError { - error: "invalid syntax".to_owned(), - location: Some( - self.source_file - .to_source_code() - .source_location(stmt.range.start(), PositionEncoding::Utf8), - ), - }); + return Err(self.error_ranged("invalid syntax".to_owned(), stmt.range)); } } Ok(()) @@ -2063,6 +2118,21 @@ impl SymbolTableBuilder { Ok(()) } + /// Scan the interpolations of a format spec, and the format specs those + /// carry in turn: `f"{x:{y:{z}}}"` only reaches `z` through two of them. + fn scan_format_spec( + &mut self, + format_spec: &ast::InterpolatedStringFormatSpec, + ) -> SymbolTableResult { + for element in format_spec.elements.interpolations() { + self.scan_expression(&element.expression, ExpressionContext::Load)?; + if let Some(nested) = &element.format_spec { + self.scan_format_spec(nested)?; + } + } + Ok(()) + } + fn scan_expression( &mut self, expression: &ast::Expr, @@ -2072,6 +2142,7 @@ impl SymbolTableBuilder { return Err(SymbolTableError { error: RECURSION_ERROR.to_owned(), location: None, + end_location: None, }); } self.recursion_depth += 1; @@ -2111,15 +2182,10 @@ impl SymbolTableBuilder { }; if let Some(context_name) = context_name { - return Err(SymbolTableError { - error: format!("{keyword} expression cannot be used within {context_name}"), - location: Some( - self.source_file.to_source_code().source_location( - expression.range().start(), - PositionEncoding::Utf8, - ), - ), - }); + return Err(self.error_ranged( + format!("{keyword} expression cannot be used within {context_name}"), + expression.range(), + )); } } @@ -2144,7 +2210,7 @@ impl SymbolTableBuilder { Expr::Attribute(ExprAttribute { value, attr, range, .. }) => { - self.check_name(attr.as_str(), context, *range)?; + self.check_name(attr.id(), context, *range)?; self.scan_expression(value, ExpressionContext::Load)?; } Expr::Dict(ExprDict { items, .. }) => { @@ -2162,25 +2228,19 @@ impl SymbolTableBuilder { if !self.allows_top_level_await() && !Self::is_function_like_scope(current_scope) { - return Err(SymbolTableError { - error: "'await' outside function".to_owned(), - location: Some(self.source_file.to_source_code().source_location( - expression.range().start(), - PositionEncoding::Utf8, - )), - }); + return Err(self.error_ranged( + "'await' outside function".to_owned(), + expression.range(), + )); } if current_scope != CompilerScope::AsyncFunction && current_scope != CompilerScope::Comprehension && !self.allows_top_level_await() { - return Err(SymbolTableError { - error: "'await' outside async function".to_owned(), - location: Some(self.source_file.to_source_code().source_location( - expression.range().start(), - PositionEncoding::Utf8, - )), - }); + return Err(self.error_ranged( + "'await' outside async function".to_owned(), + expression.range(), + )); } self.scan_expression(value, context)?; self.tables.last_mut().unwrap().is_coroutine = true; @@ -2196,13 +2256,10 @@ impl SymbolTableBuilder { .last() .is_some_and(|table| table.typ == CompilerScope::Comprehension) { - return Err(SymbolTableError { - error: format!("'yield' inside {context_name}"), - location: Some(self.source_file.to_source_code().source_location( - expression.range().start(), - PositionEncoding::Utf8, - )), - }); + return Err(self.error_ranged( + format!("'yield' inside {context_name}"), + expression.range(), + )); } } Expr::YieldFrom(ExprYieldFrom { value, .. }) => { @@ -2214,13 +2271,10 @@ impl SymbolTableBuilder { .last() .is_some_and(|table| table.typ == CompilerScope::Comprehension) { - return Err(SymbolTableError { - error: format!("'yield' inside {context_name}"), - location: Some(self.source_file.to_source_code().source_location( - expression.range().start(), - PositionEncoding::Utf8, - )), - }); + return Err(self.error_ranged( + format!("'yield' inside {context_name}"), + expression.range(), + )); } } Expr::UnaryOp(ExprUnaryOp { operand, .. }) => { @@ -2258,7 +2312,14 @@ impl SymbolTableBuilder { self.in_iter_def_exp = true; } // Generator expression - is_generator = true - self.scan_comprehension("", elt, None, generators, *range, true)?; + self.scan_comprehension( + &"genexpr".into(), + elt, + None, + generators, + *range, + true, + )?; self.in_iter_def_exp = was_in_iter_def_exp; } Expr::ListComp(ExprListComp { @@ -2272,7 +2333,14 @@ impl SymbolTableBuilder { self.in_iter_def_exp = true; } // List comprehension - is_generator = false (can be inlined) - self.scan_comprehension("", elt, None, generators, *range, false)?; + self.scan_comprehension( + &"".into(), + elt, + None, + generators, + *range, + false, + )?; self.in_iter_def_exp = was_in_iter_def_exp; } Expr::SetComp(ExprSetComp { @@ -2286,7 +2354,14 @@ impl SymbolTableBuilder { self.in_iter_def_exp = true; } // Set comprehension - is_generator = false (can be inlined) - self.scan_comprehension("", elt, None, generators, *range, false)?; + self.scan_comprehension( + &"".into(), + elt, + None, + generators, + *range, + false, + )?; self.in_iter_def_exp = was_in_iter_def_exp; } Expr::DictComp(ExprDictComp { @@ -2303,7 +2378,7 @@ impl SymbolTableBuilder { // Dict comprehension - is_generator = false (can be inlined) let key = key.as_ref(); self.scan_comprehension( - "", + &"".into(), key, Some(value), generators, @@ -2327,7 +2402,7 @@ impl SymbolTableBuilder { self.scan_expressions(&arguments.args, ExpressionContext::Load)?; for keyword in &arguments.keywords { if let Some(arg) = &keyword.arg { - self.check_name(arg.as_str(), ExpressionContext::Store, keyword.range)?; + self.check_name(arg.id(), ExpressionContext::Store, keyword.range)?; } } for keyword in &arguments.keywords { @@ -2335,8 +2410,6 @@ impl SymbolTableBuilder { } } Expr::Name(ExprName { id, range, .. }) => { - let id = id.as_str(); - self.check_name(id, context, *range)?; if !self @@ -2365,7 +2438,7 @@ impl SymbolTableBuilder { && Self::is_function_like_scope(self.tables.last().unwrap().typ) && id == "super" { - self.register_name("__class__", SymbolUsage::Used, *range)?; + self.register_name(&"__class__".into(), SymbolUsage::Used, *range)?; } } } @@ -2378,7 +2451,7 @@ impl SymbolTableBuilder { self.scan_parameter_defaults(parameters)?; } self.enter_scope_with_parameters( - "lambda", + &"lambda".into(), parameters, self.line_index_start(expression.range()), None, // lambdas have no return annotation @@ -2388,7 +2461,7 @@ impl SymbolTableBuilder { )?; } else { self.enter_scope( - "lambda", + &"lambda".into(), CompilerScope::Lambda, self.line_index_start(expression.range()), ); @@ -2413,9 +2486,7 @@ impl SymbolTableBuilder { if let Some(format_spec) = &expr.runtime_formatted_value_format_spec { self.scan_expression(format_spec, ExpressionContext::Load)?; } else if let Some(format_spec) = &expr.format_spec { - for element in format_spec.elements.interpolations() { - self.scan_expression(&element.expression, ExpressionContext::Load)? - } + self.scan_format_spec(format_spec)?; } } } @@ -2438,9 +2509,7 @@ impl SymbolTableBuilder { self.scan_expression(format_spec, ExpressionContext::Load)?; } } else if let Some(format_spec) = &expr.format_spec { - for element in format_spec.elements.interpolations() { - self.scan_expression(&element.expression, ExpressionContext::Load)? - } + self.scan_format_spec(format_spec)?; } } } @@ -2453,14 +2522,7 @@ impl SymbolTableBuilder { | Expr::NoneLiteral(_) | Expr::EllipsisLiteral(_) => {} Expr::IpyEscapeCommand(expr) => { - return Err(SymbolTableError { - error: "invalid syntax".to_owned(), - location: Some( - self.source_file - .to_source_code() - .source_location(expr.range.start(), PositionEncoding::Utf8), - ), - }); + return Err(self.error_ranged("invalid syntax".to_owned(), expr.range)); } Expr::If(ExprIf { test, body, orelse, .. @@ -2479,16 +2541,11 @@ impl SymbolTableBuilder { // named expressions are not allowed in the definition of // comprehension iterator definitions (including nested comprehensions) if context == ExpressionContext::IterDefinitionExp || self.in_iter_def_exp { - return Err(SymbolTableError { - error: + return Err(self.error_ranged( "assignment expression cannot be used in a comprehension iterable expression" .to_string(), - location: Some( - self.source_file - .to_source_code() - .source_location(range.start(), PositionEncoding::Utf8), - ), - }); + *range, + )); } let named_target = if let Expr::Name(ExprName { @@ -2497,7 +2554,6 @@ impl SymbolTableBuilder { .. }) = &**target { - let id = id.as_str(); self.check_name(id, ExpressionContext::Store, *target_range)?; let table = self.tables.last().unwrap(); if table.typ == CompilerScope::Comprehension { @@ -2525,7 +2581,7 @@ impl SymbolTableBuilder { fn scan_comprehension( &mut self, - scope_name: &str, + scope_name: &Name, elt1: &ast::Expr, elt2: Option<&ast::Expr>, generators: &[ast::Comprehension], @@ -2565,14 +2621,14 @@ impl SymbolTableBuilder { } // Register the passed argument to the generator function as the name ".0" - self.register_name(".0", SymbolUsage::Parameter, range)?; + self.register_name(&".0".into(), SymbolUsage::Parameter, range)?; let saved_comprehension_yield_context = self.comprehension_yield_context; - self.comprehension_yield_context = Some(match scope_name { + self.comprehension_yield_context = Some(match scope_name.as_ref() { "" => "list comprehension", "" => "set comprehension", "" => "dict comprehension", - "" => "generator expression", + "genexpr" => "generator expression", _ => "comprehension", }); @@ -2615,14 +2671,10 @@ impl SymbolTableBuilder { && !self.is_in_async_context() && !self.allows_top_level_await() { - return Err(SymbolTableError { - error: "asynchronous comprehension outside of an asynchronous function".to_owned(), - location: Some( - self.source_file - .to_source_code() - .source_location(range.start(), PositionEncoding::Utf8), - ), - }); + return Err(self.error_ranged( + "asynchronous comprehension outside of an asynchronous function".to_owned(), + range, + )); } if propagate_coroutine { self.tables.last_mut().unwrap().is_coroutine = true; @@ -2636,7 +2688,7 @@ impl SymbolTableBuilder { fn scan_type_param_bound_or_default( &mut self, expr: &ast::Expr, - scope_name: &str, + scope_name: &Name, scope_info: &'static str, ) -> SymbolTableResult { // Bounds/defaults are compiled as annotation scopes. @@ -2644,14 +2696,14 @@ impl SymbolTableBuilder { let line_number = self.line_index_start(expr.range()); self.enter_scope(scope_name, CompilerScope::TypeVariable, line_number); // Evaluator takes a format parameter - self.register_name(".format", SymbolUsage::Parameter, expr.range())?; - self.register_name(".format", SymbolUsage::Used, expr.range())?; + self.register_name(&".format".into(), SymbolUsage::Parameter, expr.range())?; + self.register_name(&".format".into(), SymbolUsage::Used, expr.range())?; if in_class { if let Some(table) = self.tables.last_mut() { table.can_see_class_scope = true; } - self.register_name("__classdict__", SymbolUsage::Used, expr.range())?; + self.register_name(&"__classdict__".into(), SymbolUsage::Used, expr.range())?; } self.tables.last_mut().unwrap().scope_info = Some(scope_info); @@ -2671,6 +2723,7 @@ impl SymbolTableBuilder { return Err(SymbolTableError { error: RECURSION_ERROR.to_owned(), location: None, + end_location: None, }); } self.recursion_depth += 1; @@ -2683,18 +2736,15 @@ impl SymbolTableBuilder { default, .. }) => { - self.register_name(name.as_str(), SymbolUsage::TypeParam, *type_var_range)?; + self.register_name(name.id(), SymbolUsage::TypeParam, *type_var_range)?; if name.as_str() == "__classdict__" { - return Err(SymbolTableError { - error: format!( + return Err(self.error_ranged( + format!( "reserved name '{}' cannot be used for type parameter", name.as_str() ), - location: Some(self.source_file.to_source_code().source_location( - type_var_range.start(), - PositionEncoding::Utf8, - )), - }); + *type_var_range, + )); } // Process bound in a separate scope @@ -2704,18 +2754,14 @@ impl SymbolTableBuilder { } else { "a TypeVar bound" }; - self.scan_type_param_bound_or_default( - binding, - name.as_str(), - scope_info, - )?; + self.scan_type_param_bound_or_default(binding, name.id(), scope_info)?; } // Process default in a separate scope if let Some(default_value) = default { self.scan_type_param_bound_or_default( default_value, - name.as_str(), + name.id(), "a TypeVar default", )?; } @@ -2726,24 +2772,19 @@ impl SymbolTableBuilder { default, .. }) => { - self.register_name(name, SymbolUsage::TypeParam, *param_spec_range)?; + self.register_name(name.id(), SymbolUsage::TypeParam, *param_spec_range)?; if name == "__classdict__" { - return Err(SymbolTableError { - error: format!( - "reserved name '{name}' cannot be used for type parameter" - ), - location: Some(self.source_file.to_source_code().source_location( - param_spec_range.start(), - PositionEncoding::Utf8, - )), - }); + return Err(self.error_ranged( + format!("reserved name '{name}' cannot be used for type parameter"), + *param_spec_range, + )); } // Process default in a separate scope if let Some(default_value) = default { self.scan_type_param_bound_or_default( default_value, - name, + name.id(), "a ParamSpec default", )?; } @@ -2754,24 +2795,23 @@ impl SymbolTableBuilder { default, .. }) => { - self.register_name(name, SymbolUsage::TypeParam, *type_var_tuple_range)?; + self.register_name( + name.id(), + SymbolUsage::TypeParam, + *type_var_tuple_range, + )?; if name == "__classdict__" { - return Err(SymbolTableError { - error: format!( - "reserved name '{name}' cannot be used for type parameter" - ), - location: Some(self.source_file.to_source_code().source_location( - type_var_tuple_range.start(), - PositionEncoding::Utf8, - )), - }); + return Err(self.error_ranged( + format!("reserved name '{name}' cannot be used for type parameter"), + *type_var_tuple_range, + )); } // Process default in a separate scope if let Some(default_value) = default { self.scan_type_param_bound_or_default( default_value, - name, + name.id(), "a TypeVarTuple default", )?; } @@ -2797,6 +2837,7 @@ impl SymbolTableBuilder { return Err(SymbolTableError { error: RECURSION_ERROR.to_owned(), location: None, + end_location: None, }); } self.recursion_depth += 1; @@ -2823,17 +2864,9 @@ impl SymbolTableBuilder { self.scan_patterns(patterns)?; if let Some(rest) = rest { if rest.as_str() == "_" { - return Err(SymbolTableError { - error: "invalid syntax".to_owned(), - location: Some( - self.source_file.to_source_code().source_location( - rest.range.start(), - PositionEncoding::Utf8, - ), - ), - }); + return Err(self.error_ranged("invalid syntax".to_owned(), rest.range)); } - self.register_name(rest.as_str(), SymbolUsage::Assigned, pattern.range())?; + self.register_name(rest.id(), SymbolUsage::Assigned, pattern.range())?; } } MatchClass(ast::PatternMatchClass { cls, arguments, .. }) => { @@ -2841,7 +2874,7 @@ impl SymbolTableBuilder { self.scan_patterns(&arguments.patterns)?; for kw in &arguments.keywords { self.check_name( - kw.attr.as_str(), + kw.attr.id(), ExpressionContext::Store, kw.pattern.range(), )?; @@ -2852,7 +2885,7 @@ impl SymbolTableBuilder { } MatchStar(ast::PatternMatchStar { name, .. }) => { if let Some(name) = name { - self.register_name(name.as_str(), SymbolUsage::Assigned, pattern.range())?; + self.register_name(name.id(), SymbolUsage::Assigned, pattern.range())?; } } MatchAs(ast::PatternMatchAs { @@ -2864,7 +2897,7 @@ impl SymbolTableBuilder { self.scan_pattern(as_pattern)?; } if let Some(name) = name { - self.register_name(name.as_str(), SymbolUsage::Assigned, pattern.range())?; + self.register_name(name.id(), SymbolUsage::Assigned, pattern.range())?; } } MatchOr(ast::PatternMatchOr { patterns, .. }) => self.scan_patterns(patterns)?, @@ -2896,21 +2929,13 @@ impl SymbolTableBuilder { .any(|arg| arg.default.is_some()) } - fn has_positional_defaults(parameters: &ast::Parameters) -> bool { - parameters - .posonlyargs - .iter() - .chain(parameters.args.iter()) - .any(|arg| arg.default.is_some()) - } - #[expect( clippy::too_many_arguments, reason = "keeps parameter/default scanning options explicit at call sites" )] fn enter_scope_with_parameters( &mut self, - name: &str, + name: &Name, parameters: &ast::Parameters, line_number: u32, returns: Option<&ast::Expr>, @@ -2946,34 +2971,32 @@ impl SymbolTableBuilder { Ok(()) } + fn error_ranged(&self, error: String, range: TextRange) -> SymbolTableError { + let source_code = self.source_file.to_source_code(); + SymbolTableError { + error, + location: Some(source_code.source_location(range.start(), PositionEncoding::Utf8)), + end_location: Some(source_code.source_location(range.end(), PositionEncoding::Utf8)), + } + } + fn register_ident(&mut self, ident: &ast::Identifier, role: SymbolUsage) -> SymbolTableResult { - self.register_name(ident.as_str(), role, ident.range) + self.register_name(ident.id(), role, ident.range) } fn check_name( &self, - name: &str, + name: &Name, context: ExpressionContext, range: TextRange, ) -> SymbolTableResult { if name == "__debug__" { - let location = Some( - self.source_file - .to_source_code() - .source_location(range.start(), PositionEncoding::Utf8), - ); match context { ExpressionContext::Store | ExpressionContext::Iter => { - return Err(SymbolTableError { - error: "cannot assign to __debug__".to_owned(), - location, - }); + return Err(self.error_ranged("cannot assign to __debug__".to_owned(), range)); } ExpressionContext::Delete => { - return Err(SymbolTableError { - error: "cannot delete __debug__".to_owned(), - location, - }); + return Err(self.error_ranged("cannot delete __debug__".to_owned(), range)); } _ => {} } @@ -2984,17 +3007,11 @@ impl SymbolTableBuilder { // Mirrors symtable_extend_namedexpr_scope(): assignment expressions // inside comprehensions bind in the nearest function/module-like scope, not // in the synthetic comprehension scope itself. - fn extend_namedexpr_scope(&mut self, name: &str, range: TextRange) -> SymbolTableResult { - let location = Some( - self.source_file - .to_source_code() - .source_location(range.start(), PositionEncoding::Utf8), - ); - + fn extend_namedexpr_scope(&mut self, name: &Name, range: TextRange) -> SymbolTableResult { for table_idx in (0..self.tables.len()).rev() { let table_type = self.tables[table_idx].typ; let mangled = maybe_mangle_name( - self.class_name.as_deref(), + self.class_name.as_ref(), self.tables[table_idx].mangled_names.as_ref(), name, ) @@ -3010,12 +3027,7 @@ impl SymbolTableBuilder { .contains(SymbolFlags::DEF_LOCAL | SymbolFlags::DEF_COMP_ITER) }) { - return Err(SymbolTableError { - error: format!( - "assignment expression cannot rebind comprehension iteration variable '{name}'" - ), - location, - }); + return Err(self.error_ranged(format!( "assignment expression cannot rebind comprehension iteration variable '{name}'" ), range)); } continue; } @@ -3030,7 +3042,7 @@ impl SymbolTableBuilder { let current_symbol = current .symbols .entry(mangled.clone()) - .or_insert_with(|| Symbol::new(mangled.as_str())); + .or_insert_with(|| Symbol::new(mangled.clone())); if parent_is_global { current_symbol.flags.insert(SymbolFlags::DEF_GLOBAL); current_symbol.scope = SymbolScope::GlobalExplicit; @@ -3042,7 +3054,7 @@ impl SymbolTableBuilder { let symbol = self.tables[table_idx] .symbols .entry(mangled.clone()) - .or_insert_with(|| Symbol::new(mangled.as_str())); + .or_insert_with(|| Symbol::new(mangled.clone())); symbol.flags.insert(SymbolFlags::DEF_LOCAL); return Ok(()); } @@ -3051,45 +3063,29 @@ impl SymbolTableBuilder { let current_symbol = current .symbols .entry(mangled.clone()) - .or_insert_with(|| Symbol::new(mangled.as_str())); + .or_insert_with(|| Symbol::new(mangled.clone())); current_symbol.flags.insert(SymbolFlags::DEF_GLOBAL); current_symbol.scope = SymbolScope::GlobalExplicit; let symbol = self.tables[table_idx] .symbols .entry(mangled.clone()) - .or_insert_with(|| Symbol::new(mangled.as_str())); + .or_insert_with(|| Symbol::new(mangled.clone())); symbol.flags.insert(SymbolFlags::DEF_GLOBAL); symbol.scope = SymbolScope::GlobalExplicit; return Ok(()); } CompilerScope::Class => { - return Err(SymbolTableError { - error: "assignment expression within a comprehension cannot be used in a class body".to_string(), - location, - }); + return Err(self.error_ranged("assignment expression within a comprehension cannot be used in a class body".to_string(), range)); } CompilerScope::TypeParams => { - return Err(SymbolTableError { - error: "assignment expression within a comprehension cannot be used within the definition of a generic".to_string(), - location, - }); + return Err(self.error_ranged("assignment expression within a comprehension cannot be used within the definition of a generic".to_string(), range)); } CompilerScope::TypeAlias => { - return Err(SymbolTableError { - error: - "assignment expression within a comprehension cannot be used in a type alias" - .to_string(), - location, - }); + return Err(self.error_ranged("assignment expression within a comprehension cannot be used in a type alias" .to_string(), range)); } CompilerScope::TypeVariable => { - return Err(SymbolTableError { - error: - "assignment expression within a comprehension cannot be used in a TypeVar bound" - .to_string(), - location, - }); + return Err(self.error_ranged("assignment expression within a comprehension cannot be used in a TypeVar bound" .to_string(), range)); } CompilerScope::Annotation => {} CompilerScope::Comprehension => unreachable!(), @@ -3101,15 +3097,13 @@ impl SymbolTableBuilder { fn register_name( &mut self, - name: &str, + name: &Name, role: SymbolUsage, range: TextRange, ) -> SymbolTableResult { - let location = self - .source_file - .to_source_code() - .source_location(range.start(), PositionEncoding::Utf8); - let location = Some(location); + let source_code = self.source_file.to_source_code(); + let location = Some(source_code.source_location(range.start(), PositionEncoding::Utf8)); + let end_location = Some(source_code.source_location(range.end(), PositionEncoding::Utf8)); // symtable_add_def_ctx() runs check_name() for definition // roles covered by DEF_PARAM | DEF_LOCAL | DEF_IMPORT before adding @@ -3121,7 +3115,6 @@ impl SymbolTableBuilder { | SymbolUsage::Imported | SymbolUsage::AnnotationAssigned | SymbolUsage::Parameter - | SymbolUsage::AnnotationParameter | SymbolUsage::Iter | SymbolUsage::TypeParam ) { @@ -3140,11 +3133,7 @@ impl SymbolTableBuilder { } let original_name = name; - let name = maybe_mangle_name( - self.class_name.as_deref(), - table.mangled_names.as_ref(), - name, - ); + let name = &maybe_mangle_name(self.class_name.as_ref(), table.mangled_names.as_ref(), name); // Some checks for the symbol that present on this scope level: let symbol = if let Some(symbol) = table.symbols.get_mut(name.as_ref()) { let flags = &symbol.flags; @@ -3161,17 +3150,15 @@ impl SymbolTableBuilder { "comprehension inner loop cannot rebind assignment expression target '{original_name}'" ), location, + end_location, }); } - if matches!( - role, - SymbolUsage::Parameter | SymbolUsage::AnnotationParameter - ) && flags.contains(SymbolFlags::DEF_PARAM) - { + if matches!(role, SymbolUsage::Parameter) && flags.contains(SymbolFlags::DEF_PARAM) { return Err(SymbolTableError { error: format!("duplicate argument '{original_name}' in function definition"), location, + end_location, }); } @@ -3181,6 +3168,7 @@ impl SymbolTableBuilder { return Err(SymbolTableError { error: format!("duplicate type parameter '{name}'"), location, + end_location, }); } match role { @@ -3189,18 +3177,21 @@ impl SymbolTableBuilder { return Err(SymbolTableError { error: format!("name '{name}' is parameter and global"), location, + end_location, }); } if flags.contains(SymbolFlags::USE) { return Err(SymbolTableError { error: format!("name '{name}' is used prior to global declaration"), location, + end_location, }); } if flags.contains(SymbolFlags::DEF_ANNOT) { return Err(SymbolTableError { error: format!("annotated name '{name}' can't be global"), location, + end_location, }); } if flags.contains(SymbolFlags::DEF_LOCAL) { @@ -3209,6 +3200,7 @@ impl SymbolTableBuilder { "name '{name}' is assigned to before global declaration" ), location, + end_location, }); } } @@ -3217,18 +3209,21 @@ impl SymbolTableBuilder { return Err(SymbolTableError { error: format!("name '{name}' is parameter and nonlocal"), location, + end_location, }); } if flags.contains(SymbolFlags::USE) { return Err(SymbolTableError { error: format!("name '{name}' is used prior to nonlocal declaration"), location, + end_location, }); } if flags.contains(SymbolFlags::DEF_ANNOT) { return Err(SymbolTableError { error: format!("annotated name '{name}' can't be nonlocal"), location, + end_location, }); } if flags.contains(SymbolFlags::DEF_LOCAL) { @@ -3237,6 +3232,7 @@ impl SymbolTableBuilder { "name '{name}' is assigned to before nonlocal declaration" ), location, + end_location, }); } } @@ -3253,6 +3249,7 @@ impl SymbolTableBuilder { return Err(SymbolTableError { error: format!("annotated name '{name}' can't be {usage}"), location, + end_location, }); } _ => { @@ -3268,6 +3265,7 @@ impl SymbolTableBuilder { return Err(SymbolTableError { error: "nonlocal declaration not allowed at module level".into(), location, + end_location, }); } _ => { @@ -3275,12 +3273,16 @@ impl SymbolTableBuilder { } } // Insert symbol when required: - let symbol = Symbol::new(name.as_ref()); - table.symbols.entry(name.into_owned()).or_insert(symbol) + let symbol = Symbol::new(name.clone().into_owned()); + table + .symbols + .entry(name.clone().into_owned()) + .or_insert(symbol) }; if matches!(role, SymbolUsage::Global | SymbolUsage::Nonlocal) { symbol.location = location; + symbol.end_location = end_location; } // Set proper scope and flags on symbol: @@ -3291,7 +3293,7 @@ impl SymbolTableBuilder { flags.insert(SymbolFlags::DEF_NONLOCAL); } SymbolUsage::Imported => { - flags.insert(SymbolFlags::DEF_LOCAL | SymbolFlags::DEF_IMPORT); + flags.insert(SymbolFlags::DEF_IMPORT); } SymbolUsage::Parameter => { flags.insert(SymbolFlags::DEF_PARAM); @@ -3301,14 +3303,6 @@ impl SymbolTableBuilder { self.current_varnames.push(name_str); } } - SymbolUsage::AnnotationParameter => { - flags.insert(SymbolFlags::DEF_PARAM | SymbolFlags::DEF_ANNOT); - // Annotated parameters are also added to varnames - let name_str = symbol.name.clone(); - if !self.current_varnames.contains(&name_str) { - self.current_varnames.push(name_str); - } - } SymbolUsage::AnnotationAssigned => { flags.insert(SymbolFlags::DEF_LOCAL | SymbolFlags::DEF_ANNOT); } @@ -3330,6 +3324,18 @@ impl SymbolTableBuilder { } } + // A global declaration is recorded in the module block as well, so a name + // declared global anywhere is global there too. + if matches!(role, SymbolUsage::Global) { + let module_table = self.tables.first_mut().expect("no module symbol table"); + let symbol = module_table + .symbols + .entry(name.clone().into_owned()) + .or_insert_with(|| Symbol::new(name.clone().into_owned())); + symbol.flags.insert(SymbolFlags::DEF_GLOBAL); + symbol.scope = SymbolScope::GlobalExplicit; + } + Ok(()) } } @@ -3345,38 +3351,38 @@ fn is_docstring_expr(expr: &ast::Expr) -> bool { ) } -pub(crate) fn mangle_name<'a>(class_name: Option<&str>, name: &'a str) -> Cow<'a, str> { - let class_name = match class_name { - Some(n) => n, - None => return name.into(), +pub(crate) fn mangle_name<'a>(class_name: Option<&Name>, name: &'a Name) -> Cow<'a, Name> { + let Some(class_name) = class_name else { + return Cow::Borrowed(name); }; + if !name.starts_with("__") || name.ends_with("__") || name.contains('.') { - return name.into(); + return Cow::Borrowed(name); } // Strip leading underscores from class name let class_name = class_name.trim_start_matches('_'); if class_name.is_empty() { - return name.into(); + return Cow::Borrowed(name); } let mut ret = String::with_capacity(1 + class_name.len() + name.len()); ret.push('_'); ret.push_str(class_name); ret.push_str(name); - ret.into() + Cow::Owned(ret.into()) } /// Selective mangling for type parameter scopes around generic classes. /// If `mangled_names` is Some, only mangle names that are in the set; /// other names are left unmangled. pub(crate) fn maybe_mangle_name<'a>( - class_name: Option<&str>, - mangled_names: Option<&IndexSet>, - name: &'a str, -) -> Cow<'a, str> { + class_name: Option<&Name>, + mangled_names: Option<&IndexSet>, + name: &'a Name, +) -> Cow<'a, Name> { if let Some(set) = mangled_names && !set.contains(name) { - return name.into(); + return Cow::Borrowed(name); } mangle_name(class_name, name) } @@ -3407,15 +3413,24 @@ mod tests { #[test] fn mangle_name_leaves_private_name_in_underscore_only_class() { - assert_eq!(mangle_name(Some("_"), "__a"), "__a"); - assert_eq!(mangle_name(Some("__"), "__a"), "__a"); - assert_eq!(mangle_name(Some("___"), "__a"), "__a"); + assert_eq!(mangle_name(Some(&"_".into()), &"__a".into()), "__a".into()); + assert_eq!(mangle_name(Some(&"__".into()), &"__a".into()), "__a".into()); + assert_eq!( + mangle_name(Some(&"___".into()), &"__a".into()), + "__a".into() + ); } #[test] fn mangle_name_strips_leading_class_underscores() { - assert_eq!(mangle_name(Some("_a"), "__a"), "_a__a"); - assert_eq!(mangle_name(Some("__a"), "__a"), "_a__a"); + assert_eq!( + mangle_name(Some(&"_a".into()), &"__a".into()), + "_a__a".into() + ); + assert_eq!( + mangle_name(Some(&"__a".into()), &"__a".into()), + "_a__a".into() + ); } #[test] @@ -3444,7 +3459,7 @@ mod tests { .expect("missing lambda scope"); assert!( - lambda.lookup("__class__").is_some(), + lambda.lookup(&"__class__".into()).is_some(), "CPython symtable Name_kind treats super as a __class__ use in any function-like scope" ); } @@ -3458,7 +3473,7 @@ mod tests { .find(|table| table.typ == CompilerScope::Comprehension) .expect("missing comprehension scope"); let symbol = comprehension - .lookup("i") + .lookup(&"i".into()) .expect("missing comprehension iteration target"); assert!( @@ -3506,7 +3521,7 @@ mod tests { .expect("CPython still creates an AnnotationBlock for future annotations"); assert!( - annotation_block.lookup("T").is_some(), + annotation_block.lookup(&"T".into()).is_some(), "CPython symtable_visit_annotation still visits the annotation expression with future annotations" ); } @@ -3520,8 +3535,9 @@ mod tests { .find(|table| table.typ == CompilerScope::Annotation) .expect("missing function annotation block"); let format = annotation_block - .lookup(".format") + .lookup(&".format".into()) .expect("missing annotation .format parameter"); + assert_eq!(annotation_block.varnames, [".format"]); assert!( format .flags @@ -3536,7 +3552,7 @@ mod tests { .find(|table| table.typ == CompilerScope::TypeAlias) .expect("missing type alias scope"); let format = alias - .lookup(".format") + .lookup(&".format".into()) .expect("missing type alias .format parameter"); assert!( format @@ -3557,7 +3573,7 @@ mod tests { .find(|table| table.typ == CompilerScope::TypeVariable) .expect("missing type variable scope"); let format = type_variable - .lookup(".format") + .lookup(&".format".into()) .expect("missing type variable .format parameter"); assert!( format @@ -3567,6 +3583,41 @@ mod tests { ); } + #[test] + fn deferred_annotation_store_names_are_not_public_symbols() { + let module = scan_source("x: int\n"); + assert!(module.lookup(&"__annotate__".into()).is_none()); + assert!(module.annotation_block.is_some()); + + let module = scan_source("class C:\n y: str\n"); + let class = module + .sub_tables + .iter() + .find(|table| table.typ == CompilerScope::Class) + .expect("missing class scope"); + assert!(class.lookup(&"__annotate_func__".into()).is_none()); + assert!(class.annotation_block.is_some()); + } + + #[test] + fn generic_class_symbols_follow_cpython_insertion_order() { + let module = scan_source("class C[T]:\n q = [lambda: i for i in range(2)]\n"); + let type_params = module + .sub_tables + .iter() + .find(|table| table.typ == CompilerScope::TypeParams) + .expect("missing type parameter scope"); + let class = type_params + .sub_tables + .iter() + .find(|table| table.typ == CompilerScope::Class) + .expect("missing generic class scope"); + assert_eq!( + class.symbols.keys().collect::>(), + ["__type_params__", ".type_params", "q", "range", "i"] + ); + } + #[test] fn function_signature_annotation_block_is_sibling_like_cpython() { let table = scan_source("def f(x: T): pass\n"); diff --git a/crates/codegen/src/unparse.rs b/crates/codegen/src/unparse.rs index 679560642e5..f890edf37a0 100644 --- a/crates/codegen/src/unparse.rs +++ b/crates/codegen/src/unparse.rs @@ -1,7 +1,8 @@ +use crate::strip_python_comments; use alloc::fmt; use core::fmt::Display as _; use ruff_python_ast as ast; -use ruff_text_size::Ranged; +use ruff_text_size::{Ranged, TextSize}; use rustpython_compiler_core::SourceFile; use rustpython_literal::escape::{AsciiEscape, UnicodeEscape}; @@ -610,7 +611,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { &mut self, val: &ast::Expr, debug_text: Option<&ast::DebugText>, - conversion: ast::ConversionFlag, + mut conversion: ast::ConversionFlag, spec: Option<&ast::InterpolatedStringFormatSpec>, ) -> fmt::Result { let buffered = @@ -622,6 +623,9 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { self.p(leading)?; self.p(self.source.slice(val.range()))?; self.p(trailing)?; + if conversion == ast::ConversionFlag::None && spec.is_none() { + conversion = ast::ConversionFlag::Repr; + } } let brace = if buffered.starts_with('{') { // put a space to avoid escaping the bracket @@ -709,7 +713,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { self.p("t")?; let body = fmt::from_fn(|f| { value.iter().try_for_each(|tstring| { - Unparser::new(f, self.source).unparse_fstring_body(&tstring.elements) + Unparser::new(f, self.source).unparse_tstring_body(&tstring.elements) }) }) .to_string(); @@ -717,6 +721,102 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { .str_repr() .write(self.f) } + + fn unparse_tstring_body(&mut self, elements: &[ast::InterpolatedStringElement]) -> fmt::Result { + for element in elements { + match element { + ast::InterpolatedStringElement::Literal(literal) => { + self.unparse_fstring_str(literal)?; + } + ast::InterpolatedStringElement::Interpolation(interpolation) => { + self.unparse_tstring_interpolation(interpolation)?; + } + } + } + Ok(()) + } + + fn unparse_tstring_interpolation( + &mut self, + interpolation: &ast::InterpolatedElement, + ) -> fmt::Result { + let source_conversion = interpolation.conversion; + let mut conversion = source_conversion; + let debug_parts = interpolation.debug_text.as_ref().map(|debug_text| { + ( + strip_python_comments(debug_text.leading.as_str()), + strip_python_comments(self.source.slice(interpolation.expression.range())), + strip_python_comments(debug_text.trailing.as_str()), + ) + }); + if let Some((leading, source, trailing)) = &debug_parts { + self.p(leading)?; + self.p(source)?; + self.p(trailing)?; + if conversion == ast::ConversionFlag::None && interpolation.format_spec.is_none() { + conversion = ast::ConversionFlag::Repr; + } + } + + let expression = if let Some(ast::ConstantValue::Str(value)) = &interpolation.runtime_str { + value.to_string() + } else if let Some((leading, source, trailing)) = &debug_parts { + let mut expression = leading.clone(); + expression.push_str(source); + let equal = trailing + .rfind('=') + .expect("debug interpolation must contain '='"); + expression.push_str(&trailing[..equal]); + expression.trim_end().to_owned() + } else { + let expression_range = interpolation.expression.range(); + let after_brace = interpolation.range.start() + TextSize::new(1); + let mut expression_end = interpolation.format_spec.as_ref().map_or_else( + || interpolation.range.end() - TextSize::new(1), + |format_spec| format_spec.range.start() - TextSize::new(1), + ); + if source_conversion != ast::ConversionFlag::None { + expression_end -= TextSize::new(2); + } + if interpolation.range.start() < expression_range.start() + && interpolation.range.end() >= expression_range.end() + && after_brace <= expression_end + { + strip_python_comments( + self.source + .slice(ruff_text_size::TextRange::new(after_brace, expression_end)), + ) + .trim_end() + .to_owned() + } else { + fmt::from_fn(|f| { + Unparser::new(f, self.source) + .unparse_expr(&interpolation.expression, precedence::TEST + 1) + }) + .to_string() + } + }; + + self.p(if expression.starts_with('{') { + "{ " + } else { + "{" + })?; + self.p(&expression)?; + + if conversion != ast::ConversionFlag::None { + self.p("!")?; + let conversion_byte = [conversion as u8]; + self.p(core::str::from_utf8(&conversion_byte).unwrap())?; + } + + if let Some(format_spec) = &interpolation.format_spec { + self.p(":")?; + self.unparse_tstring_body(&format_spec.elements)?; + } + + self.p("}") + } } pub(crate) struct UnparseExpr<'a> { diff --git a/crates/common/src/format.rs b/crates/common/src/format.rs index 1c5c0a9c9de..7a5e3ac0fa1 100644 --- a/crates/common/src/format.rs +++ b/crates/common/src/format.rs @@ -829,6 +829,37 @@ impl FormatSpec { Ok(self.format_sign_and_align(&AsciiStr::new(&magnitude_str), "", FormatAlign::Right)) } + /// Whether the spec carries nothing at all, which is what `format(value, "")` + /// parses to. Written as a destructure so a new field cannot be forgotten here. + fn is_empty(&self) -> bool { + let Self { + conversion, + fill, + align, + align_specified, + sign, + no_neg_0, + alternate_form, + width, + grouping_option, + precision, + frac_grouping_option, + format_type, + } = self; + conversion.is_none() + && fill.is_none() + && align.is_none() + && !align_specified + && sign.is_none() + && !no_neg_0 + && !alternate_form + && width.is_none() + && grouping_option.is_none() + && precision.is_none() + && frac_grouping_option.is_none() + && format_type.is_none() + } + pub fn format_bool(&self, input: bool) -> Result { let x = u8::from(input); match &self.format_type { @@ -844,13 +875,11 @@ impl FormatSpec { Some(FormatType::Exponent(_) | FormatType::FixedPoint(_) | FormatType::Percentage) => { self.format_float(x as f64) } - None => { - if self.no_neg_0 { - return Err(FormatSpecError::NegativeZeroCoercionNotAllowed("integer")); - } - let first_letter = (input.to_string().as_bytes()[0] as char).to_uppercase(); - Ok(first_letter.collect::() + &input.to_string()[1..]) - } + // Only the empty spec spells the value out. Everything else without a + // presentation type, a width or an alignment included, formats `bool` + // the way it formats the `int` it is. + None if self.is_empty() => Ok(if input { "True" } else { "False" }.to_owned()), + None => self.format_int(&BigInt::from_u8(x).unwrap()), Some(format_type) => { let ch = char::from(format_type); Err(FormatSpecError::UnknownFormatCode(ch, "bool")) @@ -1083,9 +1112,19 @@ impl FormatSpec { self.validate_format(FormatType::String)?; match self.format_type { Some(FormatType::String) | None => { + // CPython rejects these four in this order: sign, z, #, then '='. + if let Some(sign) = self.sign { + return Err(FormatSpecError::StringSpecNotAllowed(match sign { + FormatSign::MinusOrSpace => "Space", + FormatSign::Plus | FormatSign::Minus => "Sign", + })); + } if self.no_neg_0 { return Err(FormatSpecError::NegativeZeroCoercionNotAllowed("string")); } + if self.alternate_form { + return Err(FormatSpecError::StringSpecNotAllowed("Alternate form (#)")); + } if self.align == Some(FormatAlign::AfterSign) && self.align_specified { return Err(FormatSpecError::StringAlignmentFlag); } @@ -1334,6 +1373,7 @@ pub enum FormatSpecError { AlignmentFlag, NegativeZeroCoercionNotAllowed(&'static str), StringAlignmentFlag, + StringSpecNotAllowed(&'static str), NotImplemented(char, &'static str), } @@ -1769,6 +1809,34 @@ mod tests { assert_eq!(format_bool("%", false), Ok("0.000000%".to_owned())); } + #[test] + fn format_bool_without_a_presentation_type() { + // The bare spec is the only one that spells the value out. + assert_eq!(format_bool("", true), Ok("True".to_owned())); + assert_eq!(format_bool("", false), Ok("False".to_owned())); + + // Anything else formats the integer, the way `int.__format__` would. + assert_eq!(format_bool("5", true), Ok(" 1".to_owned())); + assert_eq!(format_bool("<5", true), Ok("1 ".to_owned())); + assert_eq!(format_bool(">5", false), Ok(" 0".to_owned())); + assert_eq!(format_bool("^5", true), Ok(" 1 ".to_owned())); + assert_eq!(format_bool("05", true), Ok("00001".to_owned())); + assert_eq!(format_bool("+", true), Ok("+1".to_owned())); + assert_eq!(format_bool(" ", false), Ok(" 0".to_owned())); + assert_eq!(format_bool(",", true), Ok("1".to_owned())); + assert_eq!(format_bool("<", true), Ok("1".to_owned())); + + // And it inherits the integer rules, precision included. + assert_eq!( + format_bool(".2", true), + Err(FormatSpecError::PrecisionNotAllowed) + ); + assert_eq!( + format_bool("z", true), + Err(FormatSpecError::NegativeZeroCoercionNotAllowed("integer")) + ); + } + #[test] fn format_string_zero_padding_uses_left_alignment() { let spec = FormatSpec::parse("08s").unwrap(); @@ -1788,6 +1856,52 @@ mod tests { ); } + #[test] + fn format_string_rejects_sign_space_and_alternate_form() { + let value = "result".to_owned(); + let cases = [ + ("+", "Sign"), + ("-", "Sign"), + ("+8s", "Sign"), + (" ", "Space"), + (" 8s", "Space"), + ("#", "Alternate form (#)"), + ("#8s", "Alternate form (#)"), + ]; + + for (text, flag) in cases { + let spec = FormatSpec::parse(text).unwrap(); + assert_eq!( + spec.format_string(&value), + Err(FormatSpecError::StringSpecNotAllowed(flag)), + "{text}" + ); + } + } + + #[test] + fn format_string_reports_the_flag_cpython_reports_first() { + let value = "result".to_owned(); + // Sign beats z, z beats the alternate form, and the alternate form + // beats an explicit '=' alignment. + let cases = [ + ("+z#5", FormatSpecError::StringSpecNotAllowed("Sign")), + ( + "x=z#5", + FormatSpecError::NegativeZeroCoercionNotAllowed("string"), + ), + ( + "x=#5", + FormatSpecError::StringSpecNotAllowed("Alternate form (#)"), + ), + ]; + + for (text, expected) in cases { + let spec = FormatSpec::parse(text).unwrap(); + assert_eq!(spec.format_string(&value), Err(expected), "{text}"); + } + } + #[test] fn format_complex_rejects_zero_padding_before_after_sign_alignment() { for text in [ diff --git a/crates/common/src/linked_list.rs b/crates/common/src/linked_list.rs index e8d3624703d..75e0b5234f3 100644 --- a/crates/common/src/linked_list.rs +++ b/crates/common/src/linked_list.rs @@ -38,10 +38,15 @@ //! specified node is actually contained by the list. #![allow(clippy::new_without_default, clippy::missing_safety_doc)] +// It doesn't make sense to enforce `unsafe_op_in_unsafe_fn` for this module because +// +// * The intrusive linked list naturally relies on unsafe operations. +// * Excessive `unsafe {}` blocks hurt readability significantly. +#![expect(unsafe_op_in_unsafe_fn)] use core::cell::UnsafeCell; use core::fmt; -use core::marker::{PhantomData, PhantomPinned}; +use core::marker::PhantomPinned; use core::mem::ManuallyDrop; use core::ptr::{self, NonNull}; @@ -49,18 +54,15 @@ use core::ptr::{self, NonNull}; /// /// Currently, the list is not emptied on drop. It is the caller's /// responsibility to ensure the list is empty before dropping it. -pub struct LinkedList { +pub struct LinkedList { /// Linked list head - head: Option>, - + head: Option>, // /// Linked list tail // tail: Option>, - /// Node type marker. - _marker: PhantomData<*const L>, } -unsafe impl Send for LinkedList where L::Target: Send {} -unsafe impl Sync for LinkedList where L::Target: Sync {} +unsafe impl Send for LinkedList where L::Target: Send {} +unsafe impl Sync for LinkedList where L::Target: Sync {} /// Defines how a type is tracked within a linked list. /// @@ -82,13 +84,21 @@ pub unsafe trait Link { type Target; /// Convert the handle to a raw pointer without consuming the handle. - #[allow(clippy::wrong_self_convention)] fn as_raw(handle: &Self::Handle) -> NonNull; /// Convert the raw pointer to a handle unsafe fn from_raw(ptr: NonNull) -> Self::Handle; /// Return the pointers for a node + /// + /// # Safety + /// + /// The resulting pointer should have the same tag in the stacked-borrows + /// stack as the argument. In particular, the method may not create an + /// intermediate reference in the process of creating the resulting raw + /// pointer. + /// + /// The `target` pointer must be valid. unsafe fn pointers(target: NonNull) -> NonNull>; } @@ -96,6 +106,7 @@ pub unsafe trait Link { pub struct Pointers { inner: UnsafeCell>, } + /// We do not want the compiler to put the `noalias` attribute on mutable /// references to this type, so the type has been made `!Unpin` with a /// `PhantomPinned` field. @@ -103,26 +114,19 @@ pub struct Pointers { /// Additionally, we never access the `prev` or `next` fields directly, as any /// such access would implicitly involve the creation of a reference to the /// field, which we want to avoid since the fields are not `!Unpin`, and would -/// hence be given the `noalias` attribute if we were to do such an access. -/// As an alternative to accessing the fields directly, the `Pointers` type +/// hence be given the `noalias` attribute if we were to do such an access. As +/// an alternative to accessing the fields directly, the [`Pointers`] type /// provides getters and setters for the two fields, and those are implemented -/// using raw pointer casts and offsets, which is valid since the struct is -/// #[repr(C)]. +/// using `ptr`-specific methods which avoids the creation of intermediate +/// references. /// /// See this link for more information: /// -#[repr(C)] struct PointersInner { - /// The previous node in the list. null if there is no previous node. - /// - /// This field is accessed through pointer manipulation, so it is not dead code. - #[allow(dead_code)] + /// The previous node in the list. [`None`] if there is no previous node. prev: Option>, - /// The next node in the list. null if there is no previous node. - /// - /// This field is accessed through pointer manipulation, so it is not dead code. - #[allow(dead_code)] + /// The next node in the list. [`None`] if there is no previous node. next: Option>, /// This type is !Unpin due to the heuristic from: @@ -130,27 +134,21 @@ struct PointersInner { _pin: PhantomPinned, } -unsafe impl Send for PointersInner {} -unsafe impl Sync for PointersInner {} - unsafe impl Send for Pointers {} unsafe impl Sync for Pointers {} // ===== impl LinkedList ===== -impl LinkedList { +impl LinkedList { /// Creates an empty linked list. #[must_use] pub const fn new() -> Self { Self { head: None, // tail: None, - _marker: PhantomData, } } -} -impl LinkedList { /// Adds an element first in the list. pub fn push_front(&mut self, val: L::Handle) { // The value should not be dropped, it is being inserted into the list @@ -167,6 +165,7 @@ impl LinkedList { L::pointers(ptr).as_ref().get_next().is_none(), "push_front: node already has next pointer (double-insert?)" ); + L::pointers(ptr).as_mut().set_next(self.head); L::pointers(ptr).as_mut().set_prev(None); @@ -210,6 +209,7 @@ impl LinkedList { if let Some(new_head) = self.head { L::pointers(new_head).as_mut().set_prev(None); } + L::pointers(head).as_mut().set_next(None); L::pointers(head).as_mut().set_prev(None); Some(L::from_raw(head)) @@ -235,47 +235,45 @@ impl LinkedList { /// The caller **must** ensure that `node` is currently contained by /// `self` or not contained by any other list. pub unsafe fn remove(&mut self, node: NonNull) -> Option { - unsafe { - if let Some(prev) = L::pointers(node).as_ref().get_prev() { - debug_assert_eq!( - L::pointers(prev).as_ref().get_next(), - Some(node), - "linked list corruption: prev->next != node (prev={prev:p}, node={node:p})" - ); - L::pointers(prev) - .as_mut() - .set_next(L::pointers(node).as_ref().get_next()); - } else { - if self.head != Some(node) { - return None; - } - - self.head = L::pointers(node).as_ref().get_next(); + if let Some(prev) = L::pointers(node).as_ref().get_prev() { + debug_assert_eq!( + L::pointers(prev).as_ref().get_next(), + Some(node), + "linked list corruption: prev->next != node (prev={prev:p}, node={node:p})" + ); + L::pointers(prev) + .as_mut() + .set_next(L::pointers(node).as_ref().get_next()); + } else { + if self.head != Some(node) { + return None; } - if let Some(next) = L::pointers(node).as_ref().get_next() { - debug_assert_eq!( - L::pointers(next).as_ref().get_prev(), - Some(node), - "linked list corruption: next->prev != node (next={next:p}, node={node:p})" - ); - L::pointers(next) - .as_mut() - .set_prev(L::pointers(node).as_ref().get_prev()); - } else { - // // This might be the last item in the list - // if self.tail != Some(node) { - // return None; - // } - - // self.tail = L::pointers(node).as_ref().get_prev(); - } + self.head = L::pointers(node).as_ref().get_next(); + } - L::pointers(node).as_mut().set_next(None); - L::pointers(node).as_mut().set_prev(None); + if let Some(next) = L::pointers(node).as_ref().get_next() { + debug_assert_eq!( + L::pointers(next).as_ref().get_prev(), + Some(node), + "linked list corruption: next->prev != node (next={next:p}, node={node:p})" + ); + L::pointers(next) + .as_mut() + .set_prev(L::pointers(node).as_ref().get_prev()); + } else { + // // This might be the last item in the list + // if self.tail != Some(node) { + // return None; + // } - Some(L::from_raw(node)) + // self.tail = L::pointers(node).as_ref().get_prev(); } + + L::pointers(node).as_mut().set_next(None); + L::pointers(node).as_mut().set_prev(None); + + Some(L::from_raw(node)) } // pub fn last(&self) -> Option<&L::Target> { @@ -293,7 +291,7 @@ impl LinkedList { } } -impl fmt::Debug for LinkedList { +impl fmt::Debug for LinkedList { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("LinkedList") .field("head", &self.head) @@ -302,7 +300,7 @@ impl fmt::Debug for LinkedList { } } -impl Default for LinkedList { +impl Default for LinkedList { fn default() -> Self { Self::new() } @@ -310,16 +308,16 @@ impl Default for LinkedList { // ===== impl DrainFilter ===== -pub struct DrainFilter<'a, T: Link, F> { - list: &'a mut LinkedList, +pub struct DrainFilter<'a, L: Link, F> { + list: &'a mut LinkedList, filter: F, - curr: Option>, + curr: Option>, } -impl LinkedList { - pub const fn drain_filter(&mut self, filter: F) -> DrainFilter<'_, T, F> +impl LinkedList { + pub const fn drain_filter(&mut self, filter: F) -> DrainFilter<'_, L, F> where - F: FnMut(&mut T::Target) -> bool, + F: FnMut(&L::Target) -> bool, { let curr = self.head; DrainFilter { @@ -330,17 +328,17 @@ impl LinkedList { } } -impl Iterator for DrainFilter<'_, T, F> +impl Iterator for DrainFilter<'_, L, F> where - T: Link, - F: FnMut(&mut T::Target) -> bool, + L: Link, + F: FnMut(&L::Target) -> bool, { - type Item = T::Handle; + type Item = L::Handle; fn next(&mut self) -> Option { while let Some(curr) = self.curr { // safety: the pointer references data contained by the list - self.curr = unsafe { T::pointers(curr).as_ref() }.get_next(); + self.curr = unsafe { L::pointers(curr).as_ref() }.get_next(); // safety: the value is still owned by the linked list. if (self.filter)(unsafe { &mut *curr.as_ptr() }) { @@ -368,38 +366,26 @@ impl Pointers { } pub const fn get_prev(&self) -> Option> { - // SAFETY: prev is the first field in PointersInner, which is #[repr(C)]. - unsafe { - let inner = self.inner.get(); - let prev = inner as *const Option>; - ptr::read(prev) - } + // SAFETY: Field is accessed immutably through a reference. + unsafe { ptr::addr_of!((*self.inner.get()).prev).read() } } + pub const fn get_next(&self) -> Option> { - // SAFETY: next is the second field in PointersInner, which is #[repr(C)]. - unsafe { - let inner = self.inner.get(); - let prev = inner as *const Option>; - let next = prev.add(1); - ptr::read(next) - } + // SAFETY: Field is accessed immutably through a reference. + unsafe { ptr::addr_of!((*self.inner.get()).next).read() } } pub const fn set_prev(&mut self, value: Option>) { - // SAFETY: prev is the first field in PointersInner, which is #[repr(C)]. + // SAFETY: Field is accessed mutably through a mutable reference. unsafe { - let inner = self.inner.get(); - let prev = inner as *mut Option>; - ptr::write(prev, value); + ptr::addr_of_mut!((*self.inner.get()).prev).write(value); } } + pub const fn set_next(&mut self, value: Option>) { - // SAFETY: next is the second field in PointersInner, which is #[repr(C)]. + // SAFETY: Field is accessed mutably through a mutable reference. unsafe { - let inner = self.inner.get(); - let prev = inner as *mut Option>; - let next = prev.add(1); - ptr::write(next, value); + ptr::addr_of_mut!((*self.inner.get()).next).write(value); } } } diff --git a/crates/common/src/refcount.rs b/crates/common/src/refcount.rs index 4d52e1382e6..6cfe6470ea1 100644 --- a/crates/common/src/refcount.rs +++ b/crates/common/src/refcount.rs @@ -1,8 +1,13 @@ use crate::atomic::{Ordering, PyAtomic, Radium}; // State layout (usize): -// [1 bit: destructed] [1 bit: published] [1 bit: leaked] [N bits: weak_count] [M bits: strong_count] -// 64-bit: N=30, M=31. 32-bit: N=14, M=15. +// [1 bit: destructed] [1 bit: published] [1 bit: leaked] [M bits: strong_count] +// 64-bit: M=61. 32-bit: M=29. +// +// Weak references live in the object's `WeakRefList`, not in this word, so the +// strong count takes every bit the flags leave. A 32-bit target reaches its +// ceiling at 536 870 911 references rather than the 32 767 that half the word +// would allow — a number two ordinary module imports pass on `wasm32`. const FLAG_BITS: u32 = 3; const DESTRUCTED: usize = 1 << (usize::BITS - 1); /// Object was published to a lock-free cache; memory reclamation is @@ -10,12 +15,9 @@ const DESTRUCTED: usize = 1 << (usize::BITS - 1); /// freed memory. Sticky once set. const PUBLISHED: usize = 1 << (usize::BITS - 2); const LEAKED: usize = 1 << (usize::BITS - 3); -const TOTAL_COUNT_WIDTH: u32 = usize::BITS - FLAG_BITS; -const WEAK_WIDTH: u32 = TOTAL_COUNT_WIDTH / 2; -const STRONG_WIDTH: u32 = TOTAL_COUNT_WIDTH - WEAK_WIDTH; +const STRONG_WIDTH: u32 = usize::BITS - FLAG_BITS; const STRONG: usize = (1 << STRONG_WIDTH) - 1; const COUNT: usize = 1; -const WEAK_COUNT: usize = 1 << STRONG_WIDTH; #[inline(never)] #[cold] @@ -48,8 +50,8 @@ impl State { } #[inline] - fn strong(self) -> u32 { - ((self.inner & STRONG) / COUNT) as u32 + fn strong(self) -> usize { + (self.inner & STRONG) / COUNT } #[inline] @@ -76,8 +78,8 @@ impl State { /// Reference count using state layout with LEAKED support. /// /// State layout (usize): -/// 64-bit: [1 bit: destructed] [1 bit: published] [1 bit: leaked] [30 bits: weak_count] [31 bits: strong_count] -/// 32-bit: [1 bit: destructed] [1 bit: published] [1 bit: leaked] [14 bits: weak_count] [15 bits: strong_count] +/// 64-bit: [1 bit: destructed] [1 bit: published] [1 bit: leaked] [61 bits: strong_count] +/// 32-bit: [1 bit: destructed] [1 bit: published] [1 bit: leaked] [29 bits: strong_count] pub struct RefCount { state: PyAtomic, } @@ -92,23 +94,22 @@ impl RefCount { /// Create a new RefCount with strong count = 1 #[must_use] pub fn new() -> Self { - // Initial state: strong=1, weak=1 (implicit weak for strong refs) Self { - state: Radium::new(COUNT + WEAK_COUNT), + state: Radium::new(COUNT), } } /// Get current strong count #[inline] pub fn get(&self) -> usize { - State::from_raw(self.state.load(Ordering::Relaxed)).strong() as usize + State::from_raw(self.state.load(Ordering::Relaxed)).strong() } /// Increment strong count #[inline] pub fn inc(&self) { let val = State::from_raw(self.state.fetch_add(COUNT, Ordering::Relaxed)); - if val.destructed() || (val.strong() as usize) > STRONG - 1 { + if val.destructed() || val.strong() > STRONG - 1 { refcount_overflow(); } if val.strong() == 0 { @@ -121,7 +122,7 @@ impl RefCount { pub fn inc_by(&self, n: usize) { debug_assert!(n <= STRONG); let val = State::from_raw(self.state.fetch_add(n * COUNT, Ordering::Relaxed)); - if val.destructed() || (val.strong() as usize) > STRONG - n { + if val.destructed() || val.strong() > STRONG - n { refcount_overflow(); } } @@ -135,7 +136,7 @@ impl RefCount { if old.destructed() || old.strong() == 0 { return false; } - if (old.strong() as usize) >= STRONG { + if old.strong() >= STRONG { refcount_overflow(); } let new_state = old.add_strong(1); @@ -299,6 +300,57 @@ pub fn flush_deferred_drops() { mod tests { use super::*; + /// The strong count reaches far past a 16-bit ceiling on every target. + /// + /// The count shares its word with the flag bits, so its width follows the + /// pointer width. A 32-bit target is the one this guards: a second counter + /// packed beside the strong count once left it 15 bits, and `wasm32` + /// aborted at 32 767 references — a total two ordinary module imports + /// pass. The check is a no-op on a 64-bit host, where 31 bits already + /// covered this; run the crate's tests against a 32-bit target to exercise + /// it. + #[test] + fn strong_count_reaches_past_a_16_bit_ceiling() { + const REFERENCES: usize = 1 << 20; + + let rc = RefCount::new(); + rc.inc_by(REFERENCES); + assert_eq!(rc.get(), REFERENCES + 1); + } + + /// `inc` and `dec` reach the same ceiling as `inc_by`. + /// + /// The aborts reported against this layout came one reference at a time + /// through `inc`, whose overflow check is written separately from + /// `inc_by`'s, and the count has to come back down through `dec` without + /// reporting the object collectable before the last reference goes. + #[test] + fn inc_and_dec_reach_past_a_16_bit_ceiling() { + const REFERENCES: usize = 1 << 20; + + let rc = RefCount::new(); // strong = 1 + for _ in 1..REFERENCES { + rc.inc(); + } + assert_eq!(rc.get(), REFERENCES); + for _ in 1..REFERENCES { + assert!(!rc.dec()); + } + assert_eq!(rc.get(), 1); + assert!(rc.dec()); + } + + /// A fresh count holds exactly one strong reference and no stray bits. + /// + /// `get` masks the flags away, so a spare field left in the word would not + /// show up there. Reading the raw state keeps the layout honest. + #[test] + fn a_new_refcount_holds_one_strong_reference_and_nothing_else() { + let rc = RefCount::new(); + assert_eq!(rc.get(), 1); + assert_eq!(rc.state.load(Ordering::Relaxed), COUNT); + } + #[test] fn published_bit_survives_refcount_traffic() { let rc = RefCount::new(); // strong = 1 diff --git a/crates/common/src/str.rs b/crates/common/src/str.rs index c649c057de6..3e972dc7bbe 100644 --- a/crates/common/src/str.rs +++ b/crates/common/src/str.rs @@ -743,6 +743,15 @@ pub mod levenshtein { /// Replace all tabs in a string with spaces, using the given tab size. #[must_use] pub fn expandtabs(input: &str, tab_size: usize) -> String { + // A tab size of zero, which is also where a negative one lands, leaves no + // column for a tab to advance to: the tabs come out and nothing else moves. + // Going through the arithmetic anyway subtracts the current column from a + // tab stop of zero and underflows on the first tab, so the width asked for + // next is `usize::MAX`. The bytes version of this already returns here. + if tab_size == 0 { + return input.chars().filter(|ch| *ch != '\t').collect(); + } + let tab_stop = tab_size; let mut expanded_str = String::with_capacity(input.len()); let mut tab_size = tab_stop; @@ -905,4 +914,28 @@ mod tests { let s = "0😀😃😄😁😆😅😂🤣9"; assert_eq!(get_chars(s, 3..7), "😄😁😆😅"); } + + #[test] + fn expandtabs_with_zero_tab_size_drops_tabs() { + // A tab that follows a character used to subtract that column from a + // tab stop of zero, so the width of the run of spaces came out as + // `usize::MAX` and the allocation aborted the process. + assert_eq!(expandtabs("a\tb", 0), "ab"); + assert_eq!(expandtabs("ab\tcd\tef", 0), "abcdef"); + assert_eq!(expandtabs("a\nb\tc", 0), "a\nbc"); + assert_eq!(expandtabs("á\tb", 0), "áb"); + assert_eq!(expandtabs("\ta", 0), "a"); + assert_eq!(expandtabs("\t", 0), ""); + assert_eq!(expandtabs("", 0), ""); + assert_eq!(expandtabs("no tabs", 0), "no tabs"); + } + + #[test] + fn expandtabs_with_a_real_tab_size_is_unchanged() { + assert_eq!(expandtabs("a\tb", 8), "a b"); + assert_eq!(expandtabs("a\tb", 1), "a b"); + assert_eq!(expandtabs("abcd\te", 4), "abcd e"); + assert_eq!(expandtabs("a\nb\tc", 4), "a\nb c"); + assert_eq!(expandtabs("\ta", 4), " a"); + } } diff --git a/crates/compiler-core/src/bytecode.rs b/crates/compiler-core/src/bytecode.rs index ba1639170a7..f06587349b5 100644 --- a/crates/compiler-core/src/bytecode.rs +++ b/crates/compiler-core/src/bytecode.rs @@ -11,7 +11,7 @@ use bitflags::bitflags; use core::{ cell::UnsafeCell, hash, mem, - ops::{Deref, Index, IndexMut}, + ops::{Deref, DerefMut, Index, IndexMut}, sync::atomic::{AtomicU8, AtomicU16, AtomicUsize, Ordering}, }; use itertools::Itertools; @@ -383,6 +383,12 @@ impl Deref for Constants { } } +impl DerefMut for Constants { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + impl Index for Constants { type Output = C; @@ -391,6 +397,12 @@ impl Index for Constants { } } +impl IndexMut for Constants { + fn index_mut(&mut self, consti: oparg::ConstIdx) -> &mut Self::Output { + &mut self.0[consti.as_usize()] + } +} + impl FromIterator for Constants { fn from_iter>(iter: T) -> Self { Self(iter.into_iter().collect()) @@ -483,6 +495,19 @@ bitflags! { } } +impl CodeFlags { + /// The `__future__` flags that `compile()` accepts and that a compiled code + /// object inherits from its caller. Mirrors `PyCF_MASK`. + pub const FUTURE_MASK: Self = Self::FUTURE_DIVISION + .union(Self::FUTURE_ABSOLUTE_IMPORT) + .union(Self::FUTURE_WITH_STATEMENT) + .union(Self::FUTURE_PRINT_FUNCTION) + .union(Self::FUTURE_UNICODE_LITERALS) + .union(Self::FUTURE_BARRY_AS_BDFL) + .union(Self::FUTURE_GENERATOR_STOP) + .union(Self::FUTURE_ANNOTATIONS); +} + #[repr(C)] #[derive(Copy, Clone, Debug)] pub struct CodeUnit { diff --git a/crates/compiler/src/lib.rs b/crates/compiler/src/lib.rs index 7562e8939b9..6d7b82d668b 100644 --- a/crates/compiler/src/lib.rs +++ b/crates/compiler/src/lib.rs @@ -1,3 +1,6 @@ +extern crate alloc; + +use alloc::borrow::Cow; pub use ruff_python_ast::token::{TokenKind, Tokens}; use ruff_python_parser::ParseErrorType; use ruff_source_file::{PositionEncoding, SourceFile, SourceFileBuilder, SourceLocation}; @@ -110,7 +113,9 @@ impl CompileError { #[must_use] pub fn python_end_location(&self) -> Option<(usize, usize)> { match self { - Self::Codegen(_) => None, + Self::Codegen(codegen_error) => codegen_error + .end_location + .map(|end| (end.line.get(), end.character_offset.get())), Self::Parse(parse_error) => Some(( parse_error.end_location.line.get(), parse_error.end_location.character_offset.get(), @@ -127,17 +132,19 @@ impl CompileError { } } +// A syntax error the parser reports counts its columns in characters rather +// than in the bytes the range is measured in. An offset that lands inside a +// character walks back to where that character starts, the way decoding the +// line up to a truncated offset would. fn source_location(source_file: &SourceFile, offset: TextSize) -> SourceLocation { + let text = source_file.source_text(); + let mut index = offset.to_usize().min(text.len()); + while !text.is_char_boundary(index) { + index -= 1; + } source_file .to_source_code() - .source_location(offset, PositionEncoding::Utf8) -} - -// Call only with UTF-8 character boundaries for Python-facing offsets. -fn source_location_in_code_points(source_file: &SourceFile, offset: TextSize) -> SourceLocation { - source_file - .to_source_code() - .source_location(offset, PositionEncoding::Utf32) + .source_location(TextSize::new(index as u32), PositionEncoding::Utf32) } fn source_locations( @@ -145,10 +152,9 @@ fn source_locations( start: TextSize, end: TextSize, ) -> (SourceLocation, SourceLocation) { - let source_code = source_file.to_source_code(); ( - source_code.source_location(start, PositionEncoding::Utf8), - source_code.source_location(end, PositionEncoding::Utf8), + source_location(source_file, start), + source_location(source_file, end), ) } @@ -186,21 +192,6 @@ impl NormalizedParseDiagnostic { ) } - fn other_in_code_points( - source_file: &SourceFile, - message: String, - start: usize, - end: usize, - ) -> Self { - let start = TextSize::new(start as u32); - let end = TextSize::new(end as u32); - Self::new( - parser::ParseErrorType::OtherError(message), - source_location_in_code_points(source_file, start), - source_location_in_code_points(source_file, end), - ) - } - const fn with_unclosed_bracket(mut self, is_unclosed_bracket: bool) -> Self { self.is_unclosed_bracket = is_unclosed_bracket; self @@ -227,12 +218,12 @@ fn cpython_parse_diagnostic_override( }; } - if let Some((message, offset)) = invalid_number_literal_error(source_text) { + if let Some((message, start, end)) = invalid_number_literal_error(source_text) { return Some(NormalizedParseDiagnostic::other( source_file, message, - offset, - offset, + start, + end, )); } source_error!(invalid_legacy_statement_error(source_text)); @@ -271,8 +262,7 @@ fn cpython_parse_diagnostic_override( } if let Some((message, start, end)) = unterminated_string_error(source_text) { - // The scanner reports quote positions, which are UTF-8 character boundaries. - return Some(NormalizedParseDiagnostic::other_in_code_points( + return Some(NormalizedParseDiagnostic::other( source_file, message, start, @@ -362,6 +352,19 @@ fn cpython_parse_diagnostic_override( )); } + // CPython's PEG parser collapses a bare "expected an expression" failure + // into the generic "invalid syntax" message. rustpython-vm's `vm_new.rs` + // does this same collapse for its own callers; rustpython-compiler has no + // vm dependency, so mirror it here. + if matches!(&error.error, parser::ParseErrorType::ExpectedExpression) { + let (loc, end_loc) = adjusted_error_locations(source_file, error.location); + return Some(NormalizedParseDiagnostic::new( + parser::ParseErrorType::OtherError("invalid syntax".into()), + loc, + end_loc, + )); + } + None } @@ -434,6 +437,10 @@ fn adjusted_error_locations( if locations.1.character_offset.get() == 1 && locations.1.line > locations.0.line { locations.1 = source_location(source_file, range.end() - TextSize::from(1)); locations.1.character_offset = locations.1.character_offset.saturating_add(1); + } else if range.is_empty() { + // The parser blames a token, and the narrowest token still covers a + // character, so an error reported between two of them spans one. + locations.1.character_offset = locations.1.character_offset.saturating_add(1); } locations } @@ -618,7 +625,9 @@ fn invalid_decimal_literal_error(bytes: &[u8], start: usize) -> Option<(String, None }; if !bytes.get(index).is_some_and(|byte| byte.is_ascii_digit()) { - return Some((message, sign.unwrap_or(exponent))); + // Without a sign the exponent letter is put back, so the position + // is the digit before it rather than the letter. + return Some((message, sign.unwrap_or_else(|| exponent.saturating_sub(1)))); } if let Some(offset) = decimal_tail_error(bytes, index) { return Some((message, offset)); @@ -627,7 +636,10 @@ fn invalid_decimal_literal_error(bytes: &[u8], start: usize) -> Option<(String, None } -fn leading_zero_decimal_literal_error(bytes: &[u8], start: usize) -> Option<(String, usize)> { +fn leading_zero_decimal_literal_error( + bytes: &[u8], + start: usize, +) -> Option<(String, usize, usize)> { if bytes.get(start) != Some(&b'0') { return None; } @@ -654,37 +666,35 @@ fn leading_zero_decimal_literal_error(bytes: &[u8], start: usize) -> Option<(Str return Some(( "leading zeros in decimal integer literals are not permitted; use an 0o prefix for octal integers".to_owned(), start, + index, )); } } None } -fn invalid_numeric_literal_error(bytes: &[u8], start: usize) -> Option<(String, usize)> { +fn invalid_numeric_literal_error(bytes: &[u8], start: usize) -> Option<(String, usize, usize)> { if bytes.get(start) == Some(&b'0') { - match bytes.get(start + 1) { - Some(b'x' | b'X') => { - return invalid_radix_literal_error(bytes, start, "hexadecimal", |byte| { - byte.is_ascii_hexdigit() - }); - } - Some(b'o' | b'O') => { - return invalid_radix_literal_error(bytes, start, "octal", |byte| { - matches!(byte, b'0'..=b'7') - }); - } - Some(b'b' | b'B') => { - return invalid_radix_literal_error(bytes, start, "binary", |byte| { - matches!(byte, b'0' | b'1') - }); - } - _ => {} + let radix = match bytes.get(start + 1) { + Some(b'x' | b'X') => invalid_radix_literal_error(bytes, start, "hexadecimal", |byte| { + byte.is_ascii_hexdigit() + }), + Some(b'o' | b'O') => invalid_radix_literal_error(bytes, start, "octal", |byte| { + matches!(byte, b'0'..=b'7') + }), + Some(b'b' | b'B') => invalid_radix_literal_error(bytes, start, "binary", |byte| { + matches!(byte, b'0' | b'1') + }), + _ => None, + }; + if let Some(radix) = radix { + return Some(point_span(radix)); } if let Some(err) = leading_zero_decimal_literal_error(bytes, start) { return Some(err); } } - invalid_decimal_literal_error(bytes, start) + invalid_decimal_literal_error(bytes, start).map(point_span) } fn consume_exponent(bytes: &[u8], index: usize) -> usize { @@ -776,7 +786,12 @@ fn skip_quoted_string(bytes: &[u8], mut index: usize) -> usize { index } -fn invalid_number_literal_error(source: &str) -> Option<(String, usize)> { +// An error the tokenizer reports at a single position spans nothing. +fn point_span((message, offset): (String, usize)) -> (String, usize, usize) { + (message, offset, offset) +} + +fn invalid_number_literal_error(source: &str) -> Option<(String, usize, usize)> { let bytes = source.as_bytes(); let mut index = 0; while index < bytes.len() { @@ -807,14 +822,15 @@ fn invalid_number_literal_error(source: &str) -> Option<(String, usize)> { }; if end > index { if source[end..].starts_with('⁄') { - return Some(("invalid character '⁄' (U+2044)".to_owned(), end)); + return Some(("invalid character '⁄' (U+2044)".to_owned(), end, end)); } if bytes .get(end) .is_some_and(|byte| *byte < 128 && is_ascii_identifier_char(*byte)) && !numeric_keyword_suffix(&bytes[end..]) { - return Some((format!("invalid {kind} literal"), end.saturating_sub(1))); + let offset = end.saturating_sub(1); + return Some((format!("invalid {kind} literal"), offset, offset)); } } index = end.max(index + 1); @@ -3815,7 +3831,7 @@ fn unterminated_string_error(source: &str) -> Option<(String, usize, usize)> { return Some(( unterminated_string_message(line, false, has_escaped_quote), start, - start + 1, + start, )); } line += 1; @@ -3853,7 +3869,7 @@ fn unterminated_string_error(source: &str) -> Option<(String, usize, usize)> { has_escaped_quote, ), start, - start + 1, + start, )); } } @@ -4946,11 +4962,31 @@ fn invalid_unparenthesized_yield_after_comma_error(source: &str) -> Option<(Stri None } +/// The byte-order mark is only stripped while decoding source bytes, so one +/// that survives into the text is just a non-printable character. The tokenizer +/// rejects it everywhere except at the very start of the text, which is where +/// this covers. +#[doc(hidden)] +#[must_use] +pub fn leading_byte_order_mark_error(source_file: &SourceFile) -> Option { + source_file.source_text().starts_with('\u{feff}').then(|| { + CompileError::from_source_error( + source_file, + "invalid non-printable character U+FEFF".to_owned(), + 0, + 0, + ) + }) +} + fn post_parse_source_error( source_file: &SourceFile, tokens: &Tokens, opts: &CompileOpts, ) -> Option { + if let Some(error) = leading_byte_order_mark_error(source_file) { + return Some(error); + } if let Some((message, start, end)) = too_many_nested_parentheses_error(source_file.source_text()) { @@ -4990,6 +5026,119 @@ fn is_compound_stmt(stmt: &ast::Stmt) -> bool { ) } +/// Syntax the reference grammar has no rule for, but that this parser accepts. +/// +/// A bare generator expression is one: `f(x for x in y)` is the `primary +/// genexp` alternative of a call, and a class header only takes `arguments`, +/// which has no such alternative. A format spec nested more than two deep is +/// the other; the tokenizer runs out of nesting levels for it. +#[doc(hidden)] +#[must_use] +pub fn unsupported_grammar_error(ast: &ast::Mod, source_file: &SourceFile) -> Option { + use ast::visitor::Visitor; + + /// The deepest chain of format specs one string literal may hold. + const MAX_FORMAT_SPEC_DEPTH: usize = 2; + + struct Checker<'a> { + source_file: &'a SourceFile, + error: Option, + } + + impl Checker<'_> { + fn fail(&mut self, message: &str, range: ruff_text_size::TextRange) { + self.error = Some(CompileError::from_source_error( + self.source_file, + message.to_owned(), + range.start().to_usize(), + range.end().to_usize(), + )); + } + + fn check_format_specs( + &mut self, + kind: &str, + elements: &ast::InterpolatedStringElements, + depth: usize, + ) { + for element in elements.interpolations() { + let Some(format_spec) = &element.format_spec else { + continue; + }; + if depth == MAX_FORMAT_SPEC_DEPTH { + self.fail( + &alloc::format!("{kind}: expressions nested too deeply"), + format_spec.range, + ); + return; + } + self.check_format_specs(kind, &format_spec.elements, depth + 1); + if self.error.is_some() { + return; + } + } + } + } + + impl<'a> Visitor<'a> for Checker<'_> { + fn visit_stmt(&mut self, stmt: &'a ast::Stmt) { + if self.error.is_some() { + return; + } + if let ast::Stmt::ClassDef(class_def) = stmt + && let Some(arguments) = &class_def.arguments + && let [ast::Expr::Generator(generator)] = &arguments.args[..] + && !generator.parenthesized + { + let range = generator + .generators + .first() + .map_or(generator.range, |comprehension| comprehension.range); + self.fail("invalid syntax", range); + return; + } + ast::visitor::walk_stmt(self, stmt); + } + + fn visit_expr(&mut self, expr: &'a ast::Expr) { + if self.error.is_some() { + return; + } + // Each literal counts its own nesting: one written inside a format + // spec starts over. + match expr { + ast::Expr::FString(fstring) => { + for part in &fstring.value { + if let ast::FStringPart::FString(part) = part { + self.check_format_specs("f-string", &part.elements, 0); + } + } + } + ast::Expr::TString(tstring) => { + for part in &tstring.value { + self.check_format_specs("t-string", &part.elements, 0); + } + } + _ => {} + } + if self.error.is_some() { + return; + } + ast::visitor::walk_expr(self, expr); + } + } + + let mut checker = Checker { + source_file, + error: None, + }; + match ast { + ast::Mod::Module(module) => checker.visit_body(&module.body), + ast::Mod::Expression(expression) => checker.visit_expr(&expression.body), + } + checker.error +} + fn single_mode_body_error(body: &[ast::Stmt], source_file: &SourceFile) -> Option { let first = body.first()?; let source_code = source_file.to_source_code(); @@ -5222,8 +5371,18 @@ fn _compile_with_syntax_warning_handler<'a>( Mode::Single | Mode::BlockExpr => parser::Mode::Module, }; let parser_options = parser::ParseOptions::from(parser_mode); - let parsed = parser::parse(source_file.source_text(), parser_options) - .map_err(|err| CompileError::from_ruff_parse_error(err, &source_file, mode))?; + let barry_source = prepare_barry_as_flufl_source( + source_file.source_text(), + parser_options.clone(), + opts.future_features + .contains(core::bytecode::CodeFlags::FUTURE_BARRY_AS_BDFL), + ); + let parsed = parser::parse(barry_source.source(), parser_options); + if let Some(error) = barry_source.diagnostic(parsed.as_ref().err(), &source_file) { + return Err(error); + } + let parsed = + parsed.map_err(|err| CompileError::from_ruff_parse_error(err, &source_file, mode))?; if opts.dont_imply_dedent && matches!(mode, Mode::Single) && let Some(error) = dont_imply_dedent_source_error(&source_file) @@ -5234,6 +5393,9 @@ fn _compile_with_syntax_warning_handler<'a>( return Err(error); } let ast = parsed.into_syntax(); + if let Some(error) = unsupported_grammar_error(&ast, &source_file) { + return Err(error); + } let single_mode_error = matches!(mode, Mode::Single) .then(|| single_mode_source_error(&ast, &source_file)) .flatten(); @@ -5251,6 +5413,186 @@ fn _compile_with_syntax_warning_handler<'a>( Ok(code) } +#[doc(hidden)] +pub struct BarrySource<'a> { + source: Cow<'a, str>, + not_equal: Option, + legacy_not_equal: Vec, +} + +impl BarrySource<'_> { + #[must_use] + pub fn source(&self) -> &str { + &self.source + } + + #[must_use] + pub fn not_equal_before( + &self, + parse_error: Option<&parser::ParseError>, + ) -> Option { + self.not_equal.filter(|range| { + parse_error.is_none_or(|error| { + let diagnostic_start = if matches!( + &error.error, + parser::ParseErrorType::Lexical(parser::LexicalErrorType::Eof) + ) { + find_unclosed_bracket(&self.source).map_or_else( + || error.location.start(), + |(_, offset)| TextSize::new(offset as u32), + ) + } else { + error.location.start() + }; + range.start() <= diagnostic_start + }) + }) + } + + /// The obsolete `<>` operator the parse error points at, if any. In Barry + /// mode the operator was rewritten to `!=`, so the error lands on its + /// start; outside Barry mode ruff lexes `<` and then an unexpected `>`, so + /// the error lands one character in. Either way the whole operator is one + /// token to the tokenizer, so report it as one. + #[must_use] + pub fn invalid_legacy_operator( + &self, + parse_error: &parser::ParseError, + ) -> Option { + let location = parse_error.location.start(); + self.legacy_not_equal + .iter() + .copied() + .find(|range| range.contains(location) || range.start() == location) + .filter(|range| self.outranks_unclosed_bracket(*range)) + } + + /// Whether `range` outranks an unclosed bracket. The bracket is reported + /// at itself, so it wins over anything that starts after it. + fn outranks_unclosed_bracket(&self, range: ruff_text_size::TextRange) -> bool { + find_unclosed_bracket(&self.source) + .is_none_or(|(_, offset)| range.start() <= TextSize::new(offset as u32)) + } + + /// The diagnostic for this source, if any: an obsolete `<>` the parse + /// error points at, or -- in Barry mode only -- the first `!=`. A `<>` + /// takes precedence over a `!=` reported later in the source. + #[must_use] + pub fn diagnostic( + &self, + parse_error: Option<&parser::ParseError>, + source_file: &SourceFile, + ) -> Option { + if let Some(range) = parse_error.and_then(|error| self.invalid_legacy_operator(error)) { + return Some(barry_as_flufl_invalid_legacy_operator_error( + source_file, + range, + )); + } + self.not_equal_before(parse_error) + .map(|range| barry_as_flufl_not_equal_error(source_file, range)) + } +} + +#[doc(hidden)] +#[must_use] +pub fn barry_as_flufl_not_equal_error( + source_file: &SourceFile, + range: ruff_text_size::TextRange, +) -> CompileError { + CompileError::from_source_error( + source_file, + "with Barry as BDFL, use '<>' instead of '!='".to_owned(), + range.start().to_usize(), + range.end().to_usize(), + ) +} + +#[doc(hidden)] +#[must_use] +pub fn barry_as_flufl_invalid_legacy_operator_error( + source_file: &SourceFile, + range: ruff_text_size::TextRange, +) -> CompileError { + CompileError::from_source_error( + source_file, + "invalid syntax".to_owned(), + range.start().to_usize(), + range.end().to_usize(), + ) +} + +/// Every `<>` in `source`, located by plain text search. Only used where the +/// operator is not rewritten, so an occurrence inside a string or a comment +/// costs nothing: it can never coincide with the location of a parse error. +fn textual_legacy_not_equal(source: &str) -> Vec { + source + .match_indices("<>") + .map(|(offset, matched)| { + ruff_text_size::TextRange::at( + TextSize::new(offset as u32), + TextSize::new(matched.len() as u32), + ) + }) + .collect() +} + +#[doc(hidden)] +pub fn prepare_barry_as_flufl_source( + source: &str, + parser_options: parser::ParseOptions, + inherited: bool, +) -> BarrySource<'_> { + let scanned = (inherited || source.contains("barry_as_FLUFL")) + .then(|| parser::parse_unchecked(source, parser_options)); + let enabled = scanned.as_ref().is_some_and(|scanned| { + inherited + || codegen::preprocess::future_features(scanned.syntax()) + .contains(core::bytecode::CodeFlags::FUTURE_BARRY_AS_BDFL) + }); + let Some(scanned) = scanned.filter(|_| enabled) else { + return BarrySource { + source: Cow::Borrowed(source), + not_equal: None, + legacy_not_equal: textual_legacy_not_equal(source), + }; + }; + + let not_equal = scanned + .tokens() + .iter() + .find(|token| token.kind() == TokenKind::NotEqual) + .map(Ranged::range); + let replacements = scanned + .tokens() + .windows(2) + .filter_map(|tokens| { + let [less, greater] = tokens else { + return None; + }; + (less.kind() == TokenKind::Less + && greater.kind() == TokenKind::Greater + && less.end() == greater.start()) + .then(|| ruff_text_size::TextRange::new(less.start(), greater.end())) + }) + .collect::>(); + + let source = if replacements.is_empty() { + Cow::Borrowed(source) + } else { + let mut rewritten = source.to_owned(); + for range in replacements.iter().rev() { + rewritten.replace_range(range.start().to_usize()..range.end().to_usize(), "!="); + } + Cow::Owned(rewritten) + }; + BarrySource { + source, + not_equal, + legacy_not_equal: replacements, + } +} + pub fn compile_with_syntax_warning_handler<'a>( source: &str, mode: Mode, @@ -5275,42 +5617,102 @@ pub fn compile_symtable( _compile_symtable(source_file, mode) } +/// Bring a module into the shape the symbol table is built from. +fn symtable_preprocess_module( + module: &mut ast::ModModule, + source_file: &SourceFile, +) -> Result<(), CompileError> { + let future_features = codegen::preprocess::checked_future_features_in_body(&module.body) + .map_err(|error| future_feature_error(error, source_file))?; + let future_annotations = + future_features.contains(core::bytecode::CodeFlags::FUTURE_ANNOTATIONS); + // Constant folding is left out; the symbol table is built from the parsed + // program as written. + codegen::preprocess::preprocess_statements(&mut module.body, 0, future_annotations, true); + Ok(()) +} + +fn future_feature_error( + error: codegen::preprocess::FutureFeatureError, + source_file: &SourceFile, +) -> CompileError { + let source_code = source_file.to_source_code(); + let location = source_code.source_location(error.range.start(), PositionEncoding::Utf8); + let end_location = source_code.source_location(error.range.end(), PositionEncoding::Utf8); + let error = match error.kind { + codegen::preprocess::FutureFeatureErrorKind::InvalidFeature(feature) => { + codegen::error::CodegenErrorType::InvalidFutureFeature(feature) + } + codegen::preprocess::FutureFeatureErrorKind::InvalidBraces => { + codegen::error::CodegenErrorType::InvalidFutureBraces + } + }; + codegen::error::CodegenError { + location: Some(location), + end_location: Some(end_location), + error, + source_path: source_file.name().to_owned(), + } + .into() +} + pub fn _compile_symtable( source_file: SourceFile, mode: Mode, ) -> Result { + let parser_mode = match mode { + Mode::Exec | Mode::Single | Mode::BlockExpr => parser::Mode::Module, + Mode::Eval => parser::Mode::Expression, + }; + let parser_options = parser::ParseOptions::from(parser_mode); + let barry_source = + prepare_barry_as_flufl_source(source_file.source_text(), parser_options.clone(), false); let res = match mode { Mode::Exec | Mode::Single | Mode::BlockExpr => { - let ast = ruff_python_parser::parse_module(source_file.source_text()) - .map_err(|e| CompileError::from_ruff_parse_error(e, &source_file, mode))?; + let parsed = ruff_python_parser::parse(barry_source.source(), parser_options); + if let Some(error) = barry_source.diagnostic(parsed.as_ref().err(), &source_file) { + return Err(error); + } + let ast = + parsed.map_err(|e| CompileError::from_ruff_parse_error(e, &source_file, mode))?; if let Some(error) = post_parse_source_error(&source_file, ast.tokens(), &CompileOpts::default()) { return Err(error); } let ast = ast.into_syntax(); + if let Some(error) = unsupported_grammar_error(&ast, &source_file) { + return Err(error); + } + let ast = ast.expect_module(); if matches!(mode, Mode::Single) && let Some(error) = single_mode_body_error(&ast.body, &source_file) { return Err(error); } + let mut ast = ast; + symtable_preprocess_module(&mut ast, &source_file)?; symboltable::SymbolTable::scan_program(&ast, source_file.clone()) } Mode::Eval => { - let ast = ruff_python_parser::parse( - source_file.source_text(), - parser::Mode::Expression.into(), - ) - .map_err(|e| CompileError::from_ruff_parse_error(e, &source_file, mode))?; + let parsed = ruff_python_parser::parse(barry_source.source(), parser_options); + if let Some(error) = barry_source.diagnostic(parsed.as_ref().err(), &source_file) { + return Err(error); + } + let ast = + parsed.map_err(|e| CompileError::from_ruff_parse_error(e, &source_file, mode))?; if let Some(error) = post_parse_source_error(&source_file, ast.tokens(), &CompileOpts::default()) { return Err(error); } - symboltable::SymbolTable::scan_expr( - &ast.into_syntax().expect_expression(), - source_file.clone(), - ) + let ast = ast.into_syntax(); + if let Some(error) = unsupported_grammar_error(&ast, &source_file) { + return Err(error); + } + let mut ast = ast; + codegen::preprocess::preprocess_mod(&mut ast, 0, false, true); + symboltable::SymbolTable::scan_expr(&ast.expect_expression(), source_file.clone()) } }; res.map_err(|e| e.into_codegen_error(source_file.name().to_owned()).into()) @@ -5342,6 +5744,120 @@ mod tests { compile(code, Mode::Single, "<>", CompileOpts::default()).expect("compile error"); } + #[test] + fn barry_as_flufl_rewrites_legacy_not_equal_after_future_import() { + let code = compile( + "from __future__ import barry_as_FLUFL\nresult = 2 <> 3\n", + Mode::Exec, + "", + CompileOpts::default(), + ) + .expect("Barry comparison should compile"); + assert!( + code.flags + .contains(core::bytecode::CodeFlags::FUTURE_BARRY_AS_BDFL) + ); + } + + #[test] + fn inherited_barry_as_flufl_rewrites_legacy_not_equal() { + let opts = CompileOpts { + future_features: core::bytecode::CodeFlags::FUTURE_BARRY_AS_BDFL, + ..CompileOpts::default() + }; + compile("2 <> 3", Mode::Single, "", opts) + .expect("inherited Barry comparison should compile"); + } + + #[test] + fn barry_as_flufl_rejects_modern_not_equal() { + let err = compile( + "from __future__ import barry_as_FLUFL\n2 != 3\n", + Mode::Exec, + "", + CompileOpts::default(), + ) + .expect_err("Barry mode should reject !="); + assert_eq!( + err.to_string(), + "with Barry as BDFL, use '<>' instead of '!='" + ); + assert_eq!(err.python_location(), (2, 3)); + } + + #[test] + fn obsolete_not_equal_diagnostic_spans_the_whole_operator() { + let err = compile("2 <> 3\n", Mode::Exec, "", CompileOpts::default()) + .expect_err("'<>' outside Barry mode is a syntax error"); + assert_eq!(err.to_string(), "invalid syntax"); + assert_eq!(err.python_location(), (1, 3)); + assert_eq!(err.python_end_location(), Some((1, 5))); + + // Only `<>` spans two characters; any other token that cannot start an + // expression keeps its own location. + let err = compile("2 <;\n", Mode::Exec, "", CompileOpts::default()) + .expect_err("'<;' is a syntax error"); + assert_eq!(err.to_string(), "invalid syntax"); + assert_eq!(err.python_location(), (1, 4)); + assert_eq!(err.python_end_location(), Some((1, 5))); + + // A `<>` that starts a statement is reported at the `<` too, where the + // parser stops instead of one character in. + let err = compile("<>\n", Mode::Exec, "", CompileOpts::default()) + .expect_err("a bare '<>' is a syntax error"); + assert_eq!(err.to_string(), "invalid syntax"); + assert_eq!(err.python_location(), (1, 1)); + assert_eq!(err.python_end_location(), Some((1, 3))); + + // A bracket left open earlier in the source outranks the operator. + let err = compile( + "(\n2 <> 3", + Mode::Exec, + "", + CompileOpts::default(), + ) + .expect_err("the bracket is never closed"); + assert_eq!(err.to_string(), "'(' was never closed"); + assert_eq!(err.python_location(), (1, 1)); + } + + #[test] + fn barry_as_flufl_does_not_rewrite_strings_or_comments() { + compile( + "from __future__ import barry_as_FLUFL\nx = '<>'\n# <>\n", + Mode::Exec, + "", + CompileOpts::default(), + ) + .expect("Barry markers in strings and comments should stay untouched"); + } + + #[test] + fn syntax_error_before_barry_not_equal_takes_precedence() { + let err = compile( + "from __future__ import barry_as_FLUFL\n<>\n2 != 3\n", + Mode::Exec, + "", + CompileOpts::default(), + ) + .expect_err("the earlier invalid comparison should fail"); + assert_eq!(err.to_string(), "invalid syntax"); + assert_eq!(err.python_location(), (2, 1)); + } + + #[test] + fn unclosed_bracket_before_barry_not_equal_takes_precedence() { + let err = compile( + "from __future__ import barry_as_FLUFL\n(\n2 != 3", + Mode::Exec, + "", + CompileOpts::default(), + ) + .expect_err("the earlier unclosed bracket should fail"); + assert_eq!(err.to_string(), "'(' was never closed"); + assert_eq!(err.python_location(), (2, 1)); + } + #[test] fn compile_phello() { let code = r#" diff --git a/crates/derive-impl/src/compile_bytecode.rs b/crates/derive-impl/src/compile_bytecode.rs index 842b21f07f1..d28a7db3b17 100644 --- a/crates/derive-impl/src/compile_bytecode.rs +++ b/crates/derive-impl/src/compile_bytecode.rs @@ -47,6 +47,16 @@ struct CompilationSource { span: (Span, Span), } +/// Read a source file as text. A byte order mark belongs to the file's +/// encoding rather than to the text, so it never reaches the compiler. +fn read_source_file(path: &Path) -> std::io::Result { + let mut source = fs::read_to_string(path)?; + if source.starts_with('\u{feff}') { + source.drain(..'\u{feff}'.len_utf8()); + } + Ok(source) +} + pub trait Compiler { fn compile( &self, @@ -103,7 +113,7 @@ impl CompilationSource { match &self.kind { CompilationSourceKind::File { base, rel_path } => { let path = base.join(rel_path); - let source = fs::read_to_string(&path).map_err(|err| { + let source = read_source_file(&path).map_err(|err| { Diagnostic::spans_error( self.span, format!("Error reading file {path:?}: {err}"), @@ -172,7 +182,7 @@ impl CompilationSource { }; let compile_path = |src_path: &Path| { - let source = fs::read_to_string(src_path).map_err(|err| { + let source = read_source_file(src_path).map_err(|err| { Diagnostic::spans_error( self.span, format!("Error reading file {path:?}: {err}"), diff --git a/crates/doc/src/data.inc.rs b/crates/doc/src/data.inc.rs index a81cf75a9cf..7cebf091f89 100644 --- a/crates/doc/src/data.inc.rs +++ b/crates/doc/src/data.inc.rs @@ -1,5 +1,5 @@ // This file was auto-generated by `.github/workflows/update-doc-db.yml`. -// CPython version: 3.14.6 +// CPython version: 3.14.7 // spell-checker: disable pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { @@ -3600,6 +3600,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_ctypes.buffer_info" => "Return buffer interface information", "_ctypes.byref" => "Return a pointer lookalike to a C instance, only usable as function argument.", "_ctypes.dlclose" => "dlclose a library", + "_ctypes.dllist" => "dllist() return a list of loaded shared libraries", "_ctypes.dlopen" => "dlopen(name, flag={RTLD_GLOBAL|RTLD_LOCAL}) open a shared library", "_ctypes.dlsym" => "find symbol in shared library", "_ctypes.sizeof" => "Return the size in bytes of a C instance.", @@ -3641,6 +3642,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_curses.error.__weakref__" => "list of weak references to the object", "_curses.error.add_note" => "Add a note to the exception", "_curses.error.with_traceback" => "Set self.__traceback__ to tb and return self.", + "_curses.filter" => "Restrict screen updates to the current line.\n\nMust be called before initscr(). Afterwards curses confines the cursor\nand screen updates to a single line, which is useful for enabling\ncharacter-at-a-time line editing without touching the rest of the\nscreen.", "_curses.flash" => "Flash the screen.\n\nThat is, change it to reverse-video and then change it back in a short\ninterval.", "_curses.flushinp" => "Flush all input buffers.\n\nThis throws away any typeahead that has been typed by the user and has\nnot yet been processed by the program.", "_curses.get_escdelay" => "Gets the curses ESCDELAY setting.\n\nGets the number of milliseconds to wait after reading an escape\ncharacter, to distinguish between an individual escape character entered\non the keyboard from escape sequences sent by cursor and function keys.", @@ -3657,6 +3659,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_curses.init_color" => "Change the definition of a color.\n\n color_number\n The number of the color to be changed (0 - (COLORS-1)).\n r\n Red component (0 - 1000).\n g\n Green component (0 - 1000).\n b\n Blue component (0 - 1000).\n\nWhen init_color() is used, all occurrences of that color on the screen\nimmediately change to the new definition. This function is a no-op on\nmost terminals; it is active only if can_change_color() returns true.", "_curses.init_pair" => "Change the definition of a color-pair.\n\n pair_number\n The number of the color-pair to be changed (1 - (COLOR_PAIRS-1)).\n fg\n Foreground color number (-1 - (COLORS-1)).\n bg\n Background color number (-1 - (COLORS-1)).\n\nIf the color-pair was previously initialized, the screen is refreshed\nand all occurrences of that color-pair are changed to the new\ndefinition.", "_curses.initscr" => "Initialize the library.\n\nReturn a WindowObject which represents the whole screen.", + "_curses.intrflush" => "Control flushing of the output buffer when an interrupt key is pressed.\n\nIf flag is true, pressing an interrupt key (interrupt, break, or quit)\nflushes all output in the terminal driver queue. If flag is false, no\nflushing is done.", "_curses.is_term_resized" => "Return True if resize_term() would modify the window structure, False otherwise.\n\n nlines\n Height.\n ncols\n Width.", "_curses.isendwin" => "Return True if endwin() has been called.", "_curses.keyname" => "Return the name of specified key.\n\n key\n Key number.", @@ -3664,7 +3667,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_curses.longname" => "Return the terminfo long name field describing the current terminal.\n\nThe maximum length of a verbose description is 128 characters. It is\ndefined only after the call to initscr().", "_curses.meta" => "Enable/disable meta keys.\n\nIf yes is True, allow 8-bit characters to be input. If yes is False,\nallow only 7-bit characters.", "_curses.mouseinterval" => "Set and retrieve the maximum time between press and release in a click.\n\n interval\n Time in milliseconds.\n\nSet the maximum time that can elapse between press and release events in\norder for them to be recognized as a click, and return the previous\ninterval value.", - "_curses.mousemask" => "Set the mouse events to be reported, and return a tuple (availmask, oldmask).\n\nReturn a tuple (availmask, oldmask). availmask indicates which of the\nspecified mouse events can be reported; on complete failure it returns\n0. oldmask is the previous value of the given window's mouse event\nmask. If this function is never called, no mouse events are ever\nreported.", + "_curses.mousemask" => "Set the mouse events to be reported, and return (availmask, oldmask).\n\nReturn a tuple (availmask, oldmask). availmask indicates which of the\nspecified mouse events can be reported; on complete failure it returns\n0. oldmask is the previous value of the mouse event mask. If this\nfunction is never called, no mouse events are ever reported.", "_curses.napms" => "Sleep for specified time.\n\n ms\n Duration in milliseconds.", "_curses.newpad" => "Create and return a pointer to a new pad data structure.\n\n nlines\n Height.\n ncols\n Width.", "_curses.newwin" => "newwin(nlines, ncols, [begin_y=0, begin_x=0])\nReturn a new window.\n\n nlines\n Height.\n ncols\n Width.\n begin_y\n Top side y-coordinate.\n begin_x\n Left side x-coordinate.\n\nBy default, the window will extend from the specified position to the\nlower right corner of the screen.", @@ -3701,6 +3704,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_curses.unget_wch" => "Push ch so the next get_wch() will return it.", "_curses.ungetch" => "Push ch so the next getch() will return it.", "_curses.ungetmouse" => "Push a KEY_MOUSE event onto the input queue.\n\nThe following getmouse() will return the given state data.", + "_curses.update_lines_cols" => "Update the LINES and COLS module variables.\n\nThis is useful for detecting manual screen resize.", "_curses.use_default_colors" => "Equivalent to assume_default_colors(-1, -1).", "_curses.use_env" => "Use environment variables LINES and COLUMNS.\n\nIf used, this function should be called before initscr() or newterm()\nare called.\n\nWhen flag is False, the values of lines and columns specified in the\nterminfo database will be used, even if environment variables LINES and\nCOLUMNS (used by default) are set, or if curses is running in a window\n(in which case default behavior would be to use the window size if LINES\nand COLUMNS are not set).", "_curses.window.__delattr__" => "Implement delattr(self, name).", @@ -3735,34 +3739,69 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_curses.window.border" => "Draw a border around the edges of the window.\n\n ls\n Left side.\n rs\n Right side.\n ts\n Top side.\n bs\n Bottom side.\n tl\n Upper-left corner.\n tr\n Upper-right corner.\n bl\n Bottom-left corner.\n br\n Bottom-right corner.\n\nEach parameter specifies the character to use for a specific part of\nthe border. The characters can be specified as integers or as\none-character strings. A 0 value for any parameter will cause the\ndefault character to be used for that parameter.", "_curses.window.box" => "box([verch=0, horch=0])\nDraw a border around the edges of the window.\n\n verch\n Left and right side.\n horch\n Top and bottom side.\n\nSimilar to border(), but both ls and rs are verch and both ts and bs\nare horch. The default corner characters are always used by this\nfunction.", "_curses.window.chgat" => "chgat([y, x,] [n=-1,] attr)\nSet the attributes of characters.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n n\n Number of characters.\n attr\n Attributes for characters.\n\nSet the attributes of num characters at the current cursor position, or at\nposition (y, x) if supplied. If no value of num is given or num = -1, the\nattribute will be set on all the characters to the end of the line. This\nfunction does not move the cursor. The changed line will be touched using\nthe touchline() method so that the contents will be redisplayed by the next\nwindow refresh.", - "_curses.window.delch" => "delch([y, x])\nDelete any character at (y, x).\n\n y\n Y-coordinate.\n x\n X-coordinate.", + "_curses.window.clear" => "Clear the window and repaint it completely on the next refresh().", + "_curses.window.clearok" => "Clear the window on the next refresh() if flag is true.", + "_curses.window.clrtobot" => "Erase from the cursor to the end of the window.", + "_curses.window.clrtoeol" => "Erase from the cursor to the end of the line.", + "_curses.window.cursyncup" => "Update the cursor position of all ancestor windows to match.", + "_curses.window.delch" => "delch([y, x])\nDelete the character under the cursor, or at (y, x) if specified.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n\nAll characters to the right on the same line are shifted one\nposition left.", + "_curses.window.deleteln" => "Delete the line under the cursor; move following lines up by one.", "_curses.window.derwin" => "derwin([nlines=0, ncols=0,] begin_y, begin_x)\nCreate a sub-window (window-relative coordinates).\n\n nlines\n Height.\n ncols\n Width.\n begin_y\n Top side y-coordinate.\n begin_x\n Left side x-coordinate.\n\nderwin() is the same as calling subwin(), except that begin_y and\nbegin_x are relative to the origin of the window, rather than\nrelative to the entire screen.", "_curses.window.echochar" => "Add character ch with attribute attr, and refresh.\n\n ch\n Character to add.\n attr\n Attributes for the character.", "_curses.window.enclose" => "Return True if the screen-relative coordinates are enclosed by the window.\n\n y\n Y-coordinate.\n x\n X-coordinate.", "_curses.window.encoding" => "the typecode character used to create the array", + "_curses.window.erase" => "Clear the window.", "_curses.window.get_wch" => "get_wch([y, x])\nGet a wide character from terminal keyboard.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n\nReturn a character for most keys, or an integer for function keys,\nkeypad keys, and other special keys.", + "_curses.window.getbegyx" => "Return a tuple (y, x) of the upper-left corner coordinates.", "_curses.window.getbkgd" => "Return the window's current background character/attribute pair.", "_curses.window.getch" => "getch([y, x])\nGet a character code from terminal keyboard.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n\nThe integer returned does not have to be in ASCII range: function\nkeys, keypad keys and so on return numbers higher than 256. In\nno-delay mode, -1 is returned if there is no input, else getch()\nwaits until a key is pressed.", "_curses.window.getkey" => "getkey([y, x])\nGet a character (string) from terminal keyboard.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n\nReturning a string instead of an integer, as getch() does. Function\nkeys, keypad keys and other special keys return a multibyte string\ncontaining the key name. In no-delay mode, an exception is raised\nif there is no input.", + "_curses.window.getmaxyx" => "Return a tuple (y, x) of the window height and width.", + "_curses.window.getparyx" => "Return (y, x) relative to the parent window, or (-1, -1) if none.", "_curses.window.getstr" => "getstr([[y, x,] n=2047])\nRead a string from the user, with primitive line editing capacity.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n n\n Maximal number of characters.", + "_curses.window.getyx" => "Return a tuple (y, x) of the current cursor position.", "_curses.window.hline" => "hline([y, x,] ch, n, [attr=_curses.A_NORMAL])\nDisplay a horizontal line.\n\n y\n Starting Y-coordinate.\n x\n Starting X-coordinate.\n ch\n Character to draw.\n n\n Line length.\n attr\n Attributes for the characters.", + "_curses.window.idcok" => "Enable or disable the hardware insert/delete character feature.", + "_curses.window.idlok" => "Enable or disable the hardware insert/delete line feature.", + "_curses.window.immedok" => "If flag is true, refresh the window on every change to it.", "_curses.window.inch" => "inch([y, x])\nReturn the character at the given position in the window.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n\nThe bottom 8 bits are the character proper, and upper bits are the\nattributes.", "_curses.window.insch" => "insch([y, x,] ch, [attr=_curses.A_NORMAL])\nInsert a character before the current or specified position.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n ch\n Character to insert.\n attr\n Attributes for the character.\n\nAll characters to the right of the cursor are shifted one position\nright, with the rightmost characters on the line being lost.", + "_curses.window.insdelln" => "Insert (nlines > 0) or delete (nlines < 0) lines above the cursor.", + "_curses.window.insertln" => "Insert a blank line under the cursor; move following lines down.", "_curses.window.insnstr" => "insnstr([y, x,] str, n, [attr])\nInsert at most n characters of the string.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n str\n String to insert.\n n\n Maximal number of characters.\n attr\n Attributes for characters.\n\nInsert a character string (as many characters as will fit on the\nline) before the character under the cursor, up to n characters. If\nn is zero or negative, the entire string is inserted. All\ncharacters to the right of the cursor are shifted right, with the\nrightmost characters on the line being lost. The cursor position\ndoes not change (after moving to y, x, if specified).", "_curses.window.insstr" => "insstr([y, x,] str, [attr])\nInsert the string before the current or specified position.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n str\n String to insert.\n attr\n Attributes for characters.\n\nInsert a character string (as many characters as will fit on the\nline) before the character under the cursor. All characters to the\nright of the cursor are shifted right, with the rightmost characters\non the line being lost. The cursor position does not change (after\nmoving to y, x, if specified).", - "_curses.window.instr" => "instr([y, x,] n=2047)\nReturn a string of characters, extracted from the window.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n n\n Maximal number of characters.\n\nReturn a string of characters, extracted from the window starting at the\ncurrent cursor position, or at y, x if specified. Attributes are stripped\nfrom the characters. If n is specified, instr() returns a string at most\nn characters long (exclusive of the trailing NUL).", + "_curses.window.instr" => "instr([y, x,] n=2047)\nReturn a string of characters, extracted from the window.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n n\n Maximal number of characters.\n\nReturn a string of characters, extracted from the window starting\nat the current cursor position, or at y, x if specified, and\nstopping at the end of the line. Attributes and color\ninformation are stripped from the characters. If n is specified,\ninstr() returns a string at most n characters long (exclusive of\nthe trailing NUL).", "_curses.window.is_linetouched" => "Return True if the specified line was modified, otherwise return False.\n\n line\n Line number.\n\nRaise a curses.error exception if line is not valid for the given\nwindow.", + "_curses.window.is_wintouched" => "Return True if the window changed since the last refresh().", + "_curses.window.keypad" => "Interpret escape sequences for special keys if flag is true.", + "_curses.window.leaveok" => "If flag is true, leave the cursor where the update leaves it.", + "_curses.window.move" => "Move the cursor to (new_y, new_x).", + "_curses.window.mvderwin" => "Move the window inside its parent window.", + "_curses.window.mvwin" => "Move the window so its upper-left corner is at (new_y, new_x).", + "_curses.window.nodelay" => "If flag is true, getch() becomes non-blocking.", + "_curses.window.notimeout" => "If flag is true, do not time out escape sequences.", "_curses.window.noutrefresh" => "noutrefresh([pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol])\nMark for refresh but wait.\n\nThis function updates the data structure representing the desired\nstate of the window, but does not force an update of the physical\nscreen. To accomplish that, call doupdate().", "_curses.window.overlay" => "overlay(destwin, [sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol])\nOverlay the window on top of destwin.\n\nThe windows need not be the same size, only the overlapping region\nis copied. This copy is non-destructive, which means that the\ncurrent background character does not overwrite the old contents of\ndestwin.\n\nTo get fine-grained control over the copied region, the second form\nof overlay() can be used. sminrow and smincol are the upper-left\ncoordinates of the source window, and the other variables mark\na rectangle in the destination window.", "_curses.window.overwrite" => "overwrite(destwin, [sminrow, smincol, dminrow, dmincol, dmaxrow,\n dmaxcol])\nOverwrite the window on top of destwin.\n\nThe windows need not be the same size, in which case only the\noverlapping region is copied. This copy is destructive, which means\nthat the current background character overwrites the old contents of\ndestwin.\n\nTo get fine-grained control over the copied region, the second form\nof overwrite() can be used. sminrow and smincol are the upper-left\ncoordinates of the source window, the other variables mark\na rectangle in the destination window.", "_curses.window.putwin" => "Write all data associated with the window into the provided file object.\n\nThis information can be later retrieved using the getwin() function.", "_curses.window.redrawln" => "Mark the specified lines corrupted.\n\n beg\n Starting line number.\n num\n The number of lines.\n\nThey should be completely redrawn on the next refresh() call.", + "_curses.window.redrawwin" => "Mark the entire window for redraw on the next refresh().", "_curses.window.refresh" => "refresh([pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol])\nUpdate the display immediately.\n\nSynchronize actual screen with previous drawing/deleting methods.\nThe 6 optional arguments can only be specified when the window is\na pad created with newpad(). The additional parameters are needed\nto indicate what part of the pad and screen are involved. pminrow\nand pmincol specify the upper left-hand corner of the rectangle to\nbe displayed in the pad. sminrow, smincol, smaxrow, and smaxcol\nspecify the edges of the rectangle to be displayed on the screen.\nThe lower right-hand corner of the rectangle to be displayed in the\npad is calculated from the screen coordinates, since the rectangles\nmust be the same size. Both rectangles must be entirely contained\nwithin their respective structures. Negative values of pminrow,\npmincol, sminrow, or smincol are treated as if they were zero.", + "_curses.window.resize" => "Resize the window to nlines rows and ncols columns.", "_curses.window.scroll" => "scroll([lines=1])\nScroll the screen or scrolling region.\n\n lines\n Number of lines to scroll.\n\nScroll upward if the argument is positive and downward if it is\nnegative.", + "_curses.window.scrollok" => "Control whether the window scrolls when the cursor moves off it.", "_curses.window.setscrreg" => "Define a software scrolling region.\n\n top\n First line number.\n bottom\n Last line number.\n\nAll scrolling actions will take place in this region.", + "_curses.window.standend" => "Turn off the standout attribute.", + "_curses.window.standout" => "Turn on the A_STANDOUT attribute.", "_curses.window.subpad" => "subwin([nlines=0, ncols=0,] begin_y, begin_x)\nCreate a sub-window (screen-relative coordinates).\n\n nlines\n Height.\n ncols\n Width.\n begin_y\n Top side y-coordinate.\n begin_x\n Left side x-coordinate.\n\nBy default, the sub-window will extend from the specified position\nto the lower right corner of the window.", "_curses.window.subwin" => "subwin([nlines=0, ncols=0,] begin_y, begin_x)\nCreate a sub-window (screen-relative coordinates).\n\n nlines\n Height.\n ncols\n Width.\n begin_y\n Top side y-coordinate.\n begin_x\n Left side x-coordinate.\n\nBy default, the sub-window will extend from the specified position\nto the lower right corner of the window.", + "_curses.window.syncdown" => "Touch each location changed in any ancestor of the window.", + "_curses.window.syncok" => "If flag is true, call syncup() on every change to the window.", + "_curses.window.syncup" => "Touch locations in ancestors that changed in this window.", + "_curses.window.timeout" => "Set blocking or non-blocking read behavior for the window.", "_curses.window.touchline" => "touchline(start, count, [changed=True])\nPretend count lines have been changed, starting with line start.\n\nIf changed is supplied, it specifies whether the affected lines are\nmarked as having been changed (changed=True) or unchanged\n(changed=False).", + "_curses.window.touchwin" => "Mark the whole window as changed.", + "_curses.window.untouchwin" => "Mark all lines in the window as unchanged since last refresh().", "_curses.window.vline" => "vline([y, x,] ch, n, [attr=_curses.A_NORMAL])\nDisplay a vertical line.\n\n y\n Starting Y-coordinate.\n x\n Starting X-coordinate.\n ch\n Character to draw.\n n\n Line length.\n attr\n Attributes for the character.", "_curses_panel.bottom_panel" => "Return the bottom panel in the panel stack.", "_curses_panel.error.__delattr__" => "Implement delattr(self, name).", @@ -3788,7 +3827,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_curses_panel.error.__weakref__" => "list of weak references to the object", "_curses_panel.error.add_note" => "Add a note to the exception", "_curses_panel.error.with_traceback" => "Set self.__traceback__ to tb and return self.", - "_curses_panel.new_panel" => "Return a panel object, associating it with the given window win.", + "_curses_panel.new_panel" => "Return a panel object, associating it with the given window win.\n\nThe new panel is placed on top of the panel stack.", "_curses_panel.panel.__delattr__" => "Implement delattr(self, name).", "_curses_panel.panel.__eq__" => "Return self==value.", "_curses_panel.panel.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -3818,7 +3857,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_curses_panel.panel.move" => "Move the panel to the screen coordinates (y, x).", "_curses_panel.panel.replace" => "Change the window associated with the panel to the window win.", "_curses_panel.panel.set_userptr" => "Set the panel's user pointer to obj.", - "_curses_panel.panel.show" => "Display the panel (which might have been hidden).", + "_curses_panel.panel.show" => "Display the panel (which might have been hidden).\n\nThe panel is placed on top of the panel stack.", "_curses_panel.panel.top" => "Push panel to the top of the stack.", "_curses_panel.panel.userptr" => "Return the user pointer for the panel.", "_curses_panel.panel.window" => "Return the window object associated with the panel.", @@ -4134,7 +4173,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_decimal.Context.compare_signal" => "Compare x and y numerically. All NaNs signal.", "_decimal.Context.compare_total" => "Compare x and y using their abstract representation.", "_decimal.Context.compare_total_mag" => "Compare x and y using their abstract representation, ignoring sign.", - "_decimal.Context.copy" => "Return a duplicate of the context with all flags cleared.", + "_decimal.Context.copy" => "Return a duplicate of the context.", "_decimal.Context.copy_abs" => "Return a copy of x with the sign set to 0.", "_decimal.Context.copy_decimal" => "Return a copy of Decimal x.", "_decimal.Context.copy_negate" => "Return a copy of x with the sign inverted.", @@ -4334,7 +4373,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_decimal.DecimalException.with_traceback" => "Set self.__traceback__ to tb and return self.", "_decimal.DecimalTuple" => "DecimalTuple(sign, digits, exponent)", "_decimal.DecimalTuple.__add__" => "Return self+value.", - "_decimal.DecimalTuple.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "_decimal.DecimalTuple.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "_decimal.DecimalTuple.__contains__" => "Return bool(key in self).", "_decimal.DecimalTuple.__delattr__" => "Implement delattr(self, name).", "_decimal.DecimalTuple.__eq__" => "Return self==value.", @@ -5136,7 +5175,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_interpchannels.ChannelID.send" => "the 'send' end of the channel", "_interpchannels.ChannelInfo" => "ChannelInfo\n\nA named tuple of a channel's state.", "_interpchannels.ChannelInfo.__add__" => "Return self+value.", - "_interpchannels.ChannelInfo.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "_interpchannels.ChannelInfo.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "_interpchannels.ChannelInfo.__contains__" => "Return bool(key in self).", "_interpchannels.ChannelInfo.__delattr__" => "Implement delattr(self, name).", "_interpchannels.ChannelInfo.__eq__" => "Return self==value.", @@ -6122,7 +6161,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_lsprof.Profiler.enable" => "Start collecting profiling information.\n\n subcalls\n If True, also records for each function\n statistics separated according to its current caller.\n builtins\n If True, records the time spent in\n built-in functions separately from their caller.", "_lsprof.Profiler.getstats" => "list of profiler_entry objects.\n\ngetstats() -> list of profiler_entry objects\n\nReturn all information collected by the profiler.\nEach profiler_entry is a tuple-like object with the\nfollowing attributes:\n\n code code object\n callcount how many times this was called\n reccallcount how many times called recursively\n totaltime total time in this entry\n inlinetime inline time in this entry (not in subcalls)\n calls details of the calls\n\nThe calls attribute is either None or a list of\nprofiler_subentry objects:\n\n code called code object\n callcount how many times this is called\n reccallcount how many times this is called recursively\n totaltime total time spent in this call\n inlinetime inline time (not in further subcalls)", "_lsprof.profiler_entry.__add__" => "Return self+value.", - "_lsprof.profiler_entry.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "_lsprof.profiler_entry.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "_lsprof.profiler_entry.__contains__" => "Return bool(key in self).", "_lsprof.profiler_entry.__delattr__" => "Implement delattr(self, name).", "_lsprof.profiler_entry.__eq__" => "Return self==value.", @@ -6159,7 +6198,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_lsprof.profiler_entry.reccallcount" => "how many times called recursively", "_lsprof.profiler_entry.totaltime" => "total time in this entry", "_lsprof.profiler_subentry.__add__" => "Return self+value.", - "_lsprof.profiler_subentry.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "_lsprof.profiler_subentry.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "_lsprof.profiler_subentry.__contains__" => "Return bool(key in self).", "_lsprof.profiler_subentry.__delattr__" => "Implement delattr(self, name).", "_lsprof.profiler_subentry.__eq__" => "Return self==value.", @@ -6853,7 +6892,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_random.Random.setstate" => "setstate(state) -> None. Restores generator state.", "_remote_debugging.AwaitedInfo" => "Information about what a thread is awaiting", "_remote_debugging.AwaitedInfo.__add__" => "Return self+value.", - "_remote_debugging.AwaitedInfo.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "_remote_debugging.AwaitedInfo.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "_remote_debugging.AwaitedInfo.__contains__" => "Return bool(key in self).", "_remote_debugging.AwaitedInfo.__delattr__" => "Implement delattr(self, name).", "_remote_debugging.AwaitedInfo.__eq__" => "Return self==value.", @@ -6887,7 +6926,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_remote_debugging.AwaitedInfo.thread_id" => "Thread ID", "_remote_debugging.CoroInfo" => "Information about a coroutine", "_remote_debugging.CoroInfo.__add__" => "Return self+value.", - "_remote_debugging.CoroInfo.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "_remote_debugging.CoroInfo.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "_remote_debugging.CoroInfo.__contains__" => "Return bool(key in self).", "_remote_debugging.CoroInfo.__delattr__" => "Implement delattr(self, name).", "_remote_debugging.CoroInfo.__eq__" => "Return self==value.", @@ -6921,7 +6960,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_remote_debugging.CoroInfo.task_name" => "Task name", "_remote_debugging.FrameInfo" => "Information about a frame", "_remote_debugging.FrameInfo.__add__" => "Return self+value.", - "_remote_debugging.FrameInfo.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "_remote_debugging.FrameInfo.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "_remote_debugging.FrameInfo.__contains__" => "Return bool(key in self).", "_remote_debugging.FrameInfo.__delattr__" => "Implement delattr(self, name).", "_remote_debugging.FrameInfo.__eq__" => "Return self==value.", @@ -6981,7 +7020,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_remote_debugging.RemoteUnwinder.get_stack_trace" => "Returns a list of stack traces for threads in the target process.\n\nEach element in the returned list is a tuple of (thread_id, frame_list), where:\n- thread_id is the OS thread identifier\n- frame_list is a list of tuples (function_name, filename, line_number) representing\n the Python stack frames for that thread, ordered from most recent to oldest\n\nThe threads returned depend on the initialization parameters:\n- If only_active_thread was True: returns only the thread holding the GIL\n- If all_threads was True: returns all threads\n- Otherwise: returns only the main thread\n\nExample:\n [\n (1234, [\n ('process_data', 'worker.py', 127),\n ('run_worker', 'worker.py', 45),\n ('main', 'app.py', 23)\n ]),\n (1235, [\n ('handle_request', 'server.py', 89),\n ('serve_forever', 'server.py', 52)\n ])\n ]\n\nRaises:\n RuntimeError: If there is an error copying memory from the target process\n OSError: If there is an error accessing the target process\n PermissionError: If access to the target process is denied\n UnicodeDecodeError: If there is an error decoding strings from the target process", "_remote_debugging.TaskInfo" => "Information about an asyncio task", "_remote_debugging.TaskInfo.__add__" => "Return self+value.", - "_remote_debugging.TaskInfo.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "_remote_debugging.TaskInfo.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "_remote_debugging.TaskInfo.__contains__" => "Return bool(key in self).", "_remote_debugging.TaskInfo.__delattr__" => "Implement delattr(self, name).", "_remote_debugging.TaskInfo.__eq__" => "Return self==value.", @@ -7017,7 +7056,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_remote_debugging.TaskInfo.task_name" => "Task name", "_remote_debugging.ThreadInfo" => "Information about a thread", "_remote_debugging.ThreadInfo.__add__" => "Return self+value.", - "_remote_debugging.ThreadInfo.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "_remote_debugging.ThreadInfo.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "_remote_debugging.ThreadInfo.__contains__" => "Return bool(key in self).", "_remote_debugging.ThreadInfo.__delattr__" => "Implement delattr(self, name).", "_remote_debugging.ThreadInfo.__eq__" => "Return self==value.", @@ -7383,7 +7422,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_signal.strsignal" => "Return the system description of the given signal.\n\nReturns the description of signal *signalnum*, such as \"Interrupt\"\nfor :const:`SIGINT`. Returns :const:`None` if *signalnum* has no\ndescription. Raises :exc:`ValueError` if *signalnum* is invalid.", "_signal.struct_siginfo" => "struct_siginfo: Result from sigwaitinfo or sigtimedwait.\n\nThis object may be accessed either as a tuple of\n(si_signo, si_code, si_errno, si_pid, si_uid, si_status, si_band),\nor via the attributes si_signo, si_code, and so on.", "_signal.struct_siginfo.__add__" => "Return self+value.", - "_signal.struct_siginfo.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "_signal.struct_siginfo.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "_signal.struct_siginfo.__contains__" => "Return bool(key in self).", "_signal.struct_siginfo.__delattr__" => "Implement delattr(self, name).", "_signal.struct_siginfo.__eq__" => "Return self==value.", @@ -8408,10 +8447,10 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_struct.Struct.format" => "struct format string", "_struct.Struct.iter_unpack" => "Return an iterator yielding tuples.\n\nTuples are unpacked from the given bytes source, like a repeated\ninvocation of unpack_from().\n\nRequires that the bytes length be a multiple of the struct size.", "_struct.Struct.pack" => "S.pack(v1, v2, ...) -> bytes\n\nReturn a bytes object containing values v1, v2, ... packed according\nto the format string S.format. See help(struct) for more on format\nstrings.", - "_struct.Struct.pack_into" => "S.pack_into(buffer, offset, v1, v2, ...)\n\nPack the values v1, v2, ... according to the format string S.format\nand write the packed bytes into the writable buffer buf starting at\noffset. Note that the offset is a required argument. See\nhelp(struct) for more on format strings.", + "_struct.Struct.pack_into" => "S.pack_into(buffer, offset, v1, v2, ...)\n\nPack the values v1, v2, ... according to the format string S.format\nand write the packed bytes into the writable buffer buf starting at\noffset. Note that the offset is a required argument. A negative\noffset counts from the end of the buffer. See help(struct) for more\non format strings.", "_struct.Struct.size" => "struct size in bytes", "_struct.Struct.unpack" => "Return a tuple containing unpacked values.\n\nUnpack according to the format string Struct.format. The buffer's size\nin bytes must be Struct.size.\n\nSee help(struct) for more on format strings.", - "_struct.Struct.unpack_from" => "Return a tuple containing unpacked values.\n\nValues are unpacked according to the format string Struct.format.\n\nThe buffer's size in bytes, starting at position offset, must be\nat least Struct.size.\n\nSee help(struct) for more on format strings.", + "_struct.Struct.unpack_from" => "Return a tuple containing unpacked values.\n\nValues are unpacked according to the format string Struct.format.\n\nThe buffer's size in bytes, starting at position offset, must be\nat least Struct.size. A negative offset counts from the end of the\nbuffer.\n\nSee help(struct) for more on format strings.", "_struct._clearcache" => "Clear the internal cache.", "_struct.calcsize" => "Return size in bytes of the struct described by the format string.", "_struct.error.__delattr__" => "Implement delattr(self, name).", @@ -8439,9 +8478,9 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_struct.error.with_traceback" => "Set self.__traceback__ to tb and return self.", "_struct.iter_unpack" => "Return an iterator yielding tuples unpacked from the given bytes.\n\nThe bytes are unpacked according to the format string, like\na repeated invocation of unpack_from().\n\nRequires that the bytes length be a multiple of the format struct size.", "_struct.pack" => "pack(format, v1, v2, ...) -> bytes\n\nReturn a bytes object containing the values v1, v2, ... packed according\nto the format string. See help(struct) for more on format strings.", - "_struct.pack_into" => "pack_into(format, buffer, offset, v1, v2, ...)\n\nPack the values v1, v2, ... according to the format string and write\nthe packed bytes into the writable buffer buf starting at offset. Note\nthat the offset is a required argument. See help(struct) for more\non format strings.", + "_struct.pack_into" => "pack_into(format, buffer, offset, v1, v2, ...)\n\nPack the values v1, v2, ... according to the format string and write\nthe packed bytes into the writable buffer buf starting at offset. Note\nthat the offset is a required argument. A negative offset counts from\nthe end of the buffer. See help(struct) for more on format strings.", "_struct.unpack" => "Return a tuple containing values unpacked according to the format string.\n\nThe buffer's size in bytes must be calcsize(format).\n\nSee help(struct) for more on format strings.", - "_struct.unpack_from" => "Return a tuple containing values unpacked according to the format string.\n\nThe buffer's size, minus offset, must be at least calcsize(format).\n\nSee help(struct) for more on format strings.", + "_struct.unpack_from" => "Return a tuple containing values unpacked according to the format string.\n\nThe buffer's size, minus offset, must be at least calcsize(format).\nA negative offset counts from the end of the buffer.\n\nSee help(struct) for more on format strings.", "_suggestions._generate_suggestions" => "Returns the candidate in candidates that's closest to item", "_symtable.symtable" => "Return symbol and scope dictionaries used internally by compiler.", "_sysconfig" => "A helper for the sysconfig module.", @@ -8509,7 +8548,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_thread.RLock.release" => "Release the lock, allowing another thread that is blocked waiting for\nthe lock to acquire the lock. The lock must be in the locked state,\nand must be locked by the same thread that unlocks it; otherwise a\n`RuntimeError` is raised.\n\nDo note that if the lock was acquire()d several times in a row by the\ncurrent thread, release() needs to be called as many times for the lock\nto be available for other threads.", "_thread._ExceptHookArgs" => "ExceptHookArgs\n\nType used to pass arguments to threading.excepthook.", "_thread._ExceptHookArgs.__add__" => "Return self+value.", - "_thread._ExceptHookArgs.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "_thread._ExceptHookArgs.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "_thread._ExceptHookArgs.__contains__" => "Return bool(key in self).", "_thread._ExceptHookArgs.__delattr__" => "Implement delattr(self, name).", "_thread._ExceptHookArgs.__eq__" => "Return self==value.", @@ -8763,7 +8802,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_tracemalloc.start" => "Start tracing Python memory allocations.\n\nAlso set the maximum number of frames stored in the traceback of a\ntrace to nframe.", "_tracemalloc.stop" => "Stop tracing Python memory allocations.\n\nAlso clear traces of memory blocks allocated by Python.", "_types" => "Define names for built-in types.", - "_types.GenericAlias" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "_types.GenericAlias" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "_types.GenericAlias.__call__" => "Call self as a function.", "_types.GenericAlias.__delattr__" => "Implement delattr(self, name).", "_types.GenericAlias.__eq__" => "Return self==value.", @@ -8859,7 +8898,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_types.SimpleNamespace.__subclasshook__" => "Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented. If it returns\nNotImplemented, the normal algorithm is used. Otherwise, it\noverrides the normal algorithm (and the outcome is cached).", "_typing" => "Primitives and accelerators for the typing module.", "_typing.Generic" => "Abstract base class for generic types.\n\nOn Python 3.12 and newer, generic classes implicitly inherit from\nGeneric when they declare a parameter list after the class's name::\n\n class Mapping[KT, VT]:\n def __getitem__(self, key: KT) -> VT:\n ...\n # Etc.\n\nOn older versions of Python, however, generic classes have to\nexplicitly inherit from Generic.\n\nAfter a class has been declared to be generic, it can then be used as\nfollows::\n\n def lookup_name[KT, VT](mapping: Mapping[KT, VT], key: KT, default: VT) -> VT:\n try:\n return mapping[key]\n except KeyError:\n return default", - "_typing.Generic.__class_getitem__" => "Parameterizes a generic class.\n\nAt least, parameterizing a generic class is the *main* thing this\nmethod does. For example, for some generic class `Foo`, this is called\nwhen we do `Foo[int]` - there, with `cls=Foo` and `params=int`.\n\nHowever, note that this method is also called when defining generic\nclasses in the first place with `class Foo[T]: ...`.", + "_typing.Generic.__class_getitem__" => "Parameterizes a generic class.\n\nAt least, parameterizing a generic class is the *main* thing this\nmethod does. For example, for some generic class `Foo`, this is\ncalled when we do `Foo[int]` - there, with `cls=Foo` and\n`params=int`.\n\nHowever, note that this method is also called when defining generic\nclasses in the first place with `class Foo[T]: ...`.", "_typing.Generic.__delattr__" => "Implement delattr(self, name).", "_typing.Generic.__eq__" => "Return self==value.", "_typing.Generic.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -9268,6 +9307,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "_winapi.GetModuleFileName" => "Return the fully-qualified path for the file that contains module.\n\nThe module must have been loaded by the current process.\n\nThe module parameter should be a handle to the loaded module\nwhose path is being requested. If this parameter is 0,\nGetModuleFileName retrieves the path of the executable file\nof the current process.", "_winapi.GetShortPathName" => "Return the short version of the provided path.\n\nIf the path is already in its short form, returns the same value.\n\nThe path must already be a 'str'. If the type is not known, use\nos.fsdecode before calling this function.", "_winapi.GetStdHandle" => "Return a handle to the specified standard device.\n\n std_handle\n One of STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, or STD_ERROR_HANDLE.\n\nThe integer associated with the handle object is returned.", + "_winapi.GetTickCount64" => "Number of milliseconds that have elapsed since the system was started.", "_winapi.GetVersion" => "Return the version number of the current operating system.", "_winapi.Overlapped" => "OVERLAPPED structure wrapper", "_winapi.Overlapped.__delattr__" => "Implement delattr(self, name).", @@ -10022,7 +10062,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.AsyncContextDecorator.__subclasshook__" => "Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented. If it returns\nNotImplemented, the normal algorithm is used. Otherwise, it\noverrides the normal algorithm (and the outcome is cached).", "builtins.AsyncContextDecorator.__weakref__" => "list of weak references to the object", "builtins.AsyncContextDecorator._recreate_cm" => "Return a recreated instance of self.", - "builtins.AsyncIterable.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.AsyncIterable.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.AsyncIterable.__delattr__" => "Implement delattr(self, name).", "builtins.AsyncIterable.__eq__" => "Return self==value.", "builtins.AsyncIterable.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -10067,7 +10107,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.AttributeError.name" => "attribute name", "builtins.AttributeError.obj" => "object", "builtins.AttributeError.with_traceback" => "Set self.__traceback__ to tb and return self.", - "builtins.Awaitable.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.Awaitable.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.Awaitable.__delattr__" => "Implement delattr(self, name).", "builtins.Awaitable.__eq__" => "Return self==value.", "builtins.Awaitable.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -11432,7 +11472,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.Compile.__subclasshook__" => "Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented. If it returns\nNotImplemented, the normal algorithm is used. Otherwise, it\noverrides the normal algorithm (and the outcome is cached).", "builtins.Compile.__weakref__" => "list of weak references to the object", "builtins.CompletedProcess" => "A process that has finished running.\n\nThis is returned by run().\n\nAttributes:\n args: The list or str args passed to run().\n returncode: The exit code of the process, negative for signals.\n stdout: The standard output (None if not captured).\n stderr: The standard error (None if not captured).", - "builtins.CompletedProcess.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.CompletedProcess.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.CompletedProcess.__delattr__" => "Implement delattr(self, name).", "builtins.CompletedProcess.__eq__" => "Return self==value.", "builtins.CompletedProcess.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -11693,7 +11733,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.ConnectionResetError.strerror" => "exception strerror", "builtins.ConnectionResetError.winerror" => "Win32 exception code", "builtins.ConnectionResetError.with_traceback" => "Set self.__traceback__ to tb and return self.", - "builtins.Container.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.Container.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.Container.__delattr__" => "Implement delattr(self, name).", "builtins.Container.__eq__" => "Return self==value.", "builtins.Container.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -12210,7 +12250,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.Dialog.__str__" => "Return str(self).", "builtins.Dialog.__subclasshook__" => "Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented. If it returns\nNotImplemented, the normal algorithm is used. Otherwise, it\noverrides the normal algorithm (and the outcome is cached).", "builtins.Dialog.__weakref__" => "list of weak references to the object", - "builtins.DictReader.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.DictReader.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.DictReader.__delattr__" => "Implement delattr(self, name).", "builtins.DictReader.__eq__" => "Return self==value.", "builtins.DictReader.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -12255,7 +12295,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.DictRemover.__sizeof__" => "Size of object in memory, in bytes.", "builtins.DictRemover.__str__" => "Return str(self).", "builtins.DictRemover.__subclasshook__" => "Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented. If it returns\nNotImplemented, the normal algorithm is used. Otherwise, it\noverrides the normal algorithm (and the outcome is cached).", - "builtins.DictWriter.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.DictWriter.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.DictWriter.__delattr__" => "Implement delattr(self, name).", "builtins.DictWriter.__eq__" => "Return self==value.", "builtins.DictWriter.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -12718,7 +12758,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.EnvironmentError.winerror" => "Win32 exception code", "builtins.EnvironmentError.with_traceback" => "Set self.__traceback__ to tb and return self.", "builtins.Event" => "Container for the properties of an event.\n\nInstances of this type are generated if one of the following events occurs:\n\nKeyPress, KeyRelease - for keyboard events\nButtonPress, ButtonRelease, Motion, Enter, Leave, MouseWheel - for mouse events\nVisibility, Unmap, Map, Expose, FocusIn, FocusOut, Circulate,\nColormap, Gravity, Reparent, Property, Destroy, Activate,\nDeactivate - for window events.\n\nIf a callback function for one of these events is registered\nusing bind, bind_all, bind_class, or tag_bind, the callback is\ncalled with an Event as first argument. It will have the\nfollowing attributes (in braces are the event types for which\nthe attribute is valid):\n\n serial - serial number of event\nnum - mouse button pressed (ButtonPress, ButtonRelease)\nfocus - whether the window has the focus (Enter, Leave)\nheight - height of the exposed window (Configure, Expose)\nwidth - width of the exposed window (Configure, Expose)\nkeycode - keycode of the pressed key (KeyPress, KeyRelease)\nstate - state of the event as a number (ButtonPress, ButtonRelease,\n Enter, KeyPress, KeyRelease,\n Leave, Motion)\nstate - state as a string (Visibility)\ntime - when the event occurred\nx - x-position of the mouse\ny - y-position of the mouse\nx_root - x-position of the mouse on the screen\n (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion)\ny_root - y-position of the mouse on the screen\n (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion)\nchar - pressed character (KeyPress, KeyRelease)\nsend_event - see X/Windows documentation\nkeysym - keysym of the event as a string (KeyPress, KeyRelease)\nkeysym_num - keysym of the event as a number (KeyPress, KeyRelease)\ntype - type of the event as a number\nwidget - widget in which the event occurred\ndelta - delta of wheel movement (MouseWheel)", - "builtins.Event.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.Event.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.Event.__delattr__" => "Implement delattr(self, name).", "builtins.Event.__eq__" => "Return self==value.", "builtins.Event.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -12896,7 +12936,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.FTP.transfercmd" => "Like ntransfercmd() but returns only the socket.", "builtins.FTP.voidcmd" => "Send a command and expect a response beginning with '2'.", "builtins.FTP.voidresp" => "Expect a response beginning with '2'.", - "builtins.Field.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.Field.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.Field.__delattr__" => "Implement delattr(self, name).", "builtins.Field.__eq__" => "Return self==value.", "builtins.Field.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -12971,7 +13011,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.FileFinder.invalidate_caches" => "Invalidate the directory mtime.", "builtins.FileFinder.path_hook" => "A class method which returns a closure to use on sys.path_hook\nwhich will return an instance using the specified loaders and the path\ncalled on the closure.\n\nIf the path called on the closure is not a directory, ImportError is\nraised.", "builtins.FileInput" => "FileInput([files[, inplace[, backup]]], *, mode=None, openhook=None)\n\nClass FileInput is the implementation of the module; its methods\nfilename(), lineno(), fileline(), isfirstline(), isstdin(), fileno(),\nnextfile() and close() correspond to the functions of the same name\nin the module.\nIn addition it has a readline() method which returns the next\ninput line, and a __getitem__() method which implements the\nsequence behavior. The sequence must be accessed in strictly\nsequential order; random access and readline() cannot be mixed.", - "builtins.FileInput.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.FileInput.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.FileInput.__delattr__" => "Implement delattr(self, name).", "builtins.FileInput.__eq__" => "Return self==value.", "builtins.FileInput.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -13383,7 +13423,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.Future" => "This class is *almost* compatible with concurrent.futures.Future.\n\nDifferences:\n\n- This class is not thread-safe.\n\n- result() and exception() do not take a timeout argument and\n raise an exception when the future isn't done yet.\n\n- Callbacks registered with add_done_callback() are always called\n via the event loop's call_soon().\n\n- This class is not compatible with the wait() and as_completed()\n methods in the concurrent.futures package.", "builtins.Future._Future__schedule_callbacks" => "Internal: Ask the event loop to call all callbacks.\n\nThe callbacks are scheduled to be called as soon as possible. Also\nclears the callback list.", "builtins.Future.__await__" => "Return an iterator to be used in await expression.", - "builtins.Future.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.Future.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.Future.__del__" => "Called when the instance is about to be destroyed.", "builtins.Future.__delattr__" => "Implement delattr(self, name).", "builtins.Future.__eq__" => "Return self==value.", @@ -13531,7 +13571,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.GeneratorExit.add_note" => "Add a note to the exception", "builtins.GeneratorExit.with_traceback" => "Set self.__traceback__ to tb and return self.", "builtins.Generic" => "Abstract base class for generic types.\n\nOn Python 3.12 and newer, generic classes implicitly inherit from\nGeneric when they declare a parameter list after the class's name::\n\n class Mapping[KT, VT]:\n def __getitem__(self, key: KT) -> VT:\n ...\n # Etc.\n\nOn older versions of Python, however, generic classes have to\nexplicitly inherit from Generic.\n\nAfter a class has been declared to be generic, it can then be used as\nfollows::\n\n def lookup_name[KT, VT](mapping: Mapping[KT, VT], key: KT, default: VT) -> VT:\n try:\n return mapping[key]\n except KeyError:\n return default", - "builtins.Generic.__class_getitem__" => "Parameterizes a generic class.\n\nAt least, parameterizing a generic class is the *main* thing this\nmethod does. For example, for some generic class `Foo`, this is called\nwhen we do `Foo[int]` - there, with `cls=Foo` and `params=int`.\n\nHowever, note that this method is also called when defining generic\nclasses in the first place with `class Foo[T]: ...`.", + "builtins.Generic.__class_getitem__" => "Parameterizes a generic class.\n\nAt least, parameterizing a generic class is the *main* thing this\nmethod does. For example, for some generic class `Foo`, this is\ncalled when we do `Foo[int]` - there, with `cls=Foo` and\n`params=int`.\n\nHowever, note that this method is also called when defining generic\nclasses in the first place with `class Foo[T]: ...`.", "builtins.Generic.__delattr__" => "Implement delattr(self, name).", "builtins.Generic.__eq__" => "Return self==value.", "builtins.Generic.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -13553,7 +13593,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.Generic.__sizeof__" => "Size of object in memory, in bytes.", "builtins.Generic.__str__" => "Return str(self).", "builtins.Generic.__subclasshook__" => "Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented. If it returns\nNotImplemented, the normal algorithm is used. Otherwise, it\noverrides the normal algorithm (and the outcome is cached).", - "builtins.GenericAlias" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.GenericAlias" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.GenericAlias.__call__" => "Call self as a function.", "builtins.GenericAlias.__delattr__" => "Implement delattr(self, name).", "builtins.GenericAlias.__eq__" => "Return self==value.", @@ -13679,49 +13719,6 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.HMAC.digest" => "Return the hash value of this hashing object.\n\nThis returns the hmac value as bytes. The object is\nnot altered in any way by this function; you can continue\nupdating the object after calling this function.", "builtins.HMAC.hexdigest" => "Like digest(), but returns a string of hexadecimal digits instead.", "builtins.HMAC.update" => "Feed data from msg into this hashing object.", - "builtins.HTTPMethod" => "HTTP methods and descriptions\n\nMethods from the following RFCs are all observed:\n\n * RFC 9110: HTTP Semantics, obsoletes 7231, which obsoleted 2616\n * RFC 5789: PATCH Method for HTTP", - "builtins.HTTPMethod.__delattr__" => "Implement delattr(self, name).", - "builtins.HTTPMethod.__eq__" => "Return self==value.", - "builtins.HTTPMethod.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", - "builtins.HTTPMethod.__ge__" => "Return self>=value.", - "builtins.HTTPMethod.__getattribute__" => "Return getattr(self, name).", - "builtins.HTTPMethod.__getstate__" => "Helper for pickle.", - "builtins.HTTPMethod.__gt__" => "Return self>value.", - "builtins.HTTPMethod.__hash__" => "Return hash(self).", - "builtins.HTTPMethod.__init__" => "Initialize self. See help(type(self)) for accurate signature.", - "builtins.HTTPMethod.__init_subclass__" => "This method is called when a class is subclassed.\n\nThe default implementation does nothing. It may be\noverridden to extend subclasses.", - "builtins.HTTPMethod.__le__" => "Return self<=value.", - "builtins.HTTPMethod.__lt__" => "Return self "Return self!=value.", - "builtins.HTTPMethod.__reduce__" => "Helper for pickle.", - "builtins.HTTPMethod.__reduce_ex__" => "Helper for pickle.", - "builtins.HTTPMethod.__setattr__" => "Implement setattr(self, name, value).", - "builtins.HTTPMethod.__sizeof__" => "Size of object in memory, in bytes.", - "builtins.HTTPMethod.__str__" => "Return str(self).", - "builtins.HTTPMethod.__subclasshook__" => "Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented. If it returns\nNotImplemented, the normal algorithm is used. Otherwise, it\noverrides the normal algorithm (and the outcome is cached).", - "builtins.HTTPMethod.__weakref__" => "list of weak references to the object", - "builtins.HTTPStatus" => "HTTP status codes and reason phrases\n\nStatus codes from the following RFCs are all observed:\n\n * RFC 9110: HTTP Semantics, obsoletes 7231, which obsoleted 2616\n * RFC 6585: Additional HTTP Status Codes\n * RFC 3229: Delta encoding in HTTP\n * RFC 4918: HTTP Extensions for WebDAV, obsoletes 2518\n * RFC 5842: Binding Extensions to WebDAV\n * RFC 7238: Permanent Redirect\n * RFC 2295: Transparent Content Negotiation in HTTP\n * RFC 2774: An HTTP Extension Framework\n * RFC 7725: An HTTP Status Code to Report Legal Obstacles\n * RFC 7540: Hypertext Transfer Protocol Version 2 (HTTP/2)\n * RFC 2324: Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0)\n * RFC 8297: An HTTP Status Code for Indicating Hints\n * RFC 8470: Using Early Data in HTTP", - "builtins.HTTPStatus.__delattr__" => "Implement delattr(self, name).", - "builtins.HTTPStatus.__eq__" => "Return self==value.", - "builtins.HTTPStatus.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", - "builtins.HTTPStatus.__ge__" => "Return self>=value.", - "builtins.HTTPStatus.__getattribute__" => "Return getattr(self, name).", - "builtins.HTTPStatus.__getstate__" => "Helper for pickle.", - "builtins.HTTPStatus.__gt__" => "Return self>value.", - "builtins.HTTPStatus.__hash__" => "Return hash(self).", - "builtins.HTTPStatus.__init__" => "Initialize self. See help(type(self)) for accurate signature.", - "builtins.HTTPStatus.__init_subclass__" => "This method is called when a class is subclassed.\n\nThe default implementation does nothing. It may be\noverridden to extend subclasses.", - "builtins.HTTPStatus.__le__" => "Return self<=value.", - "builtins.HTTPStatus.__lt__" => "Return self "Return self!=value.", - "builtins.HTTPStatus.__reduce__" => "Helper for pickle.", - "builtins.HTTPStatus.__reduce_ex__" => "Helper for pickle.", - "builtins.HTTPStatus.__repr__" => "Return repr(self).", - "builtins.HTTPStatus.__setattr__" => "Implement setattr(self, name, value).", - "builtins.HTTPStatus.__sizeof__" => "Size of object in memory, in bytes.", - "builtins.HTTPStatus.__str__" => "Return str(self).", - "builtins.HTTPStatus.__subclasshook__" => "Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented. If it returns\nNotImplemented, the normal algorithm is used. Otherwise, it\noverrides the normal algorithm (and the outcome is cached).", - "builtins.HTTPStatus.__weakref__" => "list of weak references to the object", "builtins.Handle" => "Object returned by callback registration methods.", "builtins.Handle.__delattr__" => "Implement delattr(self, name).", "builtins.Handle.__eq__" => "Return self==value.", @@ -13999,11 +13996,11 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.IMAP4.getquota" => "Get the quota root's resource usage and limits.\n\nPart of the IMAP4 QUOTA extension defined in rfc2087.\n\n(typ, [data]) = .getquota(root)", "builtins.IMAP4.getquotaroot" => "Get the list of quota roots for the named mailbox.\n\n(typ, [[QUOTAROOT responses...], [QUOTA responses]]) = .getquotaroot(mailbox)", "builtins.IMAP4.idle" => "Return an iterable IDLE context manager producing untagged responses.\nIf the argument is not None, limit iteration to 'duration' seconds.\n\nwith M.idle(duration=29 * 60) as idler:\n for typ, data in idler:\n print(typ, data)\n\nNote: 'duration' requires a socket connection (not IMAP4_stream).", - "builtins.IMAP4.list" => "List mailbox names in directory matching pattern.\n\n(typ, [data]) = .list(directory='\"\"', pattern='*')\n\n'data' is list of LIST responses.", + "builtins.IMAP4.list" => "List mailbox names in directory matching pattern.\n\n(typ, [data]) = .list(directory='', pattern='*')\n\n'data' is list of LIST responses.", "builtins.IMAP4.login" => "Identify client using plaintext password.\n\n(typ, [data]) = .login(user, password)\n\nNB: 'password' will be quoted.", "builtins.IMAP4.login_cram_md5" => "Force use of CRAM-MD5 authentication.\n\n(typ, [data]) = .login_cram_md5(user, password)", "builtins.IMAP4.logout" => "Shutdown connection to server.\n\n(typ, [data]) = .logout()\n\nReturns server 'BYE' response.", - "builtins.IMAP4.lsub" => "List 'subscribed' mailbox names in directory matching pattern.\n\n(typ, [data, ...]) = .lsub(directory='\"\"', pattern='*')\n\n'data' are tuples of message part envelope and data.", + "builtins.IMAP4.lsub" => "List 'subscribed' mailbox names in directory matching pattern.\n\n(typ, [data, ...]) = .lsub(directory='', pattern='*')\n\n'data' are tuples of message part envelope and data.", "builtins.IMAP4.myrights" => "Show my ACLs for a mailbox (i.e. the rights that I have on mailbox).\n\n(typ, [data]) = .myrights(mailbox)", "builtins.IMAP4.namespace" => "Returns IMAP namespaces ala rfc2342\n\n(typ, [data, ...]) = .namespace()", "builtins.IMAP4.noop" => "Send NOOP command.\n\n(typ, [data]) = .noop()", @@ -14561,7 +14558,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.IsADirectoryError.strerror" => "exception strerror", "builtins.IsADirectoryError.winerror" => "Win32 exception code", "builtins.IsADirectoryError.with_traceback" => "Set self.__traceback__ to tb and return self.", - "builtins.Iterable.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.Iterable.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.Iterable.__delattr__" => "Implement delattr(self, name).", "builtins.Iterable.__eq__" => "Return self==value.", "builtins.Iterable.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -14754,7 +14751,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.LZMADecompressor.eof" => "True if the end-of-stream marker has been reached.", "builtins.LZMADecompressor.needs_input" => "True if more input is needed before more decompressed data can be produced.", "builtins.LZMADecompressor.unused_data" => "Data found after the end of the compressed stream.", - "builtins.LibraryLoader.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.LibraryLoader.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.LibraryLoader.__delattr__" => "Implement delattr(self, name).", "builtins.LibraryLoader.__eq__" => "Return self==value.", "builtins.LibraryLoader.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -14871,7 +14868,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.Logcat.__subclasshook__" => "Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented. If it returns\nNotImplemented, the normal algorithm is used. Otherwise, it\noverrides the normal algorithm (and the outcome is cached).", "builtins.Logcat.__weakref__" => "list of weak references to the object", "builtins.LoggerAdapter" => "An adapter for loggers which makes it easier to specify contextual\ninformation in logging output.", - "builtins.LoggerAdapter.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.LoggerAdapter.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.LoggerAdapter.__delattr__" => "Implement delattr(self, name).", "builtins.LoggerAdapter.__eq__" => "Return self==value.", "builtins.LoggerAdapter.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -14951,7 +14948,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.MISSING.__str__" => "Return str(self).", "builtins.MISSING.__subclasshook__" => "Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented. If it returns\nNotImplemented, the normal algorithm is used. Otherwise, it\noverrides the normal algorithm (and the outcome is cached).", "builtins.Mailbox" => "A group of messages in a particular place.", - "builtins.Mailbox.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.Mailbox.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.Mailbox.__contains__" => "Return True if the keyed message exists, False otherwise.", "builtins.Mailbox.__delattr__" => "Implement delattr(self, name).", "builtins.Mailbox.__eq__" => "Return self==value.", @@ -16724,7 +16721,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.PlaceHolder.__weakref__" => "list of weak references to the object", "builtins.PlaceHolder.append" => "Add the specified logger as a child of this placeholder.", "builtins.Popen" => "Execute a child program in a new process.\n\nFor a complete description of the arguments see the Python documentation.\n\nArguments:\n args: A string, or a sequence of program arguments.\n\n bufsize: supplied as the buffering argument to the open() function when\n creating the stdin/stdout/stderr pipe file objects\n\n executable: A replacement program to execute.\n\n stdin, stdout and stderr: These specify the executed programs' standard\n input, standard output and standard error file handles, respectively.\n\n preexec_fn: (POSIX only) An object to be called in the child process\n just before the child is executed.\n\n close_fds: Controls closing or inheriting of file descriptors.\n\n shell: If true, the command will be executed through the shell.\n\n cwd: Sets the current directory before the child is executed.\n\n env: Defines the environment variables for the new process.\n\n text: If true, decode stdin, stdout and stderr using the given encoding\n (if set) or the system default otherwise.\n\n universal_newlines: Alias of text, provided for backwards compatibility.\n\n startupinfo and creationflags (Windows only)\n\n restore_signals (POSIX only)\n\n start_new_session (POSIX only)\n\n process_group (POSIX only)\n\n group (POSIX only)\n\n extra_groups (POSIX only)\n\n user (POSIX only)\n\n umask (POSIX only)\n\n pass_fds (POSIX only)\n\n encoding and errors: Text mode encoding and error handling to use for\n file objects stdin, stdout and stderr.\n\nAttributes:\n stdin, stdout, stderr, pid, returncode", - "builtins.Popen.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.Popen.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.Popen.__delattr__" => "Implement delattr(self, name).", "builtins.Popen.__eq__" => "Return self==value.", "builtins.Popen.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -17160,7 +17157,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.PythonFinalizationError.add_note" => "Add a note to the exception", "builtins.PythonFinalizationError.with_traceback" => "Set self.__traceback__ to tb and return self.", "builtins.Queue" => "Create a queue object with a given maximum size.\n\nIf maxsize is <= 0, the queue size is infinite.", - "builtins.Queue.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.Queue.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.Queue.__delattr__" => "Implement delattr(self, name).", "builtins.Queue.__eq__" => "Return self==value.", "builtins.Queue.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -17270,7 +17267,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.Random.seed" => "seed([n]) -> None.\n\nDefaults to use urandom and falls back to a combination\nof the current time and the process identifier.", "builtins.Random.setstate" => "setstate(state) -> None. Restores generator state.", "builtins.Reader" => "Protocol for simple I/O reader instances.\n\nThis protocol only supports blocking I/O.", - "builtins.Reader.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.Reader.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.Reader.__delattr__" => "Implement delattr(self, name).", "builtins.Reader.__eq__" => "Return self==value.", "builtins.Reader.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -17836,28 +17833,6 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.STARTUPINFO.__str__" => "Return str(self).", "builtins.STARTUPINFO.__subclasshook__" => "Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented. If it returns\nNotImplemented, the normal algorithm is used. Otherwise, it\noverrides the normal algorithm (and the outcome is cached).", "builtins.STARTUPINFO.__weakref__" => "list of weak references to the object", - "builtins.SafeUUID.__delattr__" => "Implement delattr(self, name).", - "builtins.SafeUUID.__eq__" => "Return self==value.", - "builtins.SafeUUID.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", - "builtins.SafeUUID.__ge__" => "Return self>=value.", - "builtins.SafeUUID.__getattribute__" => "Return getattr(self, name).", - "builtins.SafeUUID.__getstate__" => "Helper for pickle.", - "builtins.SafeUUID.__gt__" => "Return self>value.", - "builtins.SafeUUID.__hash__" => "Return hash(self).", - "builtins.SafeUUID.__init__" => "Initialize self. See help(type(self)) for accurate signature.", - "builtins.SafeUUID.__init_subclass__" => "This method is called when a class is subclassed.\n\nThe default implementation does nothing. It may be\noverridden to extend subclasses.", - "builtins.SafeUUID.__le__" => "Return self<=value.", - "builtins.SafeUUID.__lt__" => "Return self "Return self!=value.", - "builtins.SafeUUID.__new__" => "Create and return a new object. See help(type) for accurate signature.", - "builtins.SafeUUID.__reduce__" => "Helper for pickle.", - "builtins.SafeUUID.__reduce_ex__" => "Helper for pickle.", - "builtins.SafeUUID.__repr__" => "Return repr(self).", - "builtins.SafeUUID.__setattr__" => "Implement setattr(self, name, value).", - "builtins.SafeUUID.__sizeof__" => "Size of object in memory, in bytes.", - "builtins.SafeUUID.__str__" => "Return str(self).", - "builtins.SafeUUID.__subclasshook__" => "Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented. If it returns\nNotImplemented, the normal algorithm is used. Otherwise, it\noverrides the normal algorithm (and the outcome is cached).", - "builtins.SafeUUID.__weakref__" => "list of weak references to the object", "builtins.ScandirIterator.__del__" => "Called when the instance is about to be destroyed.", "builtins.ScandirIterator.__delattr__" => "Implement delattr(self, name).", "builtins.ScandirIterator.__eq__" => "Return self==value.", @@ -17971,7 +17946,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.Semaphore.acquire" => "Acquire a semaphore, decrementing the internal counter by one.\n\nWhen invoked without arguments: if the internal counter is larger than\nzero on entry, decrement it by one and return immediately. If it is zero\non entry, block, waiting until some other thread has called release() to\nmake it larger than zero. This is done with proper interlocking so that\nif multiple acquire() calls are blocked, release() will wake exactly one\nof them up. The implementation may pick one at random, so the order in\nwhich blocked threads are awakened should not be relied on. There is no\nreturn value in this case.\n\nWhen invoked with blocking set to true, do the same thing as when called\nwithout arguments, and return true.\n\nWhen invoked with blocking set to false, do not block. If a call without\nan argument would block, return false immediately; otherwise, do the\nsame thing as when called without arguments, and return true.\n\nWhen invoked with a timeout other than None, it will block for at\nmost timeout seconds. If acquire does not complete successfully in\nthat interval, return false. Return true otherwise.", "builtins.Semaphore.release" => "Release a semaphore, incrementing the internal counter by one or more.\n\nWhen the counter is zero on entry and another thread is waiting for it\nto become larger than zero again, wake up that thread.", "builtins.SequenceMatcher" => "SequenceMatcher is a flexible class for comparing pairs of sequences of\nany type, so long as the sequence elements are hashable. The basic\nalgorithm predates, and is a little fancier than, an algorithm\npublished in the late 1980's by Ratcliff and Obershelp under the\nhyperbolic name \"gestalt pattern matching\". The basic idea is to find\nthe longest contiguous matching subsequence that contains no \"junk\"\nelements (R-O doesn't address junk). The same idea is then applied\nrecursively to the pieces of the sequences to the left and to the right\nof the matching subsequence. This does not yield minimal edit\nsequences, but does tend to yield matches that \"look right\" to people.\n\nSequenceMatcher tries to compute a \"human-friendly diff\" between two\nsequences. Unlike e.g. UNIX(tm) diff, the fundamental notion is the\nlongest *contiguous* & junk-free matching subsequence. That's what\ncatches peoples' eyes. The Windows(tm) windiff has another interesting\nnotion, pairing up elements that appear uniquely in each sequence.\nThat, and the method here, appear to yield more intuitive difference\nreports than does diff. This method appears to be the least vulnerable\nto syncing up on blocks of \"junk lines\", though (like blank lines in\nordinary text files, or maybe \"

\" lines in HTML files). That may be\nbecause this is the only method of the 3 that has a *concept* of\n\"junk\" .\n\nExample, comparing two strings, and considering blanks to be \"junk\":\n\n>>> s = SequenceMatcher(lambda x: x == \" \",\n... \"private Thread currentThread;\",\n... \"private volatile Thread currentThread;\")\n>>>\n\n.ratio() returns a float in [0, 1], measuring the \"similarity\" of the\nsequences. As a rule of thumb, a .ratio() value over 0.6 means the\nsequences are close matches:\n\n>>> print(round(s.ratio(), 2))\n0.87\n>>>\n\nIf you're only interested in where the sequences match,\n.get_matching_blocks() is handy:\n\n>>> for block in s.get_matching_blocks():\n... print(\"a[%d] and b[%d] match for %d elements\" % block)\na[0] and b[0] match for 8 elements\na[8] and b[17] match for 21 elements\na[29] and b[38] match for 0 elements\n\nNote that the last tuple returned by .get_matching_blocks() is always a\ndummy, (len(a), len(b), 0), and this is the only case in which the last\ntuple element (number of elements matched) is 0.\n\nIf you want to know how to change the first sequence into the second,\nuse .get_opcodes():\n\n>>> for opcode in s.get_opcodes():\n... print(\"%6s a[%d:%d] b[%d:%d]\" % opcode)\n equal a[0:8] b[0:8]\ninsert a[8:8] b[8:17]\n equal a[8:29] b[17:38]\n\nSee the Differ class for a fancy human-friendly file differencer, which\nuses SequenceMatcher both to compare sequences of lines, and to compare\nsequences of characters within similar (near-matching) lines.\n\nSee also function get_close_matches() in this module, which shows how\nsimple code building on SequenceMatcher can be used to do useful work.\n\nTiming: Basic R-O is cubic time worst case and quadratic time expected\ncase. SequenceMatcher is quadratic time for the worst case and has\nexpected-case behavior dependent in a complicated way on how many\nelements the sequences have in common; best case time is linear.", - "builtins.SequenceMatcher.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.SequenceMatcher.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.SequenceMatcher.__delattr__" => "Implement delattr(self, name).", "builtins.SequenceMatcher.__eq__" => "Return self==value.", "builtins.SequenceMatcher.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -18303,7 +18278,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.Sniffer.__weakref__" => "list of weak references to the object", "builtins.Sniffer._guess_delimiter" => "The delimiter /should/ occur the same number of times on\neach row. However, due to malformed data, it may not. We don't want\nan all or nothing approach, so we allow for small variations in this\nnumber.\n 1) build a table of the frequency of each character on every line.\n 2) build a table of frequencies of this frequency (meta-frequency?),\n e.g. 'x occurred 5 times in 10 rows, 6 times in 1000 rows,\n 7 times in 2 rows'\n 3) use the mode of the meta-frequency to determine the /expected/\n frequency for that character\n 4) find out how often the character actually meets that goal\n 5) the character that best meets its goal is the delimiter\nFor performance reasons, the data is evaluated in chunks, so it can\ntry and evaluate the smallest portion of the data possible, evaluating\nadditional chunks as necessary.", "builtins.Sniffer._guess_quote_and_delimiter" => "Looks for text enclosed between two identical quotes\n(the probable quotechar) which are preceded and followed\nby the same character (the probable delimiter).\nFor example:\n ,'some text',\nThe quote with the most wins, same with the delimiter.\nIf there is no quotechar the delimiter can't be determined\nthis way.", - "builtins.Sniffer.sniff" => "Returns a dialect (or None) corresponding to the sample", + "builtins.Sniffer.sniff" => "Returns a dialect (or None) corresponding to the sample\n\nIf several delimiters fit the sample equally well, the\ndelimiters listed in the preferred attribute are preferred, in\nthat order, no matter how many times each of them occurs.", "builtins.StackObject.__delattr__" => "Implement delattr(self, name).", "builtins.StackObject.__eq__" => "Return self==value.", "builtins.StackObject.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -18613,10 +18588,10 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.Struct.format" => "struct format string", "builtins.Struct.iter_unpack" => "Return an iterator yielding tuples.\n\nTuples are unpacked from the given bytes source, like a repeated\ninvocation of unpack_from().\n\nRequires that the bytes length be a multiple of the struct size.", "builtins.Struct.pack" => "S.pack(v1, v2, ...) -> bytes\n\nReturn a bytes object containing values v1, v2, ... packed according\nto the format string S.format. See help(struct) for more on format\nstrings.", - "builtins.Struct.pack_into" => "S.pack_into(buffer, offset, v1, v2, ...)\n\nPack the values v1, v2, ... according to the format string S.format\nand write the packed bytes into the writable buffer buf starting at\noffset. Note that the offset is a required argument. See\nhelp(struct) for more on format strings.", + "builtins.Struct.pack_into" => "S.pack_into(buffer, offset, v1, v2, ...)\n\nPack the values v1, v2, ... according to the format string S.format\nand write the packed bytes into the writable buffer buf starting at\noffset. Note that the offset is a required argument. A negative\noffset counts from the end of the buffer. See help(struct) for more\non format strings.", "builtins.Struct.size" => "struct size in bytes", "builtins.Struct.unpack" => "Return a tuple containing unpacked values.\n\nUnpack according to the format string Struct.format. The buffer's size\nin bytes must be Struct.size.\n\nSee help(struct) for more on format strings.", - "builtins.Struct.unpack_from" => "Return a tuple containing unpacked values.\n\nValues are unpacked according to the format string Struct.format.\n\nThe buffer's size in bytes, starting at position offset, must be\nat least Struct.size.\n\nSee help(struct) for more on format strings.", + "builtins.Struct.unpack_from" => "Return a tuple containing unpacked values.\n\nValues are unpacked according to the format string Struct.format.\n\nThe buffer's size in bytes, starting at position offset, must be\nat least Struct.size. A negative offset counts from the end of the\nbuffer.\n\nSee help(struct) for more on format strings.", "builtins.StructParam_Type.__delattr__" => "Implement delattr(self, name).", "builtins.StructParam_Type.__eq__" => "Return self==value.", "builtins.StructParam_Type.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -19354,7 +19329,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.TemplateIter.__str__" => "Return str(self).", "builtins.TemplateIter.__subclasshook__" => "Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented. If it returns\nNotImplemented, the normal algorithm is used. Otherwise, it\noverrides the normal algorithm (and the outcome is cached).", "builtins.TemporaryDirectory" => "Create and return a temporary directory. This has the same\nbehavior as mkdtemp but can be used as a context manager. For\nexample:\n\n with TemporaryDirectory() as tmpdir:\n ...\n\nUpon exiting the context, the directory and everything contained\nin it are removed (unless delete=False is passed or an exception\nis raised during cleanup and ignore_cleanup_errors is not True).\n\nOptional Arguments:\n suffix - A str suffix for the directory name. (see mkdtemp)\n prefix - A str prefix for the directory name. (see mkdtemp)\n dir - A directory to create this temp dir in. (see mkdtemp)\n ignore_cleanup_errors - False; ignore exceptions during cleanup?\n delete - True; whether the directory is automatically deleted.", - "builtins.TemporaryDirectory.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.TemporaryDirectory.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.TemporaryDirectory.__delattr__" => "Implement delattr(self, name).", "builtins.TemporaryDirectory.__eq__" => "Return self==value.", "builtins.TemporaryDirectory.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -19890,7 +19865,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.TokenizerIter.__str__" => "Return str(self).", "builtins.TokenizerIter.__subclasshook__" => "Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented. If it returns\nNotImplemented, the normal algorithm is used. Otherwise, it\noverrides the normal algorithm (and the outcome is cached).", "builtins.TopologicalSorter" => "Provides functionality to topologically sort a graph of hashable nodes", - "builtins.TopologicalSorter.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.TopologicalSorter.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.TopologicalSorter.__delattr__" => "Implement delattr(self, name).", "builtins.TopologicalSorter.__eq__" => "Return self==value.", "builtins.TopologicalSorter.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -20726,7 +20701,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.Wave_write.__str__" => "Return str(self).", "builtins.Wave_write.__subclasshook__" => "Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented. If it returns\nNotImplemented, the normal algorithm is used. Otherwise, it\noverrides the normal algorithm (and the outcome is cached).", "builtins.Wave_write.__weakref__" => "list of weak references to the object", - "builtins.WeakSet.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.WeakSet.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.WeakSet.__delattr__" => "Implement delattr(self, name).", "builtins.WeakSet.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", "builtins.WeakSet.__getattribute__" => "Return getattr(self, name).", @@ -20852,7 +20827,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.Wm.iconmask" => "Set mask for the icon bitmap of this widget. Return the\nmask if None is given.", "builtins.Wm.iconname" => "Set the name of the icon for this widget. Return the name if\nNone is given.", "builtins.Wm.iconphoto" => "Sets the titlebar icon for this window based on the named photo\nimages passed through args. If default is True, this is applied to\nall future created toplevels as well.\n\nThe data in the images is taken as a snapshot at the time of\ninvocation. If the images are later changed, this is not reflected\nto the titlebar icons. Multiple images are accepted to allow\ndifferent images sizes to be provided. The window manager may scale\nprovided icons to an appropriate size.\n\nOn Windows, the images are packed into a Windows icon structure.\nThis will override an icon specified to wm_iconbitmap, and vice\nversa.\n\nOn X, the images are arranged into the _NET_WM_ICON X property,\nwhich most modern window managers support. An icon specified by\nwm_iconbitmap may exist simultaneously.\n\nOn Macintosh, this currently does nothing.", - "builtins.Wm.iconposition" => "Set the position of the icon of this widget to X and Y. Return\na tuple of the current values of X and X if None is given.", + "builtins.Wm.iconposition" => "Set the position of the icon of this widget to X and Y. Return\na tuple of the current values of X and Y if None is given.", "builtins.Wm.iconwindow" => "Set widget PATHNAME to be displayed instead of icon. Return the current\nvalue if None is given.", "builtins.Wm.manage" => "The widget specified will become a stand alone top-level window.\nThe window will be decorated with the window managers title bar,\netc.", "builtins.Wm.maxsize" => "Set max WIDTH and HEIGHT for this widget. If the window is gridded\nthe values are given in grid units. Return the current values if None\nis given.", @@ -20883,7 +20858,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.Wm.wm_iconmask" => "Set mask for the icon bitmap of this widget. Return the\nmask if None is given.", "builtins.Wm.wm_iconname" => "Set the name of the icon for this widget. Return the name if\nNone is given.", "builtins.Wm.wm_iconphoto" => "Sets the titlebar icon for this window based on the named photo\nimages passed through args. If default is True, this is applied to\nall future created toplevels as well.\n\nThe data in the images is taken as a snapshot at the time of\ninvocation. If the images are later changed, this is not reflected\nto the titlebar icons. Multiple images are accepted to allow\ndifferent images sizes to be provided. The window manager may scale\nprovided icons to an appropriate size.\n\nOn Windows, the images are packed into a Windows icon structure.\nThis will override an icon specified to wm_iconbitmap, and vice\nversa.\n\nOn X, the images are arranged into the _NET_WM_ICON X property,\nwhich most modern window managers support. An icon specified by\nwm_iconbitmap may exist simultaneously.\n\nOn Macintosh, this currently does nothing.", - "builtins.Wm.wm_iconposition" => "Set the position of the icon of this widget to X and Y. Return\na tuple of the current values of X and X if None is given.", + "builtins.Wm.wm_iconposition" => "Set the position of the icon of this widget to X and Y. Return\na tuple of the current values of X and Y if None is given.", "builtins.Wm.wm_iconwindow" => "Set widget PATHNAME to be displayed instead of icon. Return the current\nvalue if None is given.", "builtins.Wm.wm_manage" => "The widget specified will become a stand alone top-level window.\nThe window will be decorated with the window managers title bar,\netc.", "builtins.Wm.wm_maxsize" => "Set max WIDTH and HEIGHT for this widget. If the window is gridded\nthe values are given in grid units. Return the current values if None\nis given.", @@ -20898,7 +20873,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.Wm.wm_transient" => "Instruct the window manager that this widget is transient\nwith regard to widget MASTER.", "builtins.Wm.wm_withdraw" => "Withdraw this widget from the screen such that it is unmapped\nand forgotten by the window manager. Re-draw it with wm_deiconify.", "builtins.Writer" => "Protocol for simple I/O writer instances.\n\nThis protocol only supports blocking I/O.", - "builtins.Writer.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.Writer.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.Writer.__delattr__" => "Implement delattr(self, name).", "builtins.Writer.__eq__" => "Return self==value.", "builtins.Writer.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -22700,7 +22675,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins._NamespacePath.__weakref__" => "list of weak references to the object", "builtins._NamespacePath._find_parent_path_names" => "Returns a tuple of (parent-module-name, parent-path-attr-name)", "builtins._NetlocResultMixinBase" => "Shared methods for the parsed result objects containing a netloc element", - "builtins._NetlocResultMixinBase.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins._NetlocResultMixinBase.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins._NetlocResultMixinBase.__delattr__" => "Implement delattr(self, name).", "builtins._NetlocResultMixinBase.__eq__" => "Return self==value.", "builtins._NetlocResultMixinBase.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -23079,7 +23054,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins._Processor.__weakref__" => "list of weak references to the object", "builtins._Processor.from_subprocess" => "Fall back to `uname -p`", "builtins._ProxyFile" => "A read-only wrapper of a file.", - "builtins._ProxyFile.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins._ProxyFile.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins._ProxyFile.__delattr__" => "Implement delattr(self, name).", "builtins._ProxyFile.__enter__" => "Context management protocol support.", "builtins._ProxyFile.__eq__" => "Return self==value.", @@ -23113,7 +23088,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins._ProxyFile.seek" => "Change position.", "builtins._ProxyFile.tell" => "Return the position.", "builtins._PySimpleQueue" => "Simple, unbounded FIFO queue.\n\nThis pure Python implementation is not reentrant.", - "builtins._PySimpleQueue.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins._PySimpleQueue.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins._PySimpleQueue.__delattr__" => "Implement delattr(self, name).", "builtins._PySimpleQueue.__eq__" => "Return self==value.", "builtins._PySimpleQueue.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -25289,7 +25264,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.bytes_iterator.__sizeof__" => "Size of object in memory, in bytes.", "builtins.bytes_iterator.__str__" => "Return str(self).", "builtins.bytes_iterator.__subclasshook__" => "Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented. If it returns\nNotImplemented, the normal algorithm is used. Otherwise, it\noverrides the normal algorithm (and the outcome is cached).", - "builtins.cached_property.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.cached_property.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.cached_property.__delattr__" => "Implement delattr(self, name).", "builtins.cached_property.__eq__" => "Return self==value.", "builtins.cached_property.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -26145,7 +26120,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.different_locale.__weakref__" => "list of weak references to the object", "builtins.dir" => "dir([object]) -> list of strings\n\nIf called without an argument, return the names in the current scope.\nElse, return an alphabetized list of names comprising (some of) the\nattributes of the given object, and of attributes reachable from it.\nIf the object supplies a method named __dir__, it will be used;\notherwise the default dir() logic is used and returns:\n for a module object: the module's attributes.\n for a class object: its attributes, and recursively the attributes\n of its bases.\n for any other object: its attributes, its class's attributes, and\n recursively the attributes of its class's base classes.", "builtins.dircmp" => "A class that manages the comparison of 2 directories.\n\ndircmp(a, b, ignore=None, hide=None, *, shallow=True)\n A and B are directories.\n IGNORE is a list of names to ignore,\n defaults to DEFAULT_IGNORES.\n HIDE is a list of names to hide,\n defaults to [os.curdir, os.pardir].\n SHALLOW specifies whether to just check the stat signature (do not read\n the files).\n defaults to True.\n\nHigh level usage:\n x = dircmp(dir1, dir2)\n x.report() -> prints a report on the differences between dir1 and dir2\n or\n x.report_partial_closure() -> prints report on differences between dir1\n and dir2, and reports on common immediate subdirectories.\n x.report_full_closure() -> like report_partial_closure,\n but fully recursive.\n\nAttributes:\n left_list, right_list: The files in dir1 and dir2,\n filtered by hide and ignore.\n common: a list of names in both dir1 and dir2.\n left_only, right_only: names only in dir1, dir2.\n common_dirs: subdirectories in both dir1 and dir2.\n common_files: files in both dir1 and dir2.\n common_funny: names in both dir1 and dir2 where the type differs between\n dir1 and dir2, or the name is not stat-able.\n same_files: list of identical files.\n diff_files: list of filenames which differ.\n funny_files: list of files which could not be compared.\n subdirs: a dictionary of dircmp instances (or MyDirCmp instances if this\n object is of type MyDirCmp, a subclass of dircmp), keyed by names\n in common_dirs.", - "builtins.dircmp.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.dircmp.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.dircmp.__delattr__" => "Implement delattr(self, name).", "builtins.dircmp.__eq__" => "Return self==value.", "builtins.dircmp.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -27853,7 +27828,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.panel.move" => "Move the panel to the screen coordinates (y, x).", "builtins.panel.replace" => "Change the window associated with the panel to the window win.", "builtins.panel.set_userptr" => "Set the panel's user pointer to obj.", - "builtins.panel.show" => "Display the panel (which might have been hidden).", + "builtins.panel.show" => "Display the panel (which might have been hidden).\n\nThe panel is placed on top of the panel stack.", "builtins.panel.top" => "Push panel to the top of the stack.", "builtins.panel.userptr" => "Return the user pointer for the panel.", "builtins.panel.window" => "Return the window object associated with the panel.", @@ -27885,7 +27860,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.partial.func" => "function object to use in future partial calls", "builtins.partial.keywords" => "dictionary of keyword arguments to future partial calls", "builtins.partialmethod" => "Method descriptor with partial application of the given arguments\nand keywords.\n\nSupports wrapping existing descriptors and handles non-descriptor\ncallables as instance methods.", - "builtins.partialmethod.__class_getitem__" => "Represent a PEP 585 generic type\n\nE.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + "builtins.partialmethod.__class_getitem__" => "Represent a PEP 585 generic type\n\nFor example, for t = list[int], t.__origin__ is list and t.__args__\nis (int,).", "builtins.partialmethod.__delattr__" => "Implement delattr(self, name).", "builtins.partialmethod.__eq__" => "Return self==value.", "builtins.partialmethod.__format__" => "Default object formatter.\n\nReturn str(self) if format_spec is empty. Raise TypeError otherwise.", @@ -29004,7 +28979,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.traceback.__subclasshook__" => "Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented. If it returns\nNotImplemented, the normal algorithm is used. Otherwise, it\noverrides the normal algorithm (and the outcome is cached).", "builtins.tuple" => "Built-in immutable sequence.\n\nIf no argument is given, the constructor returns an empty tuple.\nIf iterable is specified the tuple is initialized from iterable's items.\n\nIf the argument is a tuple, the return value is the same object.", "builtins.tuple.__add__" => "Return self+value.", - "builtins.tuple.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "builtins.tuple.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "builtins.tuple.__contains__" => "Return bool(key in self).", "builtins.tuple.__delattr__" => "Implement delattr(self, name).", "builtins.tuple.__eq__" => "Return self==value.", @@ -29262,34 +29237,69 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "builtins.window.border" => "Draw a border around the edges of the window.\n\n ls\n Left side.\n rs\n Right side.\n ts\n Top side.\n bs\n Bottom side.\n tl\n Upper-left corner.\n tr\n Upper-right corner.\n bl\n Bottom-left corner.\n br\n Bottom-right corner.\n\nEach parameter specifies the character to use for a specific part of\nthe border. The characters can be specified as integers or as\none-character strings. A 0 value for any parameter will cause the\ndefault character to be used for that parameter.", "builtins.window.box" => "box([verch=0, horch=0])\nDraw a border around the edges of the window.\n\n verch\n Left and right side.\n horch\n Top and bottom side.\n\nSimilar to border(), but both ls and rs are verch and both ts and bs\nare horch. The default corner characters are always used by this\nfunction.", "builtins.window.chgat" => "chgat([y, x,] [n=-1,] attr)\nSet the attributes of characters.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n n\n Number of characters.\n attr\n Attributes for characters.\n\nSet the attributes of num characters at the current cursor position, or at\nposition (y, x) if supplied. If no value of num is given or num = -1, the\nattribute will be set on all the characters to the end of the line. This\nfunction does not move the cursor. The changed line will be touched using\nthe touchline() method so that the contents will be redisplayed by the next\nwindow refresh.", - "builtins.window.delch" => "delch([y, x])\nDelete any character at (y, x).\n\n y\n Y-coordinate.\n x\n X-coordinate.", + "builtins.window.clear" => "Clear the window and repaint it completely on the next refresh().", + "builtins.window.clearok" => "Clear the window on the next refresh() if flag is true.", + "builtins.window.clrtobot" => "Erase from the cursor to the end of the window.", + "builtins.window.clrtoeol" => "Erase from the cursor to the end of the line.", + "builtins.window.cursyncup" => "Update the cursor position of all ancestor windows to match.", + "builtins.window.delch" => "delch([y, x])\nDelete the character under the cursor, or at (y, x) if specified.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n\nAll characters to the right on the same line are shifted one\nposition left.", + "builtins.window.deleteln" => "Delete the line under the cursor; move following lines up by one.", "builtins.window.derwin" => "derwin([nlines=0, ncols=0,] begin_y, begin_x)\nCreate a sub-window (window-relative coordinates).\n\n nlines\n Height.\n ncols\n Width.\n begin_y\n Top side y-coordinate.\n begin_x\n Left side x-coordinate.\n\nderwin() is the same as calling subwin(), except that begin_y and\nbegin_x are relative to the origin of the window, rather than\nrelative to the entire screen.", "builtins.window.echochar" => "Add character ch with attribute attr, and refresh.\n\n ch\n Character to add.\n attr\n Attributes for the character.", "builtins.window.enclose" => "Return True if the screen-relative coordinates are enclosed by the window.\n\n y\n Y-coordinate.\n x\n X-coordinate.", "builtins.window.encoding" => "the typecode character used to create the array", + "builtins.window.erase" => "Clear the window.", "builtins.window.get_wch" => "get_wch([y, x])\nGet a wide character from terminal keyboard.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n\nReturn a character for most keys, or an integer for function keys,\nkeypad keys, and other special keys.", + "builtins.window.getbegyx" => "Return a tuple (y, x) of the upper-left corner coordinates.", "builtins.window.getbkgd" => "Return the window's current background character/attribute pair.", "builtins.window.getch" => "getch([y, x])\nGet a character code from terminal keyboard.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n\nThe integer returned does not have to be in ASCII range: function\nkeys, keypad keys and so on return numbers higher than 256. In\nno-delay mode, -1 is returned if there is no input, else getch()\nwaits until a key is pressed.", "builtins.window.getkey" => "getkey([y, x])\nGet a character (string) from terminal keyboard.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n\nReturning a string instead of an integer, as getch() does. Function\nkeys, keypad keys and other special keys return a multibyte string\ncontaining the key name. In no-delay mode, an exception is raised\nif there is no input.", + "builtins.window.getmaxyx" => "Return a tuple (y, x) of the window height and width.", + "builtins.window.getparyx" => "Return (y, x) relative to the parent window, or (-1, -1) if none.", "builtins.window.getstr" => "getstr([[y, x,] n=2047])\nRead a string from the user, with primitive line editing capacity.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n n\n Maximal number of characters.", + "builtins.window.getyx" => "Return a tuple (y, x) of the current cursor position.", "builtins.window.hline" => "hline([y, x,] ch, n, [attr=_curses.A_NORMAL])\nDisplay a horizontal line.\n\n y\n Starting Y-coordinate.\n x\n Starting X-coordinate.\n ch\n Character to draw.\n n\n Line length.\n attr\n Attributes for the characters.", + "builtins.window.idcok" => "Enable or disable the hardware insert/delete character feature.", + "builtins.window.idlok" => "Enable or disable the hardware insert/delete line feature.", + "builtins.window.immedok" => "If flag is true, refresh the window on every change to it.", "builtins.window.inch" => "inch([y, x])\nReturn the character at the given position in the window.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n\nThe bottom 8 bits are the character proper, and upper bits are the\nattributes.", "builtins.window.insch" => "insch([y, x,] ch, [attr=_curses.A_NORMAL])\nInsert a character before the current or specified position.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n ch\n Character to insert.\n attr\n Attributes for the character.\n\nAll characters to the right of the cursor are shifted one position\nright, with the rightmost characters on the line being lost.", + "builtins.window.insdelln" => "Insert (nlines > 0) or delete (nlines < 0) lines above the cursor.", + "builtins.window.insertln" => "Insert a blank line under the cursor; move following lines down.", "builtins.window.insnstr" => "insnstr([y, x,] str, n, [attr])\nInsert at most n characters of the string.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n str\n String to insert.\n n\n Maximal number of characters.\n attr\n Attributes for characters.\n\nInsert a character string (as many characters as will fit on the\nline) before the character under the cursor, up to n characters. If\nn is zero or negative, the entire string is inserted. All\ncharacters to the right of the cursor are shifted right, with the\nrightmost characters on the line being lost. The cursor position\ndoes not change (after moving to y, x, if specified).", "builtins.window.insstr" => "insstr([y, x,] str, [attr])\nInsert the string before the current or specified position.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n str\n String to insert.\n attr\n Attributes for characters.\n\nInsert a character string (as many characters as will fit on the\nline) before the character under the cursor. All characters to the\nright of the cursor are shifted right, with the rightmost characters\non the line being lost. The cursor position does not change (after\nmoving to y, x, if specified).", - "builtins.window.instr" => "instr([y, x,] n=2047)\nReturn a string of characters, extracted from the window.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n n\n Maximal number of characters.\n\nReturn a string of characters, extracted from the window starting at the\ncurrent cursor position, or at y, x if specified. Attributes are stripped\nfrom the characters. If n is specified, instr() returns a string at most\nn characters long (exclusive of the trailing NUL).", + "builtins.window.instr" => "instr([y, x,] n=2047)\nReturn a string of characters, extracted from the window.\n\n y\n Y-coordinate.\n x\n X-coordinate.\n n\n Maximal number of characters.\n\nReturn a string of characters, extracted from the window starting\nat the current cursor position, or at y, x if specified, and\nstopping at the end of the line. Attributes and color\ninformation are stripped from the characters. If n is specified,\ninstr() returns a string at most n characters long (exclusive of\nthe trailing NUL).", "builtins.window.is_linetouched" => "Return True if the specified line was modified, otherwise return False.\n\n line\n Line number.\n\nRaise a curses.error exception if line is not valid for the given\nwindow.", + "builtins.window.is_wintouched" => "Return True if the window changed since the last refresh().", + "builtins.window.keypad" => "Interpret escape sequences for special keys if flag is true.", + "builtins.window.leaveok" => "If flag is true, leave the cursor where the update leaves it.", + "builtins.window.move" => "Move the cursor to (new_y, new_x).", + "builtins.window.mvderwin" => "Move the window inside its parent window.", + "builtins.window.mvwin" => "Move the window so its upper-left corner is at (new_y, new_x).", + "builtins.window.nodelay" => "If flag is true, getch() becomes non-blocking.", + "builtins.window.notimeout" => "If flag is true, do not time out escape sequences.", "builtins.window.noutrefresh" => "noutrefresh([pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol])\nMark for refresh but wait.\n\nThis function updates the data structure representing the desired\nstate of the window, but does not force an update of the physical\nscreen. To accomplish that, call doupdate().", "builtins.window.overlay" => "overlay(destwin, [sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol])\nOverlay the window on top of destwin.\n\nThe windows need not be the same size, only the overlapping region\nis copied. This copy is non-destructive, which means that the\ncurrent background character does not overwrite the old contents of\ndestwin.\n\nTo get fine-grained control over the copied region, the second form\nof overlay() can be used. sminrow and smincol are the upper-left\ncoordinates of the source window, and the other variables mark\na rectangle in the destination window.", "builtins.window.overwrite" => "overwrite(destwin, [sminrow, smincol, dminrow, dmincol, dmaxrow,\n dmaxcol])\nOverwrite the window on top of destwin.\n\nThe windows need not be the same size, in which case only the\noverlapping region is copied. This copy is destructive, which means\nthat the current background character overwrites the old contents of\ndestwin.\n\nTo get fine-grained control over the copied region, the second form\nof overwrite() can be used. sminrow and smincol are the upper-left\ncoordinates of the source window, the other variables mark\na rectangle in the destination window.", "builtins.window.putwin" => "Write all data associated with the window into the provided file object.\n\nThis information can be later retrieved using the getwin() function.", "builtins.window.redrawln" => "Mark the specified lines corrupted.\n\n beg\n Starting line number.\n num\n The number of lines.\n\nThey should be completely redrawn on the next refresh() call.", + "builtins.window.redrawwin" => "Mark the entire window for redraw on the next refresh().", "builtins.window.refresh" => "refresh([pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol])\nUpdate the display immediately.\n\nSynchronize actual screen with previous drawing/deleting methods.\nThe 6 optional arguments can only be specified when the window is\na pad created with newpad(). The additional parameters are needed\nto indicate what part of the pad and screen are involved. pminrow\nand pmincol specify the upper left-hand corner of the rectangle to\nbe displayed in the pad. sminrow, smincol, smaxrow, and smaxcol\nspecify the edges of the rectangle to be displayed on the screen.\nThe lower right-hand corner of the rectangle to be displayed in the\npad is calculated from the screen coordinates, since the rectangles\nmust be the same size. Both rectangles must be entirely contained\nwithin their respective structures. Negative values of pminrow,\npmincol, sminrow, or smincol are treated as if they were zero.", + "builtins.window.resize" => "Resize the window to nlines rows and ncols columns.", "builtins.window.scroll" => "scroll([lines=1])\nScroll the screen or scrolling region.\n\n lines\n Number of lines to scroll.\n\nScroll upward if the argument is positive and downward if it is\nnegative.", + "builtins.window.scrollok" => "Control whether the window scrolls when the cursor moves off it.", "builtins.window.setscrreg" => "Define a software scrolling region.\n\n top\n First line number.\n bottom\n Last line number.\n\nAll scrolling actions will take place in this region.", + "builtins.window.standend" => "Turn off the standout attribute.", + "builtins.window.standout" => "Turn on the A_STANDOUT attribute.", "builtins.window.subpad" => "subwin([nlines=0, ncols=0,] begin_y, begin_x)\nCreate a sub-window (screen-relative coordinates).\n\n nlines\n Height.\n ncols\n Width.\n begin_y\n Top side y-coordinate.\n begin_x\n Left side x-coordinate.\n\nBy default, the sub-window will extend from the specified position\nto the lower right corner of the window.", "builtins.window.subwin" => "subwin([nlines=0, ncols=0,] begin_y, begin_x)\nCreate a sub-window (screen-relative coordinates).\n\n nlines\n Height.\n ncols\n Width.\n begin_y\n Top side y-coordinate.\n begin_x\n Left side x-coordinate.\n\nBy default, the sub-window will extend from the specified position\nto the lower right corner of the window.", + "builtins.window.syncdown" => "Touch each location changed in any ancestor of the window.", + "builtins.window.syncok" => "If flag is true, call syncup() on every change to the window.", + "builtins.window.syncup" => "Touch locations in ancestors that changed in this window.", + "builtins.window.timeout" => "Set blocking or non-blocking read behavior for the window.", "builtins.window.touchline" => "touchline(start, count, [changed=True])\nPretend count lines have been changed, starting with line start.\n\nIf changed is supplied, it specifies whether the affected lines are\nmarked as having been changed (changed=True) or unchanged\n(changed=False).", + "builtins.window.touchwin" => "Mark the whole window as changed.", + "builtins.window.untouchwin" => "Mark all lines in the window as unchanged since last refresh().", "builtins.window.vline" => "vline([y, x,] ch, n, [attr=_curses.A_NORMAL])\nDisplay a vertical line.\n\n y\n Starting Y-coordinate.\n x\n Starting X-coordinate.\n ch\n Character to draw.\n n\n Line length.\n attr\n Attributes for the character.", "builtins.wrapper_descriptor.__call__" => "Call self as a function.", "builtins.wrapper_descriptor.__delattr__" => "Implement delattr(self, name).", @@ -29494,7 +29504,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "grp.getgrnam" => "Return the group database entry for the given group name.\n\nIf name is not valid, raise KeyError.", "grp.struct_group" => "grp.struct_group: Results from getgr*() routines.\n\nThis object may be accessed either as a tuple of\n (gr_name,gr_passwd,gr_gid,gr_mem)\nor via the object attributes as named in the above tuple.", "grp.struct_group.__add__" => "Return self+value.", - "grp.struct_group.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "grp.struct_group.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "grp.struct_group.__contains__" => "Return bool(key in self).", "grp.struct_group.__delattr__" => "Implement delattr(self, name).", "grp.struct_group.__eq__" => "Return self==value.", @@ -30276,7 +30286,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "nt.stat" => "Perform a stat system call on the given path.\n\n path\n Path to be examined; can be string, bytes, a path-like object or\n open-file-descriptor int.\n dir_fd\n If not None, it should be a file descriptor open to a directory,\n and path should be a relative string; path will then be relative to\n that directory.\n follow_symlinks\n If False, and the last element of the path is a symbolic link,\n stat will examine the symbolic link itself instead of the file\n the link points to.\n\ndir_fd and follow_symlinks may not be implemented\n on your platform. If they are unavailable, using them will raise a\n NotImplementedError.\n\nIt's an error to use dir_fd or follow_symlinks when specifying path as\n an open file descriptor.", "nt.stat_result" => "stat_result: Result from stat, fstat, or lstat.\n\nThis object may be accessed either as a tuple of\n (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\nor via the attributes st_mode, st_ino, st_dev, st_nlink, and so on.\n\nPosix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\nor st_flags, they are available as attributes only.\n\nSee os.stat for more information.", "nt.stat_result.__add__" => "Return self+value.", - "nt.stat_result.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "nt.stat_result.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "nt.stat_result.__contains__" => "Return bool(key in self).", "nt.stat_result.__delattr__" => "Implement delattr(self, name).", "nt.stat_result.__eq__" => "Return self==value.", @@ -30325,7 +30335,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "nt.stat_result.st_uid" => "user ID of owner", "nt.statvfs_result" => "statvfs_result: Result from statvfs or fstatvfs.\n\nThis object may be accessed either as a tuple of\n (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\nor via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\nSee os.statvfs for more information.", "nt.statvfs_result.__add__" => "Return self+value.", - "nt.statvfs_result.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "nt.statvfs_result.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "nt.statvfs_result.__contains__" => "Return bool(key in self).", "nt.statvfs_result.__delattr__" => "Implement delattr(self, name).", "nt.statvfs_result.__eq__" => "Return self==value.", @@ -30360,7 +30370,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "nt.system" => "Execute the command in a subshell.", "nt.terminal_size" => "A tuple of (columns, lines) for holding terminal window size", "nt.terminal_size.__add__" => "Return self+value.", - "nt.terminal_size.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "nt.terminal_size.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "nt.terminal_size.__contains__" => "Return bool(key in self).", "nt.terminal_size.__delattr__" => "Implement delattr(self, name).", "nt.terminal_size.__eq__" => "Return self==value.", @@ -30395,7 +30405,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "nt.times" => "Return a collection containing process timing information.\n\nThe object returned behaves like a named tuple with these fields:\n (utime, stime, cutime, cstime, elapsed_time)\nAll fields are floating-point numbers.", "nt.times_result" => "times_result: Result from os.times().\n\nThis object may be accessed either as a tuple of\n (user, system, children_user, children_system, elapsed),\nor via the attributes user, system, children_user, children_system,\nand elapsed.\n\nSee os.times for more information.", "nt.times_result.__add__" => "Return self+value.", - "nt.times_result.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "nt.times_result.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "nt.times_result.__contains__" => "Return bool(key in self).", "nt.times_result.__delattr__" => "Implement delattr(self, name).", "nt.times_result.__eq__" => "Return self==value.", @@ -30434,7 +30444,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "nt.umask" => "Set the current numeric umask and return the previous umask.", "nt.uname_result" => "uname_result: Result from os.uname().\n\nThis object may be accessed either as a tuple of\n (sysname, nodename, release, version, machine),\nor via the attributes sysname, nodename, release, version, and machine.\n\nSee os.uname for more information.", "nt.uname_result.__add__" => "Return self+value.", - "nt.uname_result.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "nt.uname_result.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "nt.uname_result.__contains__" => "Return bool(key in self).", "nt.uname_result.__delattr__" => "Implement delattr(self, name).", "nt.uname_result.__eq__" => "Return self==value.", @@ -30636,7 +30646,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "posix.sched_getscheduler" => "Get the scheduling policy for the process identified by pid.\n\nPassing 0 for pid returns the scheduling policy for the calling process.", "posix.sched_param" => "Currently has only one field: sched_priority\n\n sched_priority\n A scheduling parameter.", "posix.sched_param.__add__" => "Return self+value.", - "posix.sched_param.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "posix.sched_param.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "posix.sched_param.__contains__" => "Return bool(key in self).", "posix.sched_param.__delattr__" => "Implement delattr(self, name).", "posix.sched_param.__eq__" => "Return self==value.", @@ -30694,7 +30704,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "posix.stat" => "Perform a stat system call on the given path.\n\n path\n Path to be examined; can be string, bytes, a path-like object or\n open-file-descriptor int.\n dir_fd\n If not None, it should be a file descriptor open to a directory,\n and path should be a relative string; path will then be relative to\n that directory.\n follow_symlinks\n If False, and the last element of the path is a symbolic link,\n stat will examine the symbolic link itself instead of the file\n the link points to.\n\ndir_fd and follow_symlinks may not be implemented\n on your platform. If they are unavailable, using them will raise a\n NotImplementedError.\n\nIt's an error to use dir_fd or follow_symlinks when specifying path as\n an open file descriptor.", "posix.stat_result" => "stat_result: Result from stat, fstat, or lstat.\n\nThis object may be accessed either as a tuple of\n (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\nor via the attributes st_mode, st_ino, st_dev, st_nlink, and so on.\n\nPosix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\nor st_flags, they are available as attributes only.\n\nSee os.stat for more information.", "posix.stat_result.__add__" => "Return self+value.", - "posix.stat_result.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "posix.stat_result.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "posix.stat_result.__contains__" => "Return bool(key in self).", "posix.stat_result.__delattr__" => "Implement delattr(self, name).", "posix.stat_result.__eq__" => "Return self==value.", @@ -30746,7 +30756,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "posix.statvfs" => "Perform a statvfs system call on the given path.\n\npath may always be specified as a string.\nOn some platforms, path may also be specified as an open file\ndescriptor. If this functionality is unavailable, using it raises\nan exception.", "posix.statvfs_result" => "statvfs_result: Result from statvfs or fstatvfs.\n\nThis object may be accessed either as a tuple of\n (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\nor via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\nSee os.statvfs for more information.", "posix.statvfs_result.__add__" => "Return self+value.", - "posix.statvfs_result.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "posix.statvfs_result.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "posix.statvfs_result.__contains__" => "Return bool(key in self).", "posix.statvfs_result.__delattr__" => "Implement delattr(self, name).", "posix.statvfs_result.__eq__" => "Return self==value.", @@ -30785,7 +30795,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "posix.tcsetpgrp" => "Set the process group associated with the terminal specified by fd.", "posix.terminal_size" => "A tuple of (columns, lines) for holding terminal window size", "posix.terminal_size.__add__" => "Return self+value.", - "posix.terminal_size.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "posix.terminal_size.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "posix.terminal_size.__contains__" => "Return bool(key in self).", "posix.terminal_size.__delattr__" => "Implement delattr(self, name).", "posix.terminal_size.__eq__" => "Return self==value.", @@ -30825,7 +30835,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "posix.times" => "Return a collection containing process timing information.\n\nThe object returned behaves like a named tuple with these fields:\n (utime, stime, cutime, cstime, elapsed_time)\nAll fields are floating-point numbers.", "posix.times_result" => "times_result: Result from os.times().\n\nThis object may be accessed either as a tuple of\n (user, system, children_user, children_system, elapsed),\nor via the attributes user, system, children_user, children_system,\nand elapsed.\n\nSee os.times for more information.", "posix.times_result.__add__" => "Return self+value.", - "posix.times_result.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "posix.times_result.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "posix.times_result.__contains__" => "Return bool(key in self).", "posix.times_result.__delattr__" => "Implement delattr(self, name).", "posix.times_result.__eq__" => "Return self==value.", @@ -30866,7 +30876,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "posix.uname" => "Return an object identifying the current operating system.\n\nThe object behaves like a named tuple with the following fields:\n (sysname, nodename, release, version, machine)", "posix.uname_result" => "uname_result: Result from os.uname().\n\nThis object may be accessed either as a tuple of\n (sysname, nodename, release, version, machine),\nor via the attributes sysname, nodename, release, version, and machine.\n\nSee os.uname for more information.", "posix.uname_result.__add__" => "Return self+value.", - "posix.uname_result.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "posix.uname_result.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "posix.uname_result.__contains__" => "Return bool(key in self).", "posix.uname_result.__delattr__" => "Implement delattr(self, name).", "posix.uname_result.__eq__" => "Return self==value.", @@ -30913,7 +30923,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "posix.waitid" => "Returns the result of waiting for a process or processes.\n\n idtype\n Must be one of be P_PID, P_PGID or P_ALL.\n id\n The id to wait on.\n options\n Constructed from the ORing of one or more of WEXITED, WSTOPPED\n or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\nReturns either waitid_result or None if WNOHANG is specified and there\nare no children in a waitable state.", "posix.waitid_result" => "waitid_result: Result from waitid.\n\nThis object may be accessed either as a tuple of\n (si_pid, si_uid, si_signo, si_status, si_code),\nor via the attributes si_pid, si_uid, and so on.\n\nSee os.waitid for more information.", "posix.waitid_result.__add__" => "Return self+value.", - "posix.waitid_result.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "posix.waitid_result.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "posix.waitid_result.__contains__" => "Return bool(key in self).", "posix.waitid_result.__delattr__" => "Implement delattr(self, name).", "posix.waitid_result.__eq__" => "Return self==value.", @@ -30953,7 +30963,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "pwd.getpwuid" => "Return the password database entry for the given numeric user ID.\n\nSee `help(pwd)` for more on password database entries.", "pwd.struct_passwd" => "pwd.struct_passwd: Results from getpw*() routines.\n\nThis object may be accessed either as a tuple of\n (pw_name,pw_passwd,pw_uid,pw_gid,pw_gecos,pw_dir,pw_shell)\nor via the object attributes as named in the above tuple.", "pwd.struct_passwd.__add__" => "Return self+value.", - "pwd.struct_passwd.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "pwd.struct_passwd.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "pwd.struct_passwd.__contains__" => "Return bool(key in self).", "pwd.struct_passwd.__delattr__" => "Implement delattr(self, name).", "pwd.struct_passwd.__eq__" => "Return self==value.", @@ -31105,7 +31115,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "readline.write_history_file" => "Save a readline history file.\n\nThe default filename is ~/.history.", "resource.struct_rusage" => "struct_rusage: Result from getrusage.\n\nThis object may be accessed either as a tuple of\n (utime,stime,maxrss,ixrss,idrss,isrss,minflt,majflt,\n nswap,inblock,oublock,msgsnd,msgrcv,nsignals,nvcsw,nivcsw)\nor via the attributes ru_utime, ru_stime, ru_maxrss, and so on.", "resource.struct_rusage.__add__" => "Return self+value.", - "resource.struct_rusage.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "resource.struct_rusage.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "resource.struct_rusage.__contains__" => "Return bool(key in self).", "resource.struct_rusage.__delattr__" => "Implement delattr(self, name).", "resource.struct_rusage.__eq__" => "Return self==value.", @@ -31358,7 +31368,7 @@ pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! { "time.strptime" => "strptime(string, format) -> struct_time\n\nParse a string to a time tuple according to a format specification.\nSee the library reference manual for formatting codes (same as\nstrftime()).\n\nCommonly used format codes:\n\n%Y Year with century as a decimal number.\n%m Month as a decimal number [01,12].\n%d Day of the month as a decimal number [01,31].\n%H Hour (24-hour clock) as a decimal number [00,23].\n%M Minute as a decimal number [00,59].\n%S Second as a decimal number [00,61].\n%z Time zone offset from UTC.\n%a Locale's abbreviated weekday name.\n%A Locale's full weekday name.\n%b Locale's abbreviated month name.\n%B Locale's full month name.\n%c Locale's appropriate date and time representation.\n%I Hour (12-hour clock) as a decimal number [01,12].\n%p Locale's equivalent of either AM or PM.\n\nOther codes may be available on your platform. See documentation for\nthe C library strftime function.", "time.struct_time" => "The time value as returned by gmtime(), localtime(), and strptime(), and\n accepted by asctime(), mktime() and strftime(). May be considered as a\n sequence of 9 integers.\n\n Note that several fields' values are not the same as those defined by\n the C language standard for struct tm. For example, the value of the\n field tm_year is the actual year, not year - 1900. See individual\n fields' descriptions for details.", "time.struct_time.__add__" => "Return self+value.", - "time.struct_time.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element is an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate an arbitrary length tuple of elements of type T.", + "time.struct_time.__class_getitem__" => "Tuples are generic over the types of their contents.\n\nFor example, use ``tuple[int, str]`` for a pair whose first element\nis an int and second element is a string.\n\nTuples also support the form ``tuple[T, ...]`` to indicate\nan arbitrary length tuple of elements of type T.", "time.struct_time.__contains__" => "Return bool(key in self).", "time.struct_time.__delattr__" => "Implement delattr(self, name).", "time.struct_time.__eq__" => "Return self==value.", diff --git a/crates/host_env/src/fileutils.rs b/crates/host_env/src/fileutils.rs index 9d7e4430681..affb6d2205b 100644 --- a/crates/host_env/src/fileutils.rs +++ b/crates/host_env/src/fileutils.rs @@ -445,10 +445,6 @@ pub unsafe fn fclose(fp: *mut CFile) -> core::ffi::c_int { // _Py_fopen_obj in cpython (Python/fileutils.c:1757-1835) // Open a file using std::fs::File and convert to FILE* // Automatically handles path encoding and EINTR retries -#[expect( - clippy::std_instead_of_core, - reason = "false positive: core::io::ErrorKind is unstable (core_io)" -)] pub fn fopen(path: &std::path::Path, mode: &str) -> std::io::Result<*mut CFile> { use std::fs::File; diff --git a/crates/host_env/src/os.rs b/crates/host_env/src/os.rs index 7af8f586110..6c2521ca12a 100644 --- a/crates/host_env/src/os.rs +++ b/crates/host_env/src/os.rs @@ -25,9 +25,7 @@ use { std::{os::windows::io::AsRawHandle, path::Path}, windows_sys::Win32::{ Foundation::FILETIME, - Storage::FileSystem::{ - FILE_FLAG_BACKUP_SEMANTICS, INVALID_SET_FILE_POINTER, SetFilePointer, SetFileTime, - }, + Storage::FileSystem::{FILE_FLAG_BACKUP_SEMANTICS, SetFilePointerEx, SetFileTime}, System::SystemInformation::{GetSystemInfo, SYSTEM_INFO}, }, }; @@ -292,22 +290,24 @@ pub fn seek_fd( position: crt_fd::Offset, how: i32, ) -> io::Result { + use crate::windows::CheckWin32Bool; + let handle = crt_fd::as_handle(fd)?; - let mut distance_to_move: [i32; 2] = unsafe { core::mem::transmute(position) }; - let ret = unsafe { - SetFilePointer( + // `SetFilePointer` returns the low half of the new position and reports + // failure with the value a position four gigabytes in also has, so the two + // are only told apart through the error code. The `Ex` form answers with + // the whole position and a success flag of its own. + let mut new_position = 0; + unsafe { + SetFilePointerEx( handle.as_raw_handle(), - distance_to_move[0], - &mut distance_to_move[1], + position, + &mut new_position, how as _, ) - }; - if ret == INVALID_SET_FILE_POINTER { - Err(io::Error::last_os_error()) - } else { - distance_to_move[0] = ret as _; - Ok(unsafe { core::mem::transmute::<[i32; 2], i64>(distance_to_move) }) } + .check_win32_bool()?; + Ok(new_position) } #[cfg(any(unix, target_os = "wasi"))] diff --git a/crates/host_env/src/posix.rs b/crates/host_env/src/posix.rs index 1e8d4cabe1e..5af8076613b 100644 --- a/crates/host_env/src/posix.rs +++ b/crates/host_env/src/posix.rs @@ -1406,10 +1406,6 @@ fn build_posix_spawn_attrs( target_os = "illumos", target_os = "hurd", )))] - #[expect( - clippy::std_instead_of_core, - reason = "false positive: core::io::ErrorKind is unstable (core_io); expect is co-gated with the usage so it is not left unfulfilled on platforms where this block is compiled out" - )] { return Err(std::io::Error::new( std::io::ErrorKind::Unsupported, diff --git a/crates/host_env/src/winapi.rs b/crates/host_env/src/winapi.rs index 31783847311..16698098f0c 100644 --- a/crates/host_env/src/winapi.rs +++ b/crates/host_env/src/winapi.rs @@ -188,7 +188,7 @@ pub fn create_file_w( /// `startup_info` must point to a valid `STARTUPINFOW` (or extended). unsafe fn create_process_w_raw( app_name: Option<&widestring::WideCStr>, - command_line: Option<&mut [u16]>, + command_line: Option<&mut widestring::WideCStr>, inherit_handles: i32, creation_flags: u32, env: Option<&[u16]>, @@ -214,37 +214,6 @@ unsafe fn create_process_w_raw( Ok(unsafe { procinfo.assume_init() }) } -/// Win32 `CreateProcessW` requires `lpCommandLine` to be NUL-terminated. -/// The buffer is passed `&mut [u16]` because `CreateProcessW` may modify it -/// in place. -#[inline] -fn validate_command_line_terminated(buf: &[u16]) -> io::Result<()> { - if buf.last() == Some(&0) { - Ok(()) - } else { - Err(io::Error::new( - io::ErrorKind::InvalidInput, - "command_line buffer passed to create_process must be NUL-terminated", - )) - } -} - -/// Win32 `CreateProcessW` with `CREATE_UNICODE_ENVIRONMENT` requires -/// `lpEnvironment` to be a sequence of `KEY=value\0` strings followed by a -/// final terminating `\0` — i.e. the block ends with two consecutive zero -/// `u16`s. -#[inline] -fn validate_environment_block_terminated(buf: &[u16]) -> io::Result<()> { - if buf.len() >= 2 && buf[buf.len() - 2..] == [0, 0] { - Ok(()) - } else { - Err(io::Error::new( - io::ErrorKind::InvalidInput, - "env block passed to create_process must end with a double NUL terminator", - )) - } -} - #[allow( clippy::too_many_arguments, reason = "This is the semantic host wrapper for Win32 CreateProcess parameters." @@ -259,11 +228,28 @@ pub fn create_process( startup_info: StartupInfoData, handle_list: Option>, ) -> io::Result { - if let Some(cmd) = command_line.as_deref() { - validate_command_line_terminated(cmd)?; - } - if let Some(env_block) = env { - validate_environment_block_terminated(env_block)?; + // Win32 `CreateProcessW` requires `lpCommandLine` to be NUL-terminated. + // The buffer is passed `&mut [u16]` because `CreateProcessW` may modify it in place. + let command_line = command_line + .map(widestring::WideCStr::from_slice_mut) + .transpose() + .map_err(|_| { + io::Error::new( + io::ErrorKind::InvalidInput, + "command_line buffer passed to create_process must be NUL-terminated", + ) + })?; + // Win32 `CreateProcessW` with `CREATE_UNICODE_ENVIRONMENT` requires + // `lpEnvironment` to be a sequence of `KEY=value\0` strings followed by a + // final terminating `\0` — i.e. the block ends with two consecutive zero + // `u16`s. + if let Some(env_block) = env + && !env_block.ends_with(&[0, 0]) + { + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + "env block passed to create_process must end with a double NUL terminator", + )); } let mut si: windows_sys::Win32::System::Threading::STARTUPINFOEXW = diff --git a/crates/stdlib/src/array.rs b/crates/stdlib/src/array.rs index 7ecd8f4fd9f..22eb4837d48 100644 --- a/crates/stdlib/src/array.rs +++ b/crates/stdlib/src/array.rs @@ -19,7 +19,7 @@ pub mod array { builtins::{ PositionIterInternal, PyByteArray, PyBytes, PyBytesRef, PyDictRef, PyFloat, PyGenericAlias, PyInt, PyList, PyListRef, PyStr, PyStrRef, PyTupleRef, PyType, - PyTypeRef, PyUtf8StrRef, builtins_iter, + PyTypeRef, PyUtf8StrRef, builtins_iter, locked_next, }, class_or_notimplemented, convert::{ToPyObject, ToPyResult, TryFromBorrowedObject, TryFromObject}, @@ -1517,7 +1517,7 @@ pub mod array { impl IterNext for PyArrayIter { fn next(zelf: &Py, vm: &VirtualMachine) -> PyResult { - zelf.internal.lock().next(|array, pos| { + locked_next(&zelf.internal, |array, pos| { let value = array.read().get(pos, vm); Ok(if let Some(item) = value { PyIterReturn::Return(item?) diff --git a/crates/stdlib/src/binascii.rs b/crates/stdlib/src/binascii.rs index d0cdc2148e7..8f73f262e40 100644 --- a/crates/stdlib/src/binascii.rs +++ b/crates/stdlib/src/binascii.rs @@ -291,31 +291,38 @@ mod decl { return Ok(vec![]); } - if strict_mode && b[0] == PAD { - return Err(base64::DecodeError::InvalidByte(0, 61)); - } - let mut decoded: Vec = vec![]; let mut quad_pos = 0; // position in the nibble let mut pads = 0; let mut left_char: u8 = 0; - let mut padding_started = false; for (i, &el) in b.iter().enumerate() { if el == PAD { - padding_started = true; - pads += 1; - if quad_pos >= 2 && quad_pos + pads >= 4 { - if strict_mode && i + 1 < b.len() { - // Represents excess data after padding error - return Err(base64::DecodeError::InvalidLastSymbol(i, PAD)); - } + // A pad that finishes the quad it belongs to is the expected one. + if quad_pos >= 2 && quad_pos + pads <= 4 { + continue; + } - return Ok(decoded); + // RFC 4648 section 3.3 allows a decoder to ignore a pad that + // shows up anywhere else, so only strict mode complains. + if !strict_mode { + continue; } - continue; + if quad_pos == 1 { + // A single data character cannot be padded into a quad, + // and the check after the loop already reports that. + break; + } + + return Err(if quad_pos == 0 && i == 0 { + // Represents leading padding error + base64::DecodeError::InvalidByte(0, PAD) + } else { + // Represents excess padding error + base64::DecodeError::InvalidPadding + }); } let binary_char = BASE64_TABLE[el as usize]; @@ -327,9 +334,14 @@ mod decl { continue; } - if strict_mode && padding_started { - // Represents discontinuous padding error - return Err(base64::DecodeError::InvalidByte(i, PAD)); + if pads > 0 && strict_mode { + return Err(if quad_pos + pads == 4 { + // Represents excess data after padding error + base64::DecodeError::InvalidLastSymbol(i, PAD) + } else { + // Represents discontinuous padding error + base64::DecodeError::InvalidByte(i, PAD) + }); } pads = 0; @@ -361,14 +373,19 @@ mod decl { } } - match quad_pos { - 0 => Ok(decoded), - 1 => Err(base64::DecodeError::InvalidLastSymbol( + if quad_pos == 1 { + // One data character too many: no input encodes to that length. + return Err(base64::DecodeError::InvalidLastSymbol( decoded.len() / 3 * 4 + 1, 0, - )), - _ => Err(base64::DecodeError::InvalidLength(quad_pos)), + )); } + + if quad_pos != 0 && quad_pos + pads < 4 { + return Err(base64::DecodeError::InvalidLength(quad_pos)); + } + + Ok(decoded) }) .map_err(|err| super::Base64DecodeError(err).to_pyexception(vm)) } @@ -864,7 +881,7 @@ impl ToPyException for Base64DecodeError { } // TODO: clean up errors DecodeError::InvalidLength(_) => "Incorrect padding".to_owned(), - DecodeError::InvalidPadding => "Incorrect padding".to_owned(), + DecodeError::InvalidPadding => "Excess padding not allowed".to_owned(), }; new_binascii_error(format!("error decoding base64: {message}"), vm) } diff --git a/crates/stdlib/src/bisect.rs b/crates/stdlib/src/bisect.rs index 7cb965cd5f9..c9de629dbe5 100644 --- a/crates/stdlib/src/bisect.rs +++ b/crates/stdlib/src/bisect.rs @@ -106,15 +106,15 @@ mod _bisect { #[pyfunction] fn insort_left(BisectArgs { a, x, lo, hi, key }: BisectArgs, vm: &VirtualMachine) -> PyResult { - let x = if let Some(ref key) = key { - key.call((x,), vm)? - } else { - x + // The search runs on the key, the insert has to put back the item itself. + let needle = match key { + Some(ref key) => key.call((x.clone(),), vm)?, + None => x.clone(), }; let index = bisect_left( BisectArgs { a: a.clone(), - x: x.clone(), + x: needle, lo, hi, key, @@ -126,15 +126,15 @@ mod _bisect { #[pyfunction] fn insort_right(BisectArgs { a, x, lo, hi, key }: BisectArgs, vm: &VirtualMachine) -> PyResult { - let x = if let Some(ref key) = key { - key.call((x,), vm)? - } else { - x + // The search runs on the key, the insert has to put back the item itself. + let needle = match key { + Some(ref key) => key.call((x.clone(),), vm)?, + None => x.clone(), }; let index = bisect_right( BisectArgs { a: a.clone(), - x: x.clone(), + x: needle, lo, hi, key, diff --git a/crates/stdlib/src/csv.rs b/crates/stdlib/src/csv.rs index 5697689ae7d..a7f5287645c 100644 --- a/crates/stdlib/src/csv.rs +++ b/crates/stdlib/src/csv.rs @@ -16,7 +16,7 @@ mod _csv { use itertools::Itertools; use parking_lot::Mutex; use rustpython_common::{lock::LazyLock, wtf8::Wtf8Buf}; - use rustpython_vm::{match_class, sliceable::SliceableSequenceOp}; + use rustpython_vm::match_class; use std::collections::HashMap; #[pyattr] @@ -100,8 +100,10 @@ mod _csv { impl Constructor for PyDialect { type Args = PyObjectRef; - fn py_new(_cls: &Py, ctx: Self::Args, vm: &VirtualMachine) -> PyResult { - Self::try_from_object(vm, ctx) + fn py_new(_cls: &Py, obj: Self::Args, vm: &VirtualMachine) -> PyResult { + let dialect = Self::try_from_object(vm, obj)?; + validate_dialect(vm, &dialect)?; + Ok(dialect) } } @@ -173,12 +175,11 @@ mod _csv { } else { match_class!(match obj.to_owned() { s @ PyStr => { - Ok(s.as_bytes().iter().copied().exactly_one().map_err(|_| { + parse_single_char(&s, |len| { vm.new_type_error(format!( - r#""delimiter" must be a unicode character, not a string of length {}"#, - s.len() + r#""delimiter" must be a unicode character, not a string of length {len}"# )) - })?) + }) } attr => { Err(vm.new_type_error(format!( @@ -193,8 +194,13 @@ mod _csv { fn parse_quotechar_from_obj(vm: &VirtualMachine, obj: &PyObject) -> PyResult> { match_class!(match obj.get_attr("quotechar", vm)? { s @ PyStr => { - Ok(Some(s.as_bytes().iter().copied().exactly_one().map_err(|_| { - new_csv_error(vm, format!(r#""quotechar" must be a unicode character or None, not a string of length {}"#, s.len())) + Ok(Some(parse_single_char(&s, |len| { + new_csv_error( + vm, + format!( + r#""quotechar" must be a unicode character or None, not a string of length {len}"# + ), + ) })?)) } _n @ PyNone => { @@ -215,10 +221,12 @@ mod _csv { fn parse_escapechar_from_obj(vm: &VirtualMachine, obj: &PyObject) -> PyResult> { match_class!(match obj.get_attr("escapechar", vm)? { s @ PyStr => { - Ok(Some(s.as_bytes().iter().copied().exactly_one().map_err(|_| { + Ok(Some(parse_single_char(&s, |len| { new_csv_error( vm, - format!(r#""escapechar" must be a unicode character or None, not a string of length {}"#, s.len()), + format!( + r#""escapechar" must be a unicode character or None, not a string of length {len}"# + ), ) })?)) } @@ -234,26 +242,7 @@ mod _csv { }) } - /// Validate that a line terminator is ASCII and return it as a `str`. - /// - /// The writer's quoting and escaping predicates compare raw bytes, so a - /// non-ASCII terminator would either quote a field that merely shares a - /// UTF-8 lead byte or splice an escape character into the middle of a - /// multi-byte sequence. Reject those here. - /// - /// The ASCII check must come before any UTF-8 conversion so that lone - /// surrogates are reported as this `csv.Error` too. - /// - /// TODO: RUSTPYTHON; handle non-ASCII terminators code-point-wise as part - /// of full Unicode dialect support. - fn ascii_lineterminator<'a>(vm: &VirtualMachine, s: &'a PyStr) -> PyResult<&'a str> { - if !s.as_wtf8().is_ascii() { - return Err(new_csv_error( - vm, - r#""lineterminator" must be an ASCII string"#, - )); - } - // An ASCII string is always valid UTF-8. + fn parse_lineterminator<'a>(vm: &VirtualMachine, s: &'a PyStr) -> PyResult<&'a str> { s.to_str() .ok_or_else(|| new_csv_error(vm, r#""lineterminator" must be a string"#)) } @@ -265,7 +254,7 @@ mod _csv { // arbitrary-length terminator; the manual writer paths emit it // verbatim and the csv-core writer path appends it after a // sentinel terminator (see `writerow`). - let value = ascii_lineterminator(vm, &s)?; + let value = parse_lineterminator(vm, &s)?; Ok(value.to_owned()) } attr => { @@ -277,6 +266,18 @@ mod _csv { }) } + fn parse_single_char( + s: &Py, + error: impl Fn(usize) -> PyBaseExceptionRef, + ) -> PyResult { + let ch = s + .as_wtf8() + .code_points() + .exactly_one() + .map_err(|_| error(s.char_len()))?; + u8::try_from(ch.to_u32()).map_err(|_| error(s.char_len())) + } + fn prase_quoting_from_obj(vm: &VirtualMachine, obj: &PyObject) -> PyResult { match_class!(match obj.get_attr("quoting", vm)? { i @ PyInt => { @@ -344,6 +345,7 @@ mod _csv { }; let dialect = opts.update_py_dialect(dialect); + validate_dialect(vm, &dialect)?; GLOBAL_HASHMAP .lock() .insert(name.as_str().to_owned(), dialect); @@ -441,13 +443,14 @@ mod _csv { _rest: FuncArgs, vm: &VirtualMachine, ) -> PyResult { + let dialect = options.result(vm)?; Ok(Reader { iter, state: PyMutex::new(ReadState { line_num: 0, generation: 0, }), - dialect: options.result(vm)?, + dialect, }) } @@ -466,14 +469,15 @@ mod _csv { return Err(vm.new_type_error(r#"argument 1 must have a "write" method"#)); } }; + let dialect = options.result(vm)?; Ok(Writer { write, state: PyMutex::new(WriteState { buffer: vec![0; 1024], - writer: options.to_writer(), + writer: FormatOptions::to_writer(&dialect), }), - dialect: options.result(vm)?, + dialect, }) } @@ -557,7 +561,7 @@ mod _csv { dialect: DialectItem, delimiter: Option, quotechar: Option>, - escapechar: Option, + escapechar: Option>, doublequote: Option, skipinitialspace: Option, lineterminator: Option, @@ -640,11 +644,15 @@ mod _csv { if let Some(escapechar) = args.kwargs.swap_remove("escapechar") { res.escapechar = match_class!(match escapechar { - s @ PyStr => - Some(s.as_bytes().iter().copied().exactly_one().map_err(|_| { - vm.new_type_error(r#""escapechar" must be a 1-character string"#) - })?), - _ => None, + s @ PyStr => Some(Some(parse_single_char(&s, |_| { + vm.new_type_error(r#""escapechar" must be a 1-character string"#) + })?)), + PyNone => Some(None), + _ => { + return Err(ArgumentError::Exception( + vm.new_type_error(r#""escapechar" must be a 1-character string"#), + )); + } }) }; @@ -655,7 +663,7 @@ mod _csv { lineterminator.class().name() )) })?; - let value = ascii_lineterminator(vm, s)?; + let value = parse_lineterminator(vm, s)?; res.lineterminator = Some(value.to_owned()); }; @@ -690,9 +698,9 @@ mod _csv { if let Some(quotechar) = args.kwargs.swap_remove("quotechar") { res.quotechar = match_class!(match quotechar { - s @ PyStr => Some(Some(s.as_bytes().iter().copied().exactly_one().map_err( - |_| { vm.new_type_error(r#""quotechar" must be a 1-character string"#) } - )?)), + s @ PyStr => Some(Some(parse_single_char(&s, |_| { + vm.new_type_error(r#""quotechar" must be a 1-character string"#) + })?)), PyNone => { if res .quoting @@ -735,6 +743,60 @@ mod _csv { } } + fn validate_dialect(vm: &VirtualMachine, dialect: &PyDialect) -> PyResult<()> { + let special = |name: &str, value: u8| { + if matches!(value, b'\r' | b'\n') { + Err(vm.new_value_error(format!( + "{name} must be a single character, not a line break" + ))) + } else { + Ok(()) + } + }; + + special("delimiter", dialect.delimiter)?; + if let Some(quotechar) = dialect.quotechar { + special("quotechar", quotechar)?; + } + if let Some(escapechar) = dialect.escapechar { + special("escapechar", escapechar)?; + } + + if dialect.skipinitialspace + && (matches!(dialect.escapechar, Some(b' ')) || matches!(dialect.quotechar, Some(b' '))) + { + return Err(vm.new_value_error( + "escapechar or quotechar cannot be a space when skipinitialspace is enabled", + )); + } + + let values: [(&str, Option); 3] = [ + ("delimiter", Some(dialect.delimiter)), + ("quotechar", dialect.quotechar), + ("escapechar", dialect.escapechar), + ]; + for (index, (left_name, left)) in values.iter().enumerate() { + for (right_name, right) in values.iter().skip(index + 1) { + if left.is_some() && left == right { + return Err(vm.new_value_error(format!( + "{left_name} and {right_name} cannot be the same" + ))); + } + } + if left.is_some_and(|value| { + dialect + .lineterminator + .chars() + .any(|character| character == value as char) + }) { + return Err(vm.new_value_error(format!( + "{left_name} and lineterminator cannot be the same" + ))); + } + } + Ok(()) + } + impl FormatOptions { fn update_py_dialect(&self, mut res: PyDialect) -> PyDialect { macro_rules! check_and_fill { @@ -752,7 +814,7 @@ mod _csv { check_and_fill!(res, skipinitialspace); if let Some(t) = self.escapechar { - res.escapechar = Some(t); + res.escapechar = t; }; if let Some(t) = self.quotechar { @@ -768,7 +830,7 @@ mod _csv { } fn result(&self, vm: &VirtualMachine) -> PyResult { - match &self.dialect { + let dialect = match &self.dialect { DialectItem::Str(name) => { let g = GLOBAL_HASHMAP.lock(); if let Some(dialect) = g.get(name) { @@ -789,84 +851,28 @@ mod _csv { quoting: QuoteStyle::Minimal, strict: false, })), - } - } - - fn get_quoting(&self) -> QuoteStyle { - let mut quoting = match &self.dialect { - DialectItem::Str(name) => { - let g = GLOBAL_HASHMAP.lock(); - if let Some(dialect) = g.get(name) { - dialect.quoting - } else { - QuoteStyle::Minimal - } - } - DialectItem::Obj(obj) => obj.quoting, - _ => QuoteStyle::Minimal, - }; - - if let Some(attr) = self.quoting { - quoting = attr - } - - quoting + }?; + validate_dialect(vm, &dialect)?; + Ok(dialect) } - fn to_writer(&self) -> csv_core::Writer { + fn to_writer(dialect: &PyDialect) -> csv_core::Writer { let mut builder = csv_core::WriterBuilder::new(); - let mut writer = match &self.dialect { - DialectItem::Str(name) => { - let g = GLOBAL_HASHMAP.lock(); - if let Some(dialect) = g.get(name) { - let mut builder = builder - .delimiter(dialect.delimiter) - .double_quote(dialect.doublequote); - - if let Some(t) = dialect.quotechar { - builder = builder.quote(t); - } - - builder - - // TODO: RUSTPYTHON; Perfecting the remaining attributes. - } else { - &mut builder - } - } - DialectItem::Obj(obj) => { - let mut builder = builder - .delimiter(obj.delimiter) - .double_quote(obj.doublequote); - - if let Some(t) = obj.quotechar { - builder = builder.quote(t); - } - - builder - } - _ => &mut builder, - }; + let mut writer = builder + .delimiter(dialect.delimiter) + .double_quote(dialect.doublequote); - if let Some(t) = self.delimiter { - writer = writer.delimiter(t); - } - - if let Some(Some(t)) = self.quotechar { + if let Some(t) = dialect.quotechar { writer = writer.quote(t); } - if let Some(t) = self.doublequote { - writer = writer.double_quote(t); - } - writer = writer.terminator(Terminator::Any(CSV_CORE_TERMINATOR_SENTINEL)); - if let Some(e) = self.escapechar { + if let Some(e) = dialect.escapechar { writer = writer.escape(e); } - writer = writer.quote_style(self.get_quoting().into()); + writer = writer.quote_style(dialect.quoting.into()); writer.build() } @@ -1282,39 +1288,52 @@ mod _csv { dialect: &PyDialect, vm: &VirtualMachine, ) -> PyResult<()> { - for &byte in data { - if field_needs_escape(byte, dialect) { + let mut data = data; + while let Some((&byte, rest)) = data.split_first() { + if field_needs_escape(data, dialect) { let escapechar = dialect .escapechar .ok_or_else(|| new_csv_error(vm, "need to escape, but no escapechar set"))?; output.push(escapechar); } output.push(byte); + data = rest; } Ok(()) } + fn data_contains_lineterminator_char(data: &[u8], dialect: &PyDialect) -> bool { + dialect.lineterminator.chars().any(|character| { + let mut encoded = [0; 4]; + let character = character.encode_utf8(&mut encoded).as_bytes(); + data.windows(character.len()) + .any(|window| window == character) + }) + } + + fn data_starts_with_lineterminator_char(data: &[u8], dialect: &PyDialect) -> bool { + dialect.lineterminator.chars().any(|character| { + let mut encoded = [0; 4]; + let character = character.encode_utf8(&mut encoded).as_bytes(); + data.starts_with(character) + }) + } + fn field_needs_quotes(data: &[u8], dialect: &PyDialect) -> bool { data.iter().any(|&byte| { byte == dialect.delimiter || dialect.quotechar == Some(byte) || matches!(byte, b'\r' | b'\n') - // CPython quotes a field containing any character of the line - // terminator. The terminator is ASCII-validated at parse time, so - // comparing raw bytes cannot match part of a multi-byte character. - // TODO: RUSTPYTHON; supporting non-ASCII terminators needs - // code-point-wise quoting and escaping as part of full - // Unicode dialect support. - || dialect.lineterminator.as_bytes().contains(&byte) - }) + }) || data_contains_lineterminator_char(data, dialect) } - fn field_needs_escape(byte: u8, dialect: &PyDialect) -> bool { + fn field_needs_escape(data: &[u8], dialect: &PyDialect) -> bool { + let byte = data[0]; byte == dialect.delimiter || dialect.quotechar == Some(byte) || dialect.escapechar == Some(byte) || matches!(byte, b'\r' | b'\n') - || dialect.lineterminator.as_bytes().contains(&byte) + || data_starts_with_lineterminator_char(data, dialect) } fn write_lineterminator(output: &mut Vec, terminator: &str) { diff --git a/crates/stdlib/src/openssl.rs b/crates/stdlib/src/openssl.rs index fe4a5298d12..ee9d9ae84e0 100644 --- a/crates/stdlib/src/openssl.rs +++ b/crates/stdlib/src/openssl.rs @@ -525,7 +525,7 @@ mod _ssl { if n < 0 { return Err(vm.new_value_error("num must be positive")); } - let mut buf = vec![0; n as usize]; + let mut buf = vm.new_zeroed_bytes(n as usize)?; openssl::rand::rand_bytes(&mut buf).map_err(|e| convert_openssl_error(vm, e))?; Ok(buf) } @@ -872,7 +872,7 @@ mod _ssl { if n < 0 { return Err(vm.new_value_error("num must be positive")); } - let mut buf = vec![0; n as usize]; + let mut buf = vm.new_zeroed_bytes(n as usize)?; let ret = unsafe { sys::RAND_bytes(buf.as_mut_ptr(), n) }; match ret { 0 | 1 => Ok((buf, ret == 1)), diff --git a/crates/stdlib/src/pyexpat.rs b/crates/stdlib/src/pyexpat.rs index 9b55bbb22f3..500a8a686c8 100644 --- a/crates/stdlib/src/pyexpat.rs +++ b/crates/stdlib/src/pyexpat.rs @@ -1,8 +1,5 @@ //! Pyexpat builtin module -// false positive: core::io::Cursor is unstable (core_io), unusable on stable -#![expect(clippy::std_instead_of_core)] - // spell-checker: ignore libexpat pub(crate) use _pyexpat::module_def; diff --git a/crates/stdlib/src/snapshots/rustpython_stdlib___opcode__tests__bare_function_annotations_check_attribute_and_subscript_expressions.snap b/crates/stdlib/src/snapshots/rustpython_stdlib___opcode__tests__bare_function_annotations_check_attribute_and_subscript_expressions.snap index 4d78128b5e6..c0cac3bbb98 100644 --- a/crates/stdlib/src/snapshots/rustpython_stdlib___opcode__tests__bare_function_annotations_check_attribute_and_subscript_expressions.snap +++ b/crates/stdlib/src/snapshots/rustpython_stdlib___opcode__tests__bare_function_annotations_check_attribute_and_subscript_expressions.snap @@ -5,18 +5,18 @@ expression: "dis(r#\"\ndef f(one: int):\n int.new_attr: int\n [list][0].ne --- 0 RESUME 0 - 1 LOAD_CONST 0 (", line 1>) + 1 LOAD_CONST 0 (", line 1>) MAKE_FUNCTION - LOAD_CONST 1 (", line 1>) + LOAD_CONST 1 (", line 1>) MAKE_FUNCTION SET_FUNCTION_ATTRIBUTE 16 (annotate) STORE_NAME 0 (f) LOAD_CONST 2 (None) RETURN_VALUE -Disassembly of ", line 1>: +Disassembly of ", line 1>: 1 RESUME 0 - LOAD_FAST_CHECK 0 (format) + LOAD_FAST_BORROW 0 (format) LOAD_SMALL_INT 2 COMPARE_OP 132 (>) POP_JUMP_IF_FALSE 3 (to L1) @@ -28,7 +28,7 @@ Disassembly of ", line 1>: BUILD_MAP 1 RETURN_VALUE -Disassembly of ", line 1>: +Disassembly of ", line 1>: 1 RESUME 0 2 LOAD_GLOBAL 0 (int) diff --git a/crates/stdlib/src/snapshots/rustpython_stdlib___opcode__tests__nested_double_async_with.snap b/crates/stdlib/src/snapshots/rustpython_stdlib___opcode__tests__nested_double_async_with.snap index 1b0ca25c15d..1c4b2ca9469 100644 --- a/crates/stdlib/src/snapshots/rustpython_stdlib___opcode__tests__nested_double_async_with.snap +++ b/crates/stdlib/src/snapshots/rustpython_stdlib___opcode__tests__nested_double_async_with.snap @@ -5,13 +5,13 @@ expression: "dis(r#\"\nasync def test():\n for stop_exc in (StopIteration('sp --- 0 RESUME 0 - 1 LOAD_CONST 0 (", line 1>) + 1 LOAD_CONST 0 (", line 1>) MAKE_FUNCTION STORE_NAME 0 (test) LOAD_CONST 1 (None) RETURN_VALUE -Disassembly of ", line 1>: +Disassembly of ", line 1>: 1 RETURN_GENERATOR POP_TOP L1: RESUME 0 diff --git a/crates/stdlib/src/ssl.rs b/crates/stdlib/src/ssl.rs index b942e27fc69..c99ec024fa3 100644 --- a/crates/stdlib/src/ssl.rs +++ b/crates/stdlib/src/ssl.rs @@ -13,9 +13,6 @@ //! //! Warning: This library contains AI-generated code and comments. Do not trust any code or comment without verification. Please have a qualified expert review the code and remove this notice after review. -// false positive: core::io::{Cursor, ErrorKind} are unstable (core_io), unusable on stable -#![expect(clippy::std_instead_of_core)] - // OID (Object Identifier) management module mod oid; @@ -3771,7 +3768,7 @@ mod _ssl { // Use compat layer for unified read logic with proper EOF handling // This matches SSL_read_ex() approach - let mut buf = vec![0u8; len]; + let mut buf = vm.new_zeroed_bytes(len)?; let read_result = { let mut conn_guard = self.connection.lock(); let conn = conn_guard @@ -5030,14 +5027,13 @@ mod _ssl { } #[pyfunction] - fn RAND_bytes(n: i64, vm: &VirtualMachine) -> PyResult { + fn RAND_bytes(n: i32, vm: &VirtualMachine) -> PyResult { // Validate n is not negative if n < 0 { return Err(vm.new_value_error("num must be positive")); } - let n_usize = n as usize; - let mut buf = vec![0u8; n_usize]; + let mut buf = vm.new_zeroed_bytes(n as usize)?; CryptoExt::get_provider() .secure_random .fill(&mut buf) @@ -5046,7 +5042,7 @@ mod _ssl { } #[pyfunction] - fn RAND_pseudo_bytes(n: i64, vm: &VirtualMachine) -> PyResult<(PyBytesRef, bool)> { + fn RAND_pseudo_bytes(n: i32, vm: &VirtualMachine) -> PyResult<(PyBytesRef, bool)> { // Rustls providers expose cryptographically strong random bytes. let bytes = RAND_bytes(n, vm)?; Ok((bytes, true)) diff --git a/crates/unicode/build.rs b/crates/unicode/build.rs index 3a82df85eb8..8960c3872f6 100644 --- a/crates/unicode/build.rs +++ b/crates/unicode/build.rs @@ -14,7 +14,9 @@ use std::{ thread, }; -use icu_properties::props::{EnumeratedProperty, GeneralCategory, NumericType}; +use icu_properties::props::{ + BidiClass, EnumeratedProperty, GeneralCategory, NamedEnumeratedProperty, NumericType, +}; fn generate_unicode_3_2() { let path = PathBuf::from(env::var("OUT_DIR").unwrap()) @@ -80,17 +82,23 @@ fn generate_unicode_3_2() { write_derived( &base, "DerivedBidiClass-3.2.0.txt", - "BIDI_CLASS", + "BIDI_CLASS_DIFF", "(u32, u32, BidiClass)", NonZeroUsize::new(1).unwrap(), &mut writer, |start, end, id, _| { let id = parse_bidi(id); - if id != "BidiClass::LeftToRight" { - Some((start, end, id)) - } else { - None + for i in start..=end { + let legacy = BidiClass::try_from_str(id.rsplit_once("::").unwrap().1) + .expect("Unicode data contains valid variants"); + let modern = char::from_u32(i).map(BidiClass::for_char); + + if Some(legacy) != modern { + return Some((start, end, id)); + } } + + None }, |writer, mut values| { values.sort_unstable_by_key(|(start, _, _)| *start); @@ -197,6 +205,75 @@ fn generate_numeric_type() { ); } +/// Generate a compressed array of Unicode 3.2 membership. +/// +/// Membership + diff checks is more efficient than storing the full table for 3.2. The logic is to +/// default to the latest Unicode if a character exists in 3.2 but isn't different. Membership +/// is needed because diffs aren't enough - a character may be absent in 3.2 which is different +/// than returning a default. +fn generate_membership_3_2() { + let path = Path::new(env!("CARGO_MANIFEST_DIR")) + .join("unicode") + .join("ucd32") + .join("UnicodeData-3.2.0.txt"); + let reader = BufReader::new(File::open(path).unwrap()); + + // Parse membership from the first data. Unfortunately, this is largely uncompressed. + let mut membership_set = BTreeSet::new(); + // TODO: Oh my, is this hacky and ugly... + let mut range_membership = Vec::new(); + parse_unicode_3_2( + reader, + NonZeroUsize::new(1).unwrap(), + &mut io::empty(), + |start, end, value, _| { + if value.ends_with("First>") | value.ends_with("Last>") { + // Some lines (literally 20) are compressed ranges, so we have to handle those separately + range_membership.push(start); + } else { + membership_set.insert((start, end)); + } + + Option::<()>::None + }, + |_writer, _values| {}, + ); + + // Second pass. Compress the ranges. + let mut iter = membership_set.iter(); + let &(mut start_prev, mut end_prev) = iter.next().unwrap(); + let mut membership = Vec::new(); + + for &(start, end) in iter { + if start <= end_prev + 1 { + end_prev = end_prev.max(end); + } else { + membership.push((start_prev, end_prev)); + start_prev = start; + end_prev = end; + } + } + membership.push((start_prev, end_prev)); + + let (chunks, &[]) = range_membership.as_chunks::<2>() else { + panic!("Range membership is always in pairs") + }; + for &chunk in chunks { + membership.push(chunk.into()); + } + + membership.sort_unstable_by_key(|&(start, _)| start); + + let path = PathBuf::from(env::var("OUT_DIR").unwrap()) + .join("generated") + .join("membership_3_2.rs"); + fs::create_dir_all(path.parent().unwrap()).unwrap(); + let mut writer = BufWriter::new(File::create(&path).unwrap()); + + writeln!(writer, "static MEMBERSHIP_3_2: &[(u32, u32)] = &").unwrap(); + write!(writer, "{membership:?};").unwrap(); +} + fn generate_numeric_value() { let path = PathBuf::from(env::var("OUT_DIR").unwrap()) .join("generated") @@ -204,14 +281,10 @@ fn generate_numeric_value() { fs::create_dir_all(path.parent().unwrap()).unwrap(); let mut writer = BufWriter::new(File::create(&path).unwrap()); - // Ideally, this would store the diffs between the two tables. However, we need 3.2.0 - // membership as well as different chars. The final tables are both smaller than storing the - // full 3.2.0 value table. let ucd32 = Path::new(env!("CARGO_MANIFEST_DIR")) .join("unicode") .join("ucd32"); let mut ucd32_diffs = BTreeMap::new(); - let mut ucd32_member = BTreeSet::new(); let numeric_32 = BufReader::new(File::open(ucd32.join("DerivedNumericValues-3.2.0.txt")).unwrap()); parse_unicode_3_2( @@ -223,7 +296,6 @@ fn generate_numeric_value() { .parse() .expect("Unicode data contains valid properties"); ucd32_diffs.insert((start, end), value); - ucd32_member.insert((start, end)); Option::<()>::None }, |_writer, _values| {}, @@ -270,26 +342,6 @@ fn generate_numeric_value() { write!(writer, "({start}, {end}, {value:?}),").unwrap(); } writeln!(writer, "];").unwrap(); - - // Compress membership table - let mut iter = ucd32_member.iter(); - let &(mut start_prev, mut end_prev) = iter.next().unwrap(); - let mut membership = Vec::new(); - - for &(start, end) in iter { - if start <= end_prev + 1 { - end_prev = end_prev.max(end); - } else { - membership.push((start_prev, end_prev)); - start_prev = start; - end_prev = end; - } - } - membership.push((start_prev, end_prev)); - membership.sort_unstable_by_key(|&(start, _)| start); - - writeln!(writer, "static NUMERIC_VAL_EXISTS_32: &[(u32, u32)] = &").unwrap(); - write!(writer, "{membership:?};").unwrap(); } fn generate_unicode_latest() { @@ -602,10 +654,12 @@ fn main() { println!("cargo:rerun-if-changed=unicode/latest"); let t_32 = thread::spawn(generate_unicode_3_2); + let t_32_membership = thread::spawn(generate_membership_3_2); let t_numeric_type = thread::spawn(generate_numeric_type); let t_numeric_value = thread::spawn(generate_numeric_value); let t_latest = thread::spawn(generate_unicode_latest); t_32.join().unwrap(); + t_32_membership.join().unwrap(); t_numeric_type.join().unwrap(); t_numeric_value.join().unwrap(); t_latest.join().unwrap(); diff --git a/crates/unicode/src/data.rs b/crates/unicode/src/data.rs index 83d81612b6a..3b17143290f 100644 --- a/crates/unicode/src/data.rs +++ b/crates/unicode/src/data.rs @@ -19,6 +19,7 @@ use icu_properties::props::{ }; use rustpython_wtf8::CodePoint; +include!(concat!(env!("OUT_DIR"), "/generated/membership_3_2.rs")); include!(concat!(env!("OUT_DIR"), "/generated/unicode_3_2.rs")); include!(concat!(env!("OUT_DIR"), "/generated/unicode_latest.rs")); include!(concat!(env!("OUT_DIR"), "/generated/unicode_num_type.rs")); @@ -70,7 +71,7 @@ impl DecompositionType { } } -fn lookup_property(table: &[(u32, u32, T)], ch: char) -> Option { +fn lookup_table(table: &[(u32, u32, T)], ch: char) -> Option { let ch = ch as u32; table .binary_search_by(|&(start, end, _)| { @@ -86,25 +87,34 @@ fn lookup_property(table: &[(u32, u32, T)], ch: char) -> Option { .map(|i| table[i].2) } -fn lookup_numeric_val(ch: char, modern: bool) -> Option { +fn membership_3_2(ch: u32) -> bool { + MEMBERSHIP_3_2 + .binary_search_by(|&(start, end)| { + if ch > end { + Ordering::Less + } else if ch < start { + Ordering::Greater + } else { + Ordering::Equal + } + }) + .is_ok() +} + +fn lookup_property_diff( + table: &[(u32, u32, T)], + diff: &[(u32, u32, T)], + ch: char, + modern: bool, +) -> Option { if modern { - lookup_property(NUMERIC_VALUES, ch) + lookup_table(table, ch) } else { cold_path(); - lookup_property(NUMERIC_VALUES_DIFF, ch).or_else(|| { - NUMERIC_VAL_EXISTS_32 - .binary_search_by(|&(start, end)| { - let ch = ch as u32; - if ch > end { - Ordering::Less - } else if ch < start { - Ordering::Greater - } else { - Ordering::Equal - } - }) - .ok() - .and_then(|_| lookup_property(NUMERIC_VALUES, ch)) + lookup_table(diff, ch).or_else(|| { + membership_3_2(ch as u32) + .then(|| lookup_table(table, ch)) + .flatten() }) } } @@ -154,7 +164,7 @@ impl Ucd { Some(GeneralCategory::for_char(c)) } else { cold_path(); - lookup_property(GENERAL_CATEGORY, c) + lookup_table(GENERAL_CATEGORY, c) } .unwrap_or(GeneralCategory::Unassigned) .short_name() @@ -168,11 +178,13 @@ impl Ucd { Some(BidiClass::for_char(c)) } else { cold_path(); - lookup_property(BIDI_CLASS, c) + lookup_table(BIDI_CLASS_DIFF, c) + .or_else(|| membership_3_2(c as u32).then(|| BidiClass::for_char(c))) } }) - .unwrap_or(BidiClass::LeftToRight) - .short_name() + .as_ref() + .map(BidiClass::short_name) + .unwrap_or_default() } #[must_use] @@ -192,7 +204,7 @@ impl Ucd { // // Currently, this implementation is incomplete because I can't figure // out what CPython is doing. - lookup_property(EAST_ASIAN_WIDTH, c) + lookup_table(EAST_ASIAN_WIDTH, c) } }) .unwrap_or(EastAsianWidth::Neutral) @@ -230,7 +242,7 @@ impl Ucd { Some(CanonicalCombiningClass::for_char(c)) } else { cold_path(); - lookup_property(COMBINING_CLASS, c) + lookup_table(COMBINING_CLASS, c) } }) .unwrap_or(CanonicalCombiningClass::NotReordered) @@ -296,7 +308,7 @@ impl Ucd { NumericType::for_char(ch) } else { cold_path(); - lookup_property(NUMERIC_TYPE_DIFF, ch).unwrap_or_else(|| NumericType::for_char(ch)) + lookup_table(NUMERIC_TYPE_DIFF, ch).unwrap_or_else(|| NumericType::for_char(ch)) }; expected.contains(&actual).then_some(ch) @@ -307,7 +319,7 @@ impl Ucd { pub fn digit(&self, c: CodePoint) -> Option { let expected = [NumericType::Decimal, NumericType::Digit]; self.numeric_type_matches(c, &expected).and_then(|ch| { - let value = lookup_numeric_val(ch, true)?; + let value = lookup_property_diff(NUMERIC_VALUES, &[], ch, true)?; let int = value as u64; (int as f64 == value).then_some(int) }) @@ -318,7 +330,7 @@ impl Ucd { pub fn decimal(&self, c: CodePoint) -> Option { let expected = [NumericType::Decimal]; self.numeric_type_matches(c, &expected).and_then(|ch| { - let value = lookup_numeric_val(ch, self.modern)?; + let value = lookup_property_diff(NUMERIC_VALUES, NUMERIC_VALUES_DIFF, ch, self.modern)?; let int = value as u64; (int as f64 == value).then_some(int) }) @@ -328,8 +340,9 @@ impl Ucd { #[must_use] pub fn numeric(&self, c: CodePoint) -> Option { let expected = &NumericType::ALL_VALUES[1..]; - self.numeric_type_matches(c, expected) - .and_then(|ch| lookup_numeric_val(ch, self.modern)) + self.numeric_type_matches(c, expected).and_then(|ch| { + lookup_property_diff(NUMERIC_VALUES, NUMERIC_VALUES_DIFF, ch, self.modern) + }) } #[must_use] diff --git a/crates/unicode/unicode/ucd32/UnicodeData-3.2.0.txt b/crates/unicode/unicode/ucd32/UnicodeData-3.2.0.txt new file mode 100644 index 00000000000..125a6920dc9 --- /dev/null +++ b/crates/unicode/unicode/ucd32/UnicodeData-3.2.0.txt @@ -0,0 +1,13874 @@ +0000;;Cc;0;BN;;;;;N;NULL;;;; +0001;;Cc;0;BN;;;;;N;START OF HEADING;;;; +0002;;Cc;0;BN;;;;;N;START OF TEXT;;;; +0003;;Cc;0;BN;;;;;N;END OF TEXT;;;; +0004;;Cc;0;BN;;;;;N;END OF TRANSMISSION;;;; +0005;;Cc;0;BN;;;;;N;ENQUIRY;;;; +0006;;Cc;0;BN;;;;;N;ACKNOWLEDGE;;;; +0007;;Cc;0;BN;;;;;N;BELL;;;; +0008;;Cc;0;BN;;;;;N;BACKSPACE;;;; +0009;;Cc;0;S;;;;;N;CHARACTER TABULATION;;;; +000A;;Cc;0;B;;;;;N;LINE FEED (LF);;;; +000B;;Cc;0;S;;;;;N;LINE TABULATION;;;; +000C;;Cc;0;WS;;;;;N;FORM FEED (FF);;;; +000D;;Cc;0;B;;;;;N;CARRIAGE RETURN (CR);;;; +000E;;Cc;0;BN;;;;;N;SHIFT OUT;;;; +000F;;Cc;0;BN;;;;;N;SHIFT IN;;;; +0010;;Cc;0;BN;;;;;N;DATA LINK ESCAPE;;;; +0011;;Cc;0;BN;;;;;N;DEVICE CONTROL ONE;;;; +0012;;Cc;0;BN;;;;;N;DEVICE CONTROL TWO;;;; +0013;;Cc;0;BN;;;;;N;DEVICE CONTROL THREE;;;; +0014;;Cc;0;BN;;;;;N;DEVICE CONTROL FOUR;;;; +0015;;Cc;0;BN;;;;;N;NEGATIVE ACKNOWLEDGE;;;; +0016;;Cc;0;BN;;;;;N;SYNCHRONOUS IDLE;;;; +0017;;Cc;0;BN;;;;;N;END OF TRANSMISSION BLOCK;;;; +0018;;Cc;0;BN;;;;;N;CANCEL;;;; +0019;;Cc;0;BN;;;;;N;END OF MEDIUM;;;; +001A;;Cc;0;BN;;;;;N;SUBSTITUTE;;;; +001B;;Cc;0;BN;;;;;N;ESCAPE;;;; +001C;;Cc;0;B;;;;;N;INFORMATION SEPARATOR FOUR;;;; +001D;;Cc;0;B;;;;;N;INFORMATION SEPARATOR THREE;;;; +001E;;Cc;0;B;;;;;N;INFORMATION SEPARATOR TWO;;;; +001F;;Cc;0;S;;;;;N;INFORMATION SEPARATOR ONE;;;; +0020;SPACE;Zs;0;WS;;;;;N;;;;; +0021;EXCLAMATION MARK;Po;0;ON;;;;;N;;;;; +0022;QUOTATION MARK;Po;0;ON;;;;;N;;;;; +0023;NUMBER SIGN;Po;0;ET;;;;;N;;;;; +0024;DOLLAR SIGN;Sc;0;ET;;;;;N;;;;; +0025;PERCENT SIGN;Po;0;ET;;;;;N;;;;; +0026;AMPERSAND;Po;0;ON;;;;;N;;;;; +0027;APOSTROPHE;Po;0;ON;;;;;N;APOSTROPHE-QUOTE;;;; +0028;LEFT PARENTHESIS;Ps;0;ON;;;;;Y;OPENING PARENTHESIS;;;; +0029;RIGHT PARENTHESIS;Pe;0;ON;;;;;Y;CLOSING PARENTHESIS;;;; +002A;ASTERISK;Po;0;ON;;;;;N;;;;; +002B;PLUS SIGN;Sm;0;ET;;;;;N;;;;; +002C;COMMA;Po;0;CS;;;;;N;;;;; +002D;HYPHEN-MINUS;Pd;0;ET;;;;;N;;;;; +002E;FULL STOP;Po;0;CS;;;;;N;PERIOD;;;; +002F;SOLIDUS;Po;0;ES;;;;;N;SLASH;;;; +0030;DIGIT ZERO;Nd;0;EN;;0;0;0;N;;;;; +0031;DIGIT ONE;Nd;0;EN;;1;1;1;N;;;;; +0032;DIGIT TWO;Nd;0;EN;;2;2;2;N;;;;; +0033;DIGIT THREE;Nd;0;EN;;3;3;3;N;;;;; +0034;DIGIT FOUR;Nd;0;EN;;4;4;4;N;;;;; +0035;DIGIT FIVE;Nd;0;EN;;5;5;5;N;;;;; +0036;DIGIT SIX;Nd;0;EN;;6;6;6;N;;;;; +0037;DIGIT SEVEN;Nd;0;EN;;7;7;7;N;;;;; +0038;DIGIT EIGHT;Nd;0;EN;;8;8;8;N;;;;; +0039;DIGIT NINE;Nd;0;EN;;9;9;9;N;;;;; +003A;COLON;Po;0;CS;;;;;N;;;;; +003B;SEMICOLON;Po;0;ON;;;;;N;;;;; +003C;LESS-THAN SIGN;Sm;0;ON;;;;;Y;;;;; +003D;EQUALS SIGN;Sm;0;ON;;;;;N;;;;; +003E;GREATER-THAN SIGN;Sm;0;ON;;;;;Y;;;;; +003F;QUESTION MARK;Po;0;ON;;;;;N;;;;; +0040;COMMERCIAL AT;Po;0;ON;;;;;N;;;;; +0041;LATIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0061; +0042;LATIN CAPITAL LETTER B;Lu;0;L;;;;;N;;;;0062; +0043;LATIN CAPITAL LETTER C;Lu;0;L;;;;;N;;;;0063; +0044;LATIN CAPITAL LETTER D;Lu;0;L;;;;;N;;;;0064; +0045;LATIN CAPITAL LETTER E;Lu;0;L;;;;;N;;;;0065; +0046;LATIN CAPITAL LETTER F;Lu;0;L;;;;;N;;;;0066; +0047;LATIN CAPITAL LETTER G;Lu;0;L;;;;;N;;;;0067; +0048;LATIN CAPITAL LETTER H;Lu;0;L;;;;;N;;;;0068; +0049;LATIN CAPITAL LETTER I;Lu;0;L;;;;;N;;;;0069; +004A;LATIN CAPITAL LETTER J;Lu;0;L;;;;;N;;;;006A; +004B;LATIN CAPITAL LETTER K;Lu;0;L;;;;;N;;;;006B; +004C;LATIN CAPITAL LETTER L;Lu;0;L;;;;;N;;;;006C; +004D;LATIN CAPITAL LETTER M;Lu;0;L;;;;;N;;;;006D; +004E;LATIN CAPITAL LETTER N;Lu;0;L;;;;;N;;;;006E; +004F;LATIN CAPITAL LETTER O;Lu;0;L;;;;;N;;;;006F; +0050;LATIN CAPITAL LETTER P;Lu;0;L;;;;;N;;;;0070; +0051;LATIN CAPITAL LETTER Q;Lu;0;L;;;;;N;;;;0071; +0052;LATIN CAPITAL LETTER R;Lu;0;L;;;;;N;;;;0072; +0053;LATIN CAPITAL LETTER S;Lu;0;L;;;;;N;;;;0073; +0054;LATIN CAPITAL LETTER T;Lu;0;L;;;;;N;;;;0074; +0055;LATIN CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0075; +0056;LATIN CAPITAL LETTER V;Lu;0;L;;;;;N;;;;0076; +0057;LATIN CAPITAL LETTER W;Lu;0;L;;;;;N;;;;0077; +0058;LATIN CAPITAL LETTER X;Lu;0;L;;;;;N;;;;0078; +0059;LATIN CAPITAL LETTER Y;Lu;0;L;;;;;N;;;;0079; +005A;LATIN CAPITAL LETTER Z;Lu;0;L;;;;;N;;;;007A; +005B;LEFT SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING SQUARE BRACKET;;;; +005C;REVERSE SOLIDUS;Po;0;ON;;;;;N;BACKSLASH;;;; +005D;RIGHT SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING SQUARE BRACKET;;;; +005E;CIRCUMFLEX ACCENT;Sk;0;ON;;;;;N;SPACING CIRCUMFLEX;;;; +005F;LOW LINE;Pc;0;ON;;;;;N;SPACING UNDERSCORE;;;; +0060;GRAVE ACCENT;Sk;0;ON;;;;;N;SPACING GRAVE;;;; +0061;LATIN SMALL LETTER A;Ll;0;L;;;;;N;;;0041;;0041 +0062;LATIN SMALL LETTER B;Ll;0;L;;;;;N;;;0042;;0042 +0063;LATIN SMALL LETTER C;Ll;0;L;;;;;N;;;0043;;0043 +0064;LATIN SMALL LETTER D;Ll;0;L;;;;;N;;;0044;;0044 +0065;LATIN SMALL LETTER E;Ll;0;L;;;;;N;;;0045;;0045 +0066;LATIN SMALL LETTER F;Ll;0;L;;;;;N;;;0046;;0046 +0067;LATIN SMALL LETTER G;Ll;0;L;;;;;N;;;0047;;0047 +0068;LATIN SMALL LETTER H;Ll;0;L;;;;;N;;;0048;;0048 +0069;LATIN SMALL LETTER I;Ll;0;L;;;;;N;;;0049;;0049 +006A;LATIN SMALL LETTER J;Ll;0;L;;;;;N;;;004A;;004A +006B;LATIN SMALL LETTER K;Ll;0;L;;;;;N;;;004B;;004B +006C;LATIN SMALL LETTER L;Ll;0;L;;;;;N;;;004C;;004C +006D;LATIN SMALL LETTER M;Ll;0;L;;;;;N;;;004D;;004D +006E;LATIN SMALL LETTER N;Ll;0;L;;;;;N;;;004E;;004E +006F;LATIN SMALL LETTER O;Ll;0;L;;;;;N;;;004F;;004F +0070;LATIN SMALL LETTER P;Ll;0;L;;;;;N;;;0050;;0050 +0071;LATIN SMALL LETTER Q;Ll;0;L;;;;;N;;;0051;;0051 +0072;LATIN SMALL LETTER R;Ll;0;L;;;;;N;;;0052;;0052 +0073;LATIN SMALL LETTER S;Ll;0;L;;;;;N;;;0053;;0053 +0074;LATIN SMALL LETTER T;Ll;0;L;;;;;N;;;0054;;0054 +0075;LATIN SMALL LETTER U;Ll;0;L;;;;;N;;;0055;;0055 +0076;LATIN SMALL LETTER V;Ll;0;L;;;;;N;;;0056;;0056 +0077;LATIN SMALL LETTER W;Ll;0;L;;;;;N;;;0057;;0057 +0078;LATIN SMALL LETTER X;Ll;0;L;;;;;N;;;0058;;0058 +0079;LATIN SMALL LETTER Y;Ll;0;L;;;;;N;;;0059;;0059 +007A;LATIN SMALL LETTER Z;Ll;0;L;;;;;N;;;005A;;005A +007B;LEFT CURLY BRACKET;Ps;0;ON;;;;;Y;OPENING CURLY BRACKET;;;; +007C;VERTICAL LINE;Sm;0;ON;;;;;N;VERTICAL BAR;;;; +007D;RIGHT CURLY BRACKET;Pe;0;ON;;;;;Y;CLOSING CURLY BRACKET;;;; +007E;TILDE;Sm;0;ON;;;;;N;;;;; +007F;;Cc;0;BN;;;;;N;DELETE;;;; +0080;;Cc;0;BN;;;;;N;;;;; +0081;;Cc;0;BN;;;;;N;;;;; +0082;;Cc;0;BN;;;;;N;BREAK PERMITTED HERE;;;; +0083;;Cc;0;BN;;;;;N;NO BREAK HERE;;;; +0084;;Cc;0;BN;;;;;N;;;;; +0085;;Cc;0;B;;;;;N;NEXT LINE (NEL);;;; +0086;;Cc;0;BN;;;;;N;START OF SELECTED AREA;;;; +0087;;Cc;0;BN;;;;;N;END OF SELECTED AREA;;;; +0088;;Cc;0;BN;;;;;N;CHARACTER TABULATION SET;;;; +0089;;Cc;0;BN;;;;;N;CHARACTER TABULATION WITH JUSTIFICATION;;;; +008A;;Cc;0;BN;;;;;N;LINE TABULATION SET;;;; +008B;;Cc;0;BN;;;;;N;PARTIAL LINE FORWARD;;;; +008C;;Cc;0;BN;;;;;N;PARTIAL LINE BACKWARD;;;; +008D;;Cc;0;BN;;;;;N;REVERSE LINE FEED;;;; +008E;;Cc;0;BN;;;;;N;SINGLE SHIFT TWO;;;; +008F;;Cc;0;BN;;;;;N;SINGLE SHIFT THREE;;;; +0090;;Cc;0;BN;;;;;N;DEVICE CONTROL STRING;;;; +0091;;Cc;0;BN;;;;;N;PRIVATE USE ONE;;;; +0092;;Cc;0;BN;;;;;N;PRIVATE USE TWO;;;; +0093;;Cc;0;BN;;;;;N;SET TRANSMIT STATE;;;; +0094;;Cc;0;BN;;;;;N;CANCEL CHARACTER;;;; +0095;;Cc;0;BN;;;;;N;MESSAGE WAITING;;;; +0096;;Cc;0;BN;;;;;N;START OF GUARDED AREA;;;; +0097;;Cc;0;BN;;;;;N;END OF GUARDED AREA;;;; +0098;;Cc;0;BN;;;;;N;START OF STRING;;;; +0099;;Cc;0;BN;;;;;N;;;;; +009A;;Cc;0;BN;;;;;N;SINGLE CHARACTER INTRODUCER;;;; +009B;;Cc;0;BN;;;;;N;CONTROL SEQUENCE INTRODUCER;;;; +009C;;Cc;0;BN;;;;;N;STRING TERMINATOR;;;; +009D;;Cc;0;BN;;;;;N;OPERATING SYSTEM COMMAND;;;; +009E;;Cc;0;BN;;;;;N;PRIVACY MESSAGE;;;; +009F;;Cc;0;BN;;;;;N;APPLICATION PROGRAM COMMAND;;;; +00A0;NO-BREAK SPACE;Zs;0;CS; 0020;;;;N;NON-BREAKING SPACE;;;; +00A1;INVERTED EXCLAMATION MARK;Po;0;ON;;;;;N;;;;; +00A2;CENT SIGN;Sc;0;ET;;;;;N;;;;; +00A3;POUND SIGN;Sc;0;ET;;;;;N;;;;; +00A4;CURRENCY SIGN;Sc;0;ET;;;;;N;;;;; +00A5;YEN SIGN;Sc;0;ET;;;;;N;;;;; +00A6;BROKEN BAR;So;0;ON;;;;;N;BROKEN VERTICAL BAR;;;; +00A7;SECTION SIGN;So;0;ON;;;;;N;;;;; +00A8;DIAERESIS;Sk;0;ON; 0020 0308;;;;N;SPACING DIAERESIS;;;; +00A9;COPYRIGHT SIGN;So;0;ON;;;;;N;;;;; +00AA;FEMININE ORDINAL INDICATOR;Ll;0;L; 0061;;;;N;;;;; +00AB;LEFT-POINTING DOUBLE ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING GUILLEMET;*;;; +00AC;NOT SIGN;Sm;0;ON;;;;;N;;;;; +00AD;SOFT HYPHEN;Pd;0;ON;;;;;N;;;;; +00AE;REGISTERED SIGN;So;0;ON;;;;;N;REGISTERED TRADE MARK SIGN;;;; +00AF;MACRON;Sk;0;ON; 0020 0304;;;;N;SPACING MACRON;;;; +00B0;DEGREE SIGN;So;0;ET;;;;;N;;;;; +00B1;PLUS-MINUS SIGN;Sm;0;ET;;;;;N;PLUS-OR-MINUS SIGN;;;; +00B2;SUPERSCRIPT TWO;No;0;EN; 0032;2;2;2;N;SUPERSCRIPT DIGIT TWO;;;; +00B3;SUPERSCRIPT THREE;No;0;EN; 0033;3;3;3;N;SUPERSCRIPT DIGIT THREE;;;; +00B4;ACUTE ACCENT;Sk;0;ON; 0020 0301;;;;N;SPACING ACUTE;;;; +00B5;MICRO SIGN;Ll;0;L; 03BC;;;;N;;;039C;;039C +00B6;PILCROW SIGN;So;0;ON;;;;;N;PARAGRAPH SIGN;;;; +00B7;MIDDLE DOT;Po;0;ON;;;;;N;;;;; +00B8;CEDILLA;Sk;0;ON; 0020 0327;;;;N;SPACING CEDILLA;;;; +00B9;SUPERSCRIPT ONE;No;0;EN; 0031;1;1;1;N;SUPERSCRIPT DIGIT ONE;;;; +00BA;MASCULINE ORDINAL INDICATOR;Ll;0;L; 006F;;;;N;;;;; +00BB;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING GUILLEMET;*;;; +00BC;VULGAR FRACTION ONE QUARTER;No;0;ON; 0031 2044 0034;;;1/4;N;FRACTION ONE QUARTER;;;; +00BD;VULGAR FRACTION ONE HALF;No;0;ON; 0031 2044 0032;;;1/2;N;FRACTION ONE HALF;;;; +00BE;VULGAR FRACTION THREE QUARTERS;No;0;ON; 0033 2044 0034;;;3/4;N;FRACTION THREE QUARTERS;;;; +00BF;INVERTED QUESTION MARK;Po;0;ON;;;;;N;;;;; +00C0;LATIN CAPITAL LETTER A WITH GRAVE;Lu;0;L;0041 0300;;;;N;LATIN CAPITAL LETTER A GRAVE;;;00E0; +00C1;LATIN CAPITAL LETTER A WITH ACUTE;Lu;0;L;0041 0301;;;;N;LATIN CAPITAL LETTER A ACUTE;;;00E1; +00C2;LATIN CAPITAL LETTER A WITH CIRCUMFLEX;Lu;0;L;0041 0302;;;;N;LATIN CAPITAL LETTER A CIRCUMFLEX;;;00E2; +00C3;LATIN CAPITAL LETTER A WITH TILDE;Lu;0;L;0041 0303;;;;N;LATIN CAPITAL LETTER A TILDE;;;00E3; +00C4;LATIN CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0041 0308;;;;N;LATIN CAPITAL LETTER A DIAERESIS;;;00E4; +00C5;LATIN CAPITAL LETTER A WITH RING ABOVE;Lu;0;L;0041 030A;;;;N;LATIN CAPITAL LETTER A RING;;;00E5; +00C6;LATIN CAPITAL LETTER AE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER A E;ash *;;00E6; +00C7;LATIN CAPITAL LETTER C WITH CEDILLA;Lu;0;L;0043 0327;;;;N;LATIN CAPITAL LETTER C CEDILLA;;;00E7; +00C8;LATIN CAPITAL LETTER E WITH GRAVE;Lu;0;L;0045 0300;;;;N;LATIN CAPITAL LETTER E GRAVE;;;00E8; +00C9;LATIN CAPITAL LETTER E WITH ACUTE;Lu;0;L;0045 0301;;;;N;LATIN CAPITAL LETTER E ACUTE;;;00E9; +00CA;LATIN CAPITAL LETTER E WITH CIRCUMFLEX;Lu;0;L;0045 0302;;;;N;LATIN CAPITAL LETTER E CIRCUMFLEX;;;00EA; +00CB;LATIN CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;0045 0308;;;;N;LATIN CAPITAL LETTER E DIAERESIS;;;00EB; +00CC;LATIN CAPITAL LETTER I WITH GRAVE;Lu;0;L;0049 0300;;;;N;LATIN CAPITAL LETTER I GRAVE;;;00EC; +00CD;LATIN CAPITAL LETTER I WITH ACUTE;Lu;0;L;0049 0301;;;;N;LATIN CAPITAL LETTER I ACUTE;;;00ED; +00CE;LATIN CAPITAL LETTER I WITH CIRCUMFLEX;Lu;0;L;0049 0302;;;;N;LATIN CAPITAL LETTER I CIRCUMFLEX;;;00EE; +00CF;LATIN CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0049 0308;;;;N;LATIN CAPITAL LETTER I DIAERESIS;;;00EF; +00D0;LATIN CAPITAL LETTER ETH;Lu;0;L;;;;;N;;Icelandic;;00F0; +00D1;LATIN CAPITAL LETTER N WITH TILDE;Lu;0;L;004E 0303;;;;N;LATIN CAPITAL LETTER N TILDE;;;00F1; +00D2;LATIN CAPITAL LETTER O WITH GRAVE;Lu;0;L;004F 0300;;;;N;LATIN CAPITAL LETTER O GRAVE;;;00F2; +00D3;LATIN CAPITAL LETTER O WITH ACUTE;Lu;0;L;004F 0301;;;;N;LATIN CAPITAL LETTER O ACUTE;;;00F3; +00D4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX;Lu;0;L;004F 0302;;;;N;LATIN CAPITAL LETTER O CIRCUMFLEX;;;00F4; +00D5;LATIN CAPITAL LETTER O WITH TILDE;Lu;0;L;004F 0303;;;;N;LATIN CAPITAL LETTER O TILDE;;;00F5; +00D6;LATIN CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;004F 0308;;;;N;LATIN CAPITAL LETTER O DIAERESIS;;;00F6; +00D7;MULTIPLICATION SIGN;Sm;0;ON;;;;;N;;;;; +00D8;LATIN CAPITAL LETTER O WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O SLASH;;;00F8; +00D9;LATIN CAPITAL LETTER U WITH GRAVE;Lu;0;L;0055 0300;;;;N;LATIN CAPITAL LETTER U GRAVE;;;00F9; +00DA;LATIN CAPITAL LETTER U WITH ACUTE;Lu;0;L;0055 0301;;;;N;LATIN CAPITAL LETTER U ACUTE;;;00FA; +00DB;LATIN CAPITAL LETTER U WITH CIRCUMFLEX;Lu;0;L;0055 0302;;;;N;LATIN CAPITAL LETTER U CIRCUMFLEX;;;00FB; +00DC;LATIN CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0055 0308;;;;N;LATIN CAPITAL LETTER U DIAERESIS;;;00FC; +00DD;LATIN CAPITAL LETTER Y WITH ACUTE;Lu;0;L;0059 0301;;;;N;LATIN CAPITAL LETTER Y ACUTE;;;00FD; +00DE;LATIN CAPITAL LETTER THORN;Lu;0;L;;;;;N;;Icelandic;;00FE; +00DF;LATIN SMALL LETTER SHARP S;Ll;0;L;;;;;N;;German;;; +00E0;LATIN SMALL LETTER A WITH GRAVE;Ll;0;L;0061 0300;;;;N;LATIN SMALL LETTER A GRAVE;;00C0;;00C0 +00E1;LATIN SMALL LETTER A WITH ACUTE;Ll;0;L;0061 0301;;;;N;LATIN SMALL LETTER A ACUTE;;00C1;;00C1 +00E2;LATIN SMALL LETTER A WITH CIRCUMFLEX;Ll;0;L;0061 0302;;;;N;LATIN SMALL LETTER A CIRCUMFLEX;;00C2;;00C2 +00E3;LATIN SMALL LETTER A WITH TILDE;Ll;0;L;0061 0303;;;;N;LATIN SMALL LETTER A TILDE;;00C3;;00C3 +00E4;LATIN SMALL LETTER A WITH DIAERESIS;Ll;0;L;0061 0308;;;;N;LATIN SMALL LETTER A DIAERESIS;;00C4;;00C4 +00E5;LATIN SMALL LETTER A WITH RING ABOVE;Ll;0;L;0061 030A;;;;N;LATIN SMALL LETTER A RING;;00C5;;00C5 +00E6;LATIN SMALL LETTER AE;Ll;0;L;;;;;N;LATIN SMALL LETTER A E;ash *;00C6;;00C6 +00E7;LATIN SMALL LETTER C WITH CEDILLA;Ll;0;L;0063 0327;;;;N;LATIN SMALL LETTER C CEDILLA;;00C7;;00C7 +00E8;LATIN SMALL LETTER E WITH GRAVE;Ll;0;L;0065 0300;;;;N;LATIN SMALL LETTER E GRAVE;;00C8;;00C8 +00E9;LATIN SMALL LETTER E WITH ACUTE;Ll;0;L;0065 0301;;;;N;LATIN SMALL LETTER E ACUTE;;00C9;;00C9 +00EA;LATIN SMALL LETTER E WITH CIRCUMFLEX;Ll;0;L;0065 0302;;;;N;LATIN SMALL LETTER E CIRCUMFLEX;;00CA;;00CA +00EB;LATIN SMALL LETTER E WITH DIAERESIS;Ll;0;L;0065 0308;;;;N;LATIN SMALL LETTER E DIAERESIS;;00CB;;00CB +00EC;LATIN SMALL LETTER I WITH GRAVE;Ll;0;L;0069 0300;;;;N;LATIN SMALL LETTER I GRAVE;;00CC;;00CC +00ED;LATIN SMALL LETTER I WITH ACUTE;Ll;0;L;0069 0301;;;;N;LATIN SMALL LETTER I ACUTE;;00CD;;00CD +00EE;LATIN SMALL LETTER I WITH CIRCUMFLEX;Ll;0;L;0069 0302;;;;N;LATIN SMALL LETTER I CIRCUMFLEX;;00CE;;00CE +00EF;LATIN SMALL LETTER I WITH DIAERESIS;Ll;0;L;0069 0308;;;;N;LATIN SMALL LETTER I DIAERESIS;;00CF;;00CF +00F0;LATIN SMALL LETTER ETH;Ll;0;L;;;;;N;;Icelandic;00D0;;00D0 +00F1;LATIN SMALL LETTER N WITH TILDE;Ll;0;L;006E 0303;;;;N;LATIN SMALL LETTER N TILDE;;00D1;;00D1 +00F2;LATIN SMALL LETTER O WITH GRAVE;Ll;0;L;006F 0300;;;;N;LATIN SMALL LETTER O GRAVE;;00D2;;00D2 +00F3;LATIN SMALL LETTER O WITH ACUTE;Ll;0;L;006F 0301;;;;N;LATIN SMALL LETTER O ACUTE;;00D3;;00D3 +00F4;LATIN SMALL LETTER O WITH CIRCUMFLEX;Ll;0;L;006F 0302;;;;N;LATIN SMALL LETTER O CIRCUMFLEX;;00D4;;00D4 +00F5;LATIN SMALL LETTER O WITH TILDE;Ll;0;L;006F 0303;;;;N;LATIN SMALL LETTER O TILDE;;00D5;;00D5 +00F6;LATIN SMALL LETTER O WITH DIAERESIS;Ll;0;L;006F 0308;;;;N;LATIN SMALL LETTER O DIAERESIS;;00D6;;00D6 +00F7;DIVISION SIGN;Sm;0;ON;;;;;N;;;;; +00F8;LATIN SMALL LETTER O WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER O SLASH;;00D8;;00D8 +00F9;LATIN SMALL LETTER U WITH GRAVE;Ll;0;L;0075 0300;;;;N;LATIN SMALL LETTER U GRAVE;;00D9;;00D9 +00FA;LATIN SMALL LETTER U WITH ACUTE;Ll;0;L;0075 0301;;;;N;LATIN SMALL LETTER U ACUTE;;00DA;;00DA +00FB;LATIN SMALL LETTER U WITH CIRCUMFLEX;Ll;0;L;0075 0302;;;;N;LATIN SMALL LETTER U CIRCUMFLEX;;00DB;;00DB +00FC;LATIN SMALL LETTER U WITH DIAERESIS;Ll;0;L;0075 0308;;;;N;LATIN SMALL LETTER U DIAERESIS;;00DC;;00DC +00FD;LATIN SMALL LETTER Y WITH ACUTE;Ll;0;L;0079 0301;;;;N;LATIN SMALL LETTER Y ACUTE;;00DD;;00DD +00FE;LATIN SMALL LETTER THORN;Ll;0;L;;;;;N;;Icelandic;00DE;;00DE +00FF;LATIN SMALL LETTER Y WITH DIAERESIS;Ll;0;L;0079 0308;;;;N;LATIN SMALL LETTER Y DIAERESIS;;0178;;0178 +0100;LATIN CAPITAL LETTER A WITH MACRON;Lu;0;L;0041 0304;;;;N;LATIN CAPITAL LETTER A MACRON;;;0101; +0101;LATIN SMALL LETTER A WITH MACRON;Ll;0;L;0061 0304;;;;N;LATIN SMALL LETTER A MACRON;;0100;;0100 +0102;LATIN CAPITAL LETTER A WITH BREVE;Lu;0;L;0041 0306;;;;N;LATIN CAPITAL LETTER A BREVE;;;0103; +0103;LATIN SMALL LETTER A WITH BREVE;Ll;0;L;0061 0306;;;;N;LATIN SMALL LETTER A BREVE;;0102;;0102 +0104;LATIN CAPITAL LETTER A WITH OGONEK;Lu;0;L;0041 0328;;;;N;LATIN CAPITAL LETTER A OGONEK;;;0105; +0105;LATIN SMALL LETTER A WITH OGONEK;Ll;0;L;0061 0328;;;;N;LATIN SMALL LETTER A OGONEK;;0104;;0104 +0106;LATIN CAPITAL LETTER C WITH ACUTE;Lu;0;L;0043 0301;;;;N;LATIN CAPITAL LETTER C ACUTE;;;0107; +0107;LATIN SMALL LETTER C WITH ACUTE;Ll;0;L;0063 0301;;;;N;LATIN SMALL LETTER C ACUTE;;0106;;0106 +0108;LATIN CAPITAL LETTER C WITH CIRCUMFLEX;Lu;0;L;0043 0302;;;;N;LATIN CAPITAL LETTER C CIRCUMFLEX;;;0109; +0109;LATIN SMALL LETTER C WITH CIRCUMFLEX;Ll;0;L;0063 0302;;;;N;LATIN SMALL LETTER C CIRCUMFLEX;;0108;;0108 +010A;LATIN CAPITAL LETTER C WITH DOT ABOVE;Lu;0;L;0043 0307;;;;N;LATIN CAPITAL LETTER C DOT;;;010B; +010B;LATIN SMALL LETTER C WITH DOT ABOVE;Ll;0;L;0063 0307;;;;N;LATIN SMALL LETTER C DOT;;010A;;010A +010C;LATIN CAPITAL LETTER C WITH CARON;Lu;0;L;0043 030C;;;;N;LATIN CAPITAL LETTER C HACEK;;;010D; +010D;LATIN SMALL LETTER C WITH CARON;Ll;0;L;0063 030C;;;;N;LATIN SMALL LETTER C HACEK;;010C;;010C +010E;LATIN CAPITAL LETTER D WITH CARON;Lu;0;L;0044 030C;;;;N;LATIN CAPITAL LETTER D HACEK;;;010F; +010F;LATIN SMALL LETTER D WITH CARON;Ll;0;L;0064 030C;;;;N;LATIN SMALL LETTER D HACEK;;010E;;010E +0110;LATIN CAPITAL LETTER D WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D BAR;;;0111; +0111;LATIN SMALL LETTER D WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER D BAR;;0110;;0110 +0112;LATIN CAPITAL LETTER E WITH MACRON;Lu;0;L;0045 0304;;;;N;LATIN CAPITAL LETTER E MACRON;;;0113; +0113;LATIN SMALL LETTER E WITH MACRON;Ll;0;L;0065 0304;;;;N;LATIN SMALL LETTER E MACRON;;0112;;0112 +0114;LATIN CAPITAL LETTER E WITH BREVE;Lu;0;L;0045 0306;;;;N;LATIN CAPITAL LETTER E BREVE;;;0115; +0115;LATIN SMALL LETTER E WITH BREVE;Ll;0;L;0065 0306;;;;N;LATIN SMALL LETTER E BREVE;;0114;;0114 +0116;LATIN CAPITAL LETTER E WITH DOT ABOVE;Lu;0;L;0045 0307;;;;N;LATIN CAPITAL LETTER E DOT;;;0117; +0117;LATIN SMALL LETTER E WITH DOT ABOVE;Ll;0;L;0065 0307;;;;N;LATIN SMALL LETTER E DOT;;0116;;0116 +0118;LATIN CAPITAL LETTER E WITH OGONEK;Lu;0;L;0045 0328;;;;N;LATIN CAPITAL LETTER E OGONEK;;;0119; +0119;LATIN SMALL LETTER E WITH OGONEK;Ll;0;L;0065 0328;;;;N;LATIN SMALL LETTER E OGONEK;;0118;;0118 +011A;LATIN CAPITAL LETTER E WITH CARON;Lu;0;L;0045 030C;;;;N;LATIN CAPITAL LETTER E HACEK;;;011B; +011B;LATIN SMALL LETTER E WITH CARON;Ll;0;L;0065 030C;;;;N;LATIN SMALL LETTER E HACEK;;011A;;011A +011C;LATIN CAPITAL LETTER G WITH CIRCUMFLEX;Lu;0;L;0047 0302;;;;N;LATIN CAPITAL LETTER G CIRCUMFLEX;;;011D; +011D;LATIN SMALL LETTER G WITH CIRCUMFLEX;Ll;0;L;0067 0302;;;;N;LATIN SMALL LETTER G CIRCUMFLEX;;011C;;011C +011E;LATIN CAPITAL LETTER G WITH BREVE;Lu;0;L;0047 0306;;;;N;LATIN CAPITAL LETTER G BREVE;;;011F; +011F;LATIN SMALL LETTER G WITH BREVE;Ll;0;L;0067 0306;;;;N;LATIN SMALL LETTER G BREVE;;011E;;011E +0120;LATIN CAPITAL LETTER G WITH DOT ABOVE;Lu;0;L;0047 0307;;;;N;LATIN CAPITAL LETTER G DOT;;;0121; +0121;LATIN SMALL LETTER G WITH DOT ABOVE;Ll;0;L;0067 0307;;;;N;LATIN SMALL LETTER G DOT;;0120;;0120 +0122;LATIN CAPITAL LETTER G WITH CEDILLA;Lu;0;L;0047 0327;;;;N;LATIN CAPITAL LETTER G CEDILLA;;;0123; +0123;LATIN SMALL LETTER G WITH CEDILLA;Ll;0;L;0067 0327;;;;N;LATIN SMALL LETTER G CEDILLA;;0122;;0122 +0124;LATIN CAPITAL LETTER H WITH CIRCUMFLEX;Lu;0;L;0048 0302;;;;N;LATIN CAPITAL LETTER H CIRCUMFLEX;;;0125; +0125;LATIN SMALL LETTER H WITH CIRCUMFLEX;Ll;0;L;0068 0302;;;;N;LATIN SMALL LETTER H CIRCUMFLEX;;0124;;0124 +0126;LATIN CAPITAL LETTER H WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER H BAR;;;0127; +0127;LATIN SMALL LETTER H WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER H BAR;;0126;;0126 +0128;LATIN CAPITAL LETTER I WITH TILDE;Lu;0;L;0049 0303;;;;N;LATIN CAPITAL LETTER I TILDE;;;0129; +0129;LATIN SMALL LETTER I WITH TILDE;Ll;0;L;0069 0303;;;;N;LATIN SMALL LETTER I TILDE;;0128;;0128 +012A;LATIN CAPITAL LETTER I WITH MACRON;Lu;0;L;0049 0304;;;;N;LATIN CAPITAL LETTER I MACRON;;;012B; +012B;LATIN SMALL LETTER I WITH MACRON;Ll;0;L;0069 0304;;;;N;LATIN SMALL LETTER I MACRON;;012A;;012A +012C;LATIN CAPITAL LETTER I WITH BREVE;Lu;0;L;0049 0306;;;;N;LATIN CAPITAL LETTER I BREVE;;;012D; +012D;LATIN SMALL LETTER I WITH BREVE;Ll;0;L;0069 0306;;;;N;LATIN SMALL LETTER I BREVE;;012C;;012C +012E;LATIN CAPITAL LETTER I WITH OGONEK;Lu;0;L;0049 0328;;;;N;LATIN CAPITAL LETTER I OGONEK;;;012F; +012F;LATIN SMALL LETTER I WITH OGONEK;Ll;0;L;0069 0328;;;;N;LATIN SMALL LETTER I OGONEK;;012E;;012E +0130;LATIN CAPITAL LETTER I WITH DOT ABOVE;Lu;0;L;0049 0307;;;;N;LATIN CAPITAL LETTER I DOT;;;0069; +0131;LATIN SMALL LETTER DOTLESS I;Ll;0;L;;;;;N;;;0049;;0049 +0132;LATIN CAPITAL LIGATURE IJ;Lu;0;L; 0049 004A;;;;N;LATIN CAPITAL LETTER I J;;;0133; +0133;LATIN SMALL LIGATURE IJ;Ll;0;L; 0069 006A;;;;N;LATIN SMALL LETTER I J;;0132;;0132 +0134;LATIN CAPITAL LETTER J WITH CIRCUMFLEX;Lu;0;L;004A 0302;;;;N;LATIN CAPITAL LETTER J CIRCUMFLEX;;;0135; +0135;LATIN SMALL LETTER J WITH CIRCUMFLEX;Ll;0;L;006A 0302;;;;N;LATIN SMALL LETTER J CIRCUMFLEX;;0134;;0134 +0136;LATIN CAPITAL LETTER K WITH CEDILLA;Lu;0;L;004B 0327;;;;N;LATIN CAPITAL LETTER K CEDILLA;;;0137; +0137;LATIN SMALL LETTER K WITH CEDILLA;Ll;0;L;006B 0327;;;;N;LATIN SMALL LETTER K CEDILLA;;0136;;0136 +0138;LATIN SMALL LETTER KRA;Ll;0;L;;;;;N;;Greenlandic;;; +0139;LATIN CAPITAL LETTER L WITH ACUTE;Lu;0;L;004C 0301;;;;N;LATIN CAPITAL LETTER L ACUTE;;;013A; +013A;LATIN SMALL LETTER L WITH ACUTE;Ll;0;L;006C 0301;;;;N;LATIN SMALL LETTER L ACUTE;;0139;;0139 +013B;LATIN CAPITAL LETTER L WITH CEDILLA;Lu;0;L;004C 0327;;;;N;LATIN CAPITAL LETTER L CEDILLA;;;013C; +013C;LATIN SMALL LETTER L WITH CEDILLA;Ll;0;L;006C 0327;;;;N;LATIN SMALL LETTER L CEDILLA;;013B;;013B +013D;LATIN CAPITAL LETTER L WITH CARON;Lu;0;L;004C 030C;;;;N;LATIN CAPITAL LETTER L HACEK;;;013E; +013E;LATIN SMALL LETTER L WITH CARON;Ll;0;L;006C 030C;;;;N;LATIN SMALL LETTER L HACEK;;013D;;013D +013F;LATIN CAPITAL LETTER L WITH MIDDLE DOT;Lu;0;L; 004C 00B7;;;;N;;;;0140; +0140;LATIN SMALL LETTER L WITH MIDDLE DOT;Ll;0;L; 006C 00B7;;;;N;;;013F;;013F +0141;LATIN CAPITAL LETTER L WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER L SLASH;;;0142; +0142;LATIN SMALL LETTER L WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER L SLASH;;0141;;0141 +0143;LATIN CAPITAL LETTER N WITH ACUTE;Lu;0;L;004E 0301;;;;N;LATIN CAPITAL LETTER N ACUTE;;;0144; +0144;LATIN SMALL LETTER N WITH ACUTE;Ll;0;L;006E 0301;;;;N;LATIN SMALL LETTER N ACUTE;;0143;;0143 +0145;LATIN CAPITAL LETTER N WITH CEDILLA;Lu;0;L;004E 0327;;;;N;LATIN CAPITAL LETTER N CEDILLA;;;0146; +0146;LATIN SMALL LETTER N WITH CEDILLA;Ll;0;L;006E 0327;;;;N;LATIN SMALL LETTER N CEDILLA;;0145;;0145 +0147;LATIN CAPITAL LETTER N WITH CARON;Lu;0;L;004E 030C;;;;N;LATIN CAPITAL LETTER N HACEK;;;0148; +0148;LATIN SMALL LETTER N WITH CARON;Ll;0;L;006E 030C;;;;N;LATIN SMALL LETTER N HACEK;;0147;;0147 +0149;LATIN SMALL LETTER N PRECEDED BY APOSTROPHE;Ll;0;L; 02BC 006E;;;;N;LATIN SMALL LETTER APOSTROPHE N;;;; +014A;LATIN CAPITAL LETTER ENG;Lu;0;L;;;;;N;;Sami;;014B; +014B;LATIN SMALL LETTER ENG;Ll;0;L;;;;;N;;Sami;014A;;014A +014C;LATIN CAPITAL LETTER O WITH MACRON;Lu;0;L;004F 0304;;;;N;LATIN CAPITAL LETTER O MACRON;;;014D; +014D;LATIN SMALL LETTER O WITH MACRON;Ll;0;L;006F 0304;;;;N;LATIN SMALL LETTER O MACRON;;014C;;014C +014E;LATIN CAPITAL LETTER O WITH BREVE;Lu;0;L;004F 0306;;;;N;LATIN CAPITAL LETTER O BREVE;;;014F; +014F;LATIN SMALL LETTER O WITH BREVE;Ll;0;L;006F 0306;;;;N;LATIN SMALL LETTER O BREVE;;014E;;014E +0150;LATIN CAPITAL LETTER O WITH DOUBLE ACUTE;Lu;0;L;004F 030B;;;;N;LATIN CAPITAL LETTER O DOUBLE ACUTE;;;0151; +0151;LATIN SMALL LETTER O WITH DOUBLE ACUTE;Ll;0;L;006F 030B;;;;N;LATIN SMALL LETTER O DOUBLE ACUTE;;0150;;0150 +0152;LATIN CAPITAL LIGATURE OE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O E;;;0153; +0153;LATIN SMALL LIGATURE OE;Ll;0;L;;;;;N;LATIN SMALL LETTER O E;;0152;;0152 +0154;LATIN CAPITAL LETTER R WITH ACUTE;Lu;0;L;0052 0301;;;;N;LATIN CAPITAL LETTER R ACUTE;;;0155; +0155;LATIN SMALL LETTER R WITH ACUTE;Ll;0;L;0072 0301;;;;N;LATIN SMALL LETTER R ACUTE;;0154;;0154 +0156;LATIN CAPITAL LETTER R WITH CEDILLA;Lu;0;L;0052 0327;;;;N;LATIN CAPITAL LETTER R CEDILLA;;;0157; +0157;LATIN SMALL LETTER R WITH CEDILLA;Ll;0;L;0072 0327;;;;N;LATIN SMALL LETTER R CEDILLA;;0156;;0156 +0158;LATIN CAPITAL LETTER R WITH CARON;Lu;0;L;0052 030C;;;;N;LATIN CAPITAL LETTER R HACEK;;;0159; +0159;LATIN SMALL LETTER R WITH CARON;Ll;0;L;0072 030C;;;;N;LATIN SMALL LETTER R HACEK;;0158;;0158 +015A;LATIN CAPITAL LETTER S WITH ACUTE;Lu;0;L;0053 0301;;;;N;LATIN CAPITAL LETTER S ACUTE;;;015B; +015B;LATIN SMALL LETTER S WITH ACUTE;Ll;0;L;0073 0301;;;;N;LATIN SMALL LETTER S ACUTE;;015A;;015A +015C;LATIN CAPITAL LETTER S WITH CIRCUMFLEX;Lu;0;L;0053 0302;;;;N;LATIN CAPITAL LETTER S CIRCUMFLEX;;;015D; +015D;LATIN SMALL LETTER S WITH CIRCUMFLEX;Ll;0;L;0073 0302;;;;N;LATIN SMALL LETTER S CIRCUMFLEX;;015C;;015C +015E;LATIN CAPITAL LETTER S WITH CEDILLA;Lu;0;L;0053 0327;;;;N;LATIN CAPITAL LETTER S CEDILLA;*;;015F; +015F;LATIN SMALL LETTER S WITH CEDILLA;Ll;0;L;0073 0327;;;;N;LATIN SMALL LETTER S CEDILLA;*;015E;;015E +0160;LATIN CAPITAL LETTER S WITH CARON;Lu;0;L;0053 030C;;;;N;LATIN CAPITAL LETTER S HACEK;;;0161; +0161;LATIN SMALL LETTER S WITH CARON;Ll;0;L;0073 030C;;;;N;LATIN SMALL LETTER S HACEK;;0160;;0160 +0162;LATIN CAPITAL LETTER T WITH CEDILLA;Lu;0;L;0054 0327;;;;N;LATIN CAPITAL LETTER T CEDILLA;*;;0163; +0163;LATIN SMALL LETTER T WITH CEDILLA;Ll;0;L;0074 0327;;;;N;LATIN SMALL LETTER T CEDILLA;*;0162;;0162 +0164;LATIN CAPITAL LETTER T WITH CARON;Lu;0;L;0054 030C;;;;N;LATIN CAPITAL LETTER T HACEK;;;0165; +0165;LATIN SMALL LETTER T WITH CARON;Ll;0;L;0074 030C;;;;N;LATIN SMALL LETTER T HACEK;;0164;;0164 +0166;LATIN CAPITAL LETTER T WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T BAR;;;0167; +0167;LATIN SMALL LETTER T WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER T BAR;;0166;;0166 +0168;LATIN CAPITAL LETTER U WITH TILDE;Lu;0;L;0055 0303;;;;N;LATIN CAPITAL LETTER U TILDE;;;0169; +0169;LATIN SMALL LETTER U WITH TILDE;Ll;0;L;0075 0303;;;;N;LATIN SMALL LETTER U TILDE;;0168;;0168 +016A;LATIN CAPITAL LETTER U WITH MACRON;Lu;0;L;0055 0304;;;;N;LATIN CAPITAL LETTER U MACRON;;;016B; +016B;LATIN SMALL LETTER U WITH MACRON;Ll;0;L;0075 0304;;;;N;LATIN SMALL LETTER U MACRON;;016A;;016A +016C;LATIN CAPITAL LETTER U WITH BREVE;Lu;0;L;0055 0306;;;;N;LATIN CAPITAL LETTER U BREVE;;;016D; +016D;LATIN SMALL LETTER U WITH BREVE;Ll;0;L;0075 0306;;;;N;LATIN SMALL LETTER U BREVE;;016C;;016C +016E;LATIN CAPITAL LETTER U WITH RING ABOVE;Lu;0;L;0055 030A;;;;N;LATIN CAPITAL LETTER U RING;;;016F; +016F;LATIN SMALL LETTER U WITH RING ABOVE;Ll;0;L;0075 030A;;;;N;LATIN SMALL LETTER U RING;;016E;;016E +0170;LATIN CAPITAL LETTER U WITH DOUBLE ACUTE;Lu;0;L;0055 030B;;;;N;LATIN CAPITAL LETTER U DOUBLE ACUTE;;;0171; +0171;LATIN SMALL LETTER U WITH DOUBLE ACUTE;Ll;0;L;0075 030B;;;;N;LATIN SMALL LETTER U DOUBLE ACUTE;;0170;;0170 +0172;LATIN CAPITAL LETTER U WITH OGONEK;Lu;0;L;0055 0328;;;;N;LATIN CAPITAL LETTER U OGONEK;;;0173; +0173;LATIN SMALL LETTER U WITH OGONEK;Ll;0;L;0075 0328;;;;N;LATIN SMALL LETTER U OGONEK;;0172;;0172 +0174;LATIN CAPITAL LETTER W WITH CIRCUMFLEX;Lu;0;L;0057 0302;;;;N;LATIN CAPITAL LETTER W CIRCUMFLEX;;;0175; +0175;LATIN SMALL LETTER W WITH CIRCUMFLEX;Ll;0;L;0077 0302;;;;N;LATIN SMALL LETTER W CIRCUMFLEX;;0174;;0174 +0176;LATIN CAPITAL LETTER Y WITH CIRCUMFLEX;Lu;0;L;0059 0302;;;;N;LATIN CAPITAL LETTER Y CIRCUMFLEX;;;0177; +0177;LATIN SMALL LETTER Y WITH CIRCUMFLEX;Ll;0;L;0079 0302;;;;N;LATIN SMALL LETTER Y CIRCUMFLEX;;0176;;0176 +0178;LATIN CAPITAL LETTER Y WITH DIAERESIS;Lu;0;L;0059 0308;;;;N;LATIN CAPITAL LETTER Y DIAERESIS;;;00FF; +0179;LATIN CAPITAL LETTER Z WITH ACUTE;Lu;0;L;005A 0301;;;;N;LATIN CAPITAL LETTER Z ACUTE;;;017A; +017A;LATIN SMALL LETTER Z WITH ACUTE;Ll;0;L;007A 0301;;;;N;LATIN SMALL LETTER Z ACUTE;;0179;;0179 +017B;LATIN CAPITAL LETTER Z WITH DOT ABOVE;Lu;0;L;005A 0307;;;;N;LATIN CAPITAL LETTER Z DOT;;;017C; +017C;LATIN SMALL LETTER Z WITH DOT ABOVE;Ll;0;L;007A 0307;;;;N;LATIN SMALL LETTER Z DOT;;017B;;017B +017D;LATIN CAPITAL LETTER Z WITH CARON;Lu;0;L;005A 030C;;;;N;LATIN CAPITAL LETTER Z HACEK;;;017E; +017E;LATIN SMALL LETTER Z WITH CARON;Ll;0;L;007A 030C;;;;N;LATIN SMALL LETTER Z HACEK;;017D;;017D +017F;LATIN SMALL LETTER LONG S;Ll;0;L; 0073;;;;N;;;0053;;0053 +0180;LATIN SMALL LETTER B WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER B BAR;;;; +0181;LATIN CAPITAL LETTER B WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER B HOOK;;;0253; +0182;LATIN CAPITAL LETTER B WITH TOPBAR;Lu;0;L;;;;;N;LATIN CAPITAL LETTER B TOPBAR;;;0183; +0183;LATIN SMALL LETTER B WITH TOPBAR;Ll;0;L;;;;;N;LATIN SMALL LETTER B TOPBAR;;0182;;0182 +0184;LATIN CAPITAL LETTER TONE SIX;Lu;0;L;;;;;N;;;;0185; +0185;LATIN SMALL LETTER TONE SIX;Ll;0;L;;;;;N;;;0184;;0184 +0186;LATIN CAPITAL LETTER OPEN O;Lu;0;L;;;;;N;;;;0254; +0187;LATIN CAPITAL LETTER C WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER C HOOK;;;0188; +0188;LATIN SMALL LETTER C WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER C HOOK;;0187;;0187 +0189;LATIN CAPITAL LETTER AFRICAN D;Lu;0;L;;;;;N;;*;;0256; +018A;LATIN CAPITAL LETTER D WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D HOOK;;;0257; +018B;LATIN CAPITAL LETTER D WITH TOPBAR;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D TOPBAR;;;018C; +018C;LATIN SMALL LETTER D WITH TOPBAR;Ll;0;L;;;;;N;LATIN SMALL LETTER D TOPBAR;;018B;;018B +018D;LATIN SMALL LETTER TURNED DELTA;Ll;0;L;;;;;N;;;;; +018E;LATIN CAPITAL LETTER REVERSED E;Lu;0;L;;;;;N;LATIN CAPITAL LETTER TURNED E;;;01DD; +018F;LATIN CAPITAL LETTER SCHWA;Lu;0;L;;;;;N;;;;0259; +0190;LATIN CAPITAL LETTER OPEN E;Lu;0;L;;;;;N;LATIN CAPITAL LETTER EPSILON;;;025B; +0191;LATIN CAPITAL LETTER F WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER F HOOK;;;0192; +0192;LATIN SMALL LETTER F WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT F;;0191;;0191 +0193;LATIN CAPITAL LETTER G WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G HOOK;;;0260; +0194;LATIN CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;0263; +0195;LATIN SMALL LETTER HV;Ll;0;L;;;;;N;LATIN SMALL LETTER H V;hwair;01F6;;01F6 +0196;LATIN CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;0269; +0197;LATIN CAPITAL LETTER I WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED I;;;0268; +0198;LATIN CAPITAL LETTER K WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER K HOOK;;;0199; +0199;LATIN SMALL LETTER K WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER K HOOK;;0198;;0198 +019A;LATIN SMALL LETTER L WITH BAR;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED L;;;; +019B;LATIN SMALL LETTER LAMBDA WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED LAMBDA;;;; +019C;LATIN CAPITAL LETTER TURNED M;Lu;0;L;;;;;N;;;;026F; +019D;LATIN CAPITAL LETTER N WITH LEFT HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER N HOOK;;;0272; +019E;LATIN SMALL LETTER N WITH LONG RIGHT LEG;Ll;0;L;;;;;N;;;0220;;0220 +019F;LATIN CAPITAL LETTER O WITH MIDDLE TILDE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED O;*;;0275; +01A0;LATIN CAPITAL LETTER O WITH HORN;Lu;0;L;004F 031B;;;;N;LATIN CAPITAL LETTER O HORN;;;01A1; +01A1;LATIN SMALL LETTER O WITH HORN;Ll;0;L;006F 031B;;;;N;LATIN SMALL LETTER O HORN;;01A0;;01A0 +01A2;LATIN CAPITAL LETTER OI;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O I;gha;;01A3; +01A3;LATIN SMALL LETTER OI;Ll;0;L;;;;;N;LATIN SMALL LETTER O I;gha;01A2;;01A2 +01A4;LATIN CAPITAL LETTER P WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER P HOOK;;;01A5; +01A5;LATIN SMALL LETTER P WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER P HOOK;;01A4;;01A4 +01A6;LATIN LETTER YR;Lu;0;L;;;;;N;LATIN LETTER Y R;*;;0280; +01A7;LATIN CAPITAL LETTER TONE TWO;Lu;0;L;;;;;N;;;;01A8; +01A8;LATIN SMALL LETTER TONE TWO;Ll;0;L;;;;;N;;;01A7;;01A7 +01A9;LATIN CAPITAL LETTER ESH;Lu;0;L;;;;;N;;;;0283; +01AA;LATIN LETTER REVERSED ESH LOOP;Ll;0;L;;;;;N;;;;; +01AB;LATIN SMALL LETTER T WITH PALATAL HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T PALATAL HOOK;;;; +01AC;LATIN CAPITAL LETTER T WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T HOOK;;;01AD; +01AD;LATIN SMALL LETTER T WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T HOOK;;01AC;;01AC +01AE;LATIN CAPITAL LETTER T WITH RETROFLEX HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T RETROFLEX HOOK;;;0288; +01AF;LATIN CAPITAL LETTER U WITH HORN;Lu;0;L;0055 031B;;;;N;LATIN CAPITAL LETTER U HORN;;;01B0; +01B0;LATIN SMALL LETTER U WITH HORN;Ll;0;L;0075 031B;;;;N;LATIN SMALL LETTER U HORN;;01AF;;01AF +01B1;LATIN CAPITAL LETTER UPSILON;Lu;0;L;;;;;N;;;;028A; +01B2;LATIN CAPITAL LETTER V WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER SCRIPT V;;;028B; +01B3;LATIN CAPITAL LETTER Y WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER Y HOOK;;;01B4; +01B4;LATIN SMALL LETTER Y WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Y HOOK;;01B3;;01B3 +01B5;LATIN CAPITAL LETTER Z WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER Z BAR;;;01B6; +01B6;LATIN SMALL LETTER Z WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER Z BAR;;01B5;;01B5 +01B7;LATIN CAPITAL LETTER EZH;Lu;0;L;;;;;N;LATIN CAPITAL LETTER YOGH;;;0292; +01B8;LATIN CAPITAL LETTER EZH REVERSED;Lu;0;L;;;;;N;LATIN CAPITAL LETTER REVERSED YOGH;;;01B9; +01B9;LATIN SMALL LETTER EZH REVERSED;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED YOGH;;01B8;;01B8 +01BA;LATIN SMALL LETTER EZH WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH WITH TAIL;;;; +01BB;LATIN LETTER TWO WITH STROKE;Lo;0;L;;;;;N;LATIN LETTER TWO BAR;;;; +01BC;LATIN CAPITAL LETTER TONE FIVE;Lu;0;L;;;;;N;;;;01BD; +01BD;LATIN SMALL LETTER TONE FIVE;Ll;0;L;;;;;N;;;01BC;;01BC +01BE;LATIN LETTER INVERTED GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER INVERTED GLOTTAL STOP BAR;;;; +01BF;LATIN LETTER WYNN;Ll;0;L;;;;;N;;;01F7;;01F7 +01C0;LATIN LETTER DENTAL CLICK;Lo;0;L;;;;;N;LATIN LETTER PIPE;;;; +01C1;LATIN LETTER LATERAL CLICK;Lo;0;L;;;;;N;LATIN LETTER DOUBLE PIPE;;;; +01C2;LATIN LETTER ALVEOLAR CLICK;Lo;0;L;;;;;N;LATIN LETTER PIPE DOUBLE BAR;;;; +01C3;LATIN LETTER RETROFLEX CLICK;Lo;0;L;;;;;N;LATIN LETTER EXCLAMATION MARK;;;; +01C4;LATIN CAPITAL LETTER DZ WITH CARON;Lu;0;L; 0044 017D;;;;N;LATIN CAPITAL LETTER D Z HACEK;;;01C6;01C5 +01C5;LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON;Lt;0;L; 0044 017E;;;;N;LATIN LETTER CAPITAL D SMALL Z HACEK;;01C4;01C6; +01C6;LATIN SMALL LETTER DZ WITH CARON;Ll;0;L; 0064 017E;;;;N;LATIN SMALL LETTER D Z HACEK;;01C4;;01C5 +01C7;LATIN CAPITAL LETTER LJ;Lu;0;L; 004C 004A;;;;N;LATIN CAPITAL LETTER L J;;;01C9;01C8 +01C8;LATIN CAPITAL LETTER L WITH SMALL LETTER J;Lt;0;L; 004C 006A;;;;N;LATIN LETTER CAPITAL L SMALL J;;01C7;01C9; +01C9;LATIN SMALL LETTER LJ;Ll;0;L; 006C 006A;;;;N;LATIN SMALL LETTER L J;;01C7;;01C8 +01CA;LATIN CAPITAL LETTER NJ;Lu;0;L; 004E 004A;;;;N;LATIN CAPITAL LETTER N J;;;01CC;01CB +01CB;LATIN CAPITAL LETTER N WITH SMALL LETTER J;Lt;0;L; 004E 006A;;;;N;LATIN LETTER CAPITAL N SMALL J;;01CA;01CC; +01CC;LATIN SMALL LETTER NJ;Ll;0;L; 006E 006A;;;;N;LATIN SMALL LETTER N J;;01CA;;01CB +01CD;LATIN CAPITAL LETTER A WITH CARON;Lu;0;L;0041 030C;;;;N;LATIN CAPITAL LETTER A HACEK;;;01CE; +01CE;LATIN SMALL LETTER A WITH CARON;Ll;0;L;0061 030C;;;;N;LATIN SMALL LETTER A HACEK;;01CD;;01CD +01CF;LATIN CAPITAL LETTER I WITH CARON;Lu;0;L;0049 030C;;;;N;LATIN CAPITAL LETTER I HACEK;;;01D0; +01D0;LATIN SMALL LETTER I WITH CARON;Ll;0;L;0069 030C;;;;N;LATIN SMALL LETTER I HACEK;;01CF;;01CF +01D1;LATIN CAPITAL LETTER O WITH CARON;Lu;0;L;004F 030C;;;;N;LATIN CAPITAL LETTER O HACEK;;;01D2; +01D2;LATIN SMALL LETTER O WITH CARON;Ll;0;L;006F 030C;;;;N;LATIN SMALL LETTER O HACEK;;01D1;;01D1 +01D3;LATIN CAPITAL LETTER U WITH CARON;Lu;0;L;0055 030C;;;;N;LATIN CAPITAL LETTER U HACEK;;;01D4; +01D4;LATIN SMALL LETTER U WITH CARON;Ll;0;L;0075 030C;;;;N;LATIN SMALL LETTER U HACEK;;01D3;;01D3 +01D5;LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON;Lu;0;L;00DC 0304;;;;N;LATIN CAPITAL LETTER U DIAERESIS MACRON;;;01D6; +01D6;LATIN SMALL LETTER U WITH DIAERESIS AND MACRON;Ll;0;L;00FC 0304;;;;N;LATIN SMALL LETTER U DIAERESIS MACRON;;01D5;;01D5 +01D7;LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE;Lu;0;L;00DC 0301;;;;N;LATIN CAPITAL LETTER U DIAERESIS ACUTE;;;01D8; +01D8;LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE;Ll;0;L;00FC 0301;;;;N;LATIN SMALL LETTER U DIAERESIS ACUTE;;01D7;;01D7 +01D9;LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON;Lu;0;L;00DC 030C;;;;N;LATIN CAPITAL LETTER U DIAERESIS HACEK;;;01DA; +01DA;LATIN SMALL LETTER U WITH DIAERESIS AND CARON;Ll;0;L;00FC 030C;;;;N;LATIN SMALL LETTER U DIAERESIS HACEK;;01D9;;01D9 +01DB;LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE;Lu;0;L;00DC 0300;;;;N;LATIN CAPITAL LETTER U DIAERESIS GRAVE;;;01DC; +01DC;LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE;Ll;0;L;00FC 0300;;;;N;LATIN SMALL LETTER U DIAERESIS GRAVE;;01DB;;01DB +01DD;LATIN SMALL LETTER TURNED E;Ll;0;L;;;;;N;;;018E;;018E +01DE;LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON;Lu;0;L;00C4 0304;;;;N;LATIN CAPITAL LETTER A DIAERESIS MACRON;;;01DF; +01DF;LATIN SMALL LETTER A WITH DIAERESIS AND MACRON;Ll;0;L;00E4 0304;;;;N;LATIN SMALL LETTER A DIAERESIS MACRON;;01DE;;01DE +01E0;LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON;Lu;0;L;0226 0304;;;;N;LATIN CAPITAL LETTER A DOT MACRON;;;01E1; +01E1;LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON;Ll;0;L;0227 0304;;;;N;LATIN SMALL LETTER A DOT MACRON;;01E0;;01E0 +01E2;LATIN CAPITAL LETTER AE WITH MACRON;Lu;0;L;00C6 0304;;;;N;LATIN CAPITAL LETTER A E MACRON;ash *;;01E3; +01E3;LATIN SMALL LETTER AE WITH MACRON;Ll;0;L;00E6 0304;;;;N;LATIN SMALL LETTER A E MACRON;ash *;01E2;;01E2 +01E4;LATIN CAPITAL LETTER G WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G BAR;;;01E5; +01E5;LATIN SMALL LETTER G WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER G BAR;;01E4;;01E4 +01E6;LATIN CAPITAL LETTER G WITH CARON;Lu;0;L;0047 030C;;;;N;LATIN CAPITAL LETTER G HACEK;;;01E7; +01E7;LATIN SMALL LETTER G WITH CARON;Ll;0;L;0067 030C;;;;N;LATIN SMALL LETTER G HACEK;;01E6;;01E6 +01E8;LATIN CAPITAL LETTER K WITH CARON;Lu;0;L;004B 030C;;;;N;LATIN CAPITAL LETTER K HACEK;;;01E9; +01E9;LATIN SMALL LETTER K WITH CARON;Ll;0;L;006B 030C;;;;N;LATIN SMALL LETTER K HACEK;;01E8;;01E8 +01EA;LATIN CAPITAL LETTER O WITH OGONEK;Lu;0;L;004F 0328;;;;N;LATIN CAPITAL LETTER O OGONEK;;;01EB; +01EB;LATIN SMALL LETTER O WITH OGONEK;Ll;0;L;006F 0328;;;;N;LATIN SMALL LETTER O OGONEK;;01EA;;01EA +01EC;LATIN CAPITAL LETTER O WITH OGONEK AND MACRON;Lu;0;L;01EA 0304;;;;N;LATIN CAPITAL LETTER O OGONEK MACRON;;;01ED; +01ED;LATIN SMALL LETTER O WITH OGONEK AND MACRON;Ll;0;L;01EB 0304;;;;N;LATIN SMALL LETTER O OGONEK MACRON;;01EC;;01EC +01EE;LATIN CAPITAL LETTER EZH WITH CARON;Lu;0;L;01B7 030C;;;;N;LATIN CAPITAL LETTER YOGH HACEK;;;01EF; +01EF;LATIN SMALL LETTER EZH WITH CARON;Ll;0;L;0292 030C;;;;N;LATIN SMALL LETTER YOGH HACEK;;01EE;;01EE +01F0;LATIN SMALL LETTER J WITH CARON;Ll;0;L;006A 030C;;;;N;LATIN SMALL LETTER J HACEK;;;; +01F1;LATIN CAPITAL LETTER DZ;Lu;0;L; 0044 005A;;;;N;;;;01F3;01F2 +01F2;LATIN CAPITAL LETTER D WITH SMALL LETTER Z;Lt;0;L; 0044 007A;;;;N;;;01F1;01F3; +01F3;LATIN SMALL LETTER DZ;Ll;0;L; 0064 007A;;;;N;;;01F1;;01F2 +01F4;LATIN CAPITAL LETTER G WITH ACUTE;Lu;0;L;0047 0301;;;;N;;;;01F5; +01F5;LATIN SMALL LETTER G WITH ACUTE;Ll;0;L;0067 0301;;;;N;;;01F4;;01F4 +01F6;LATIN CAPITAL LETTER HWAIR;Lu;0;L;;;;;N;;;;0195; +01F7;LATIN CAPITAL LETTER WYNN;Lu;0;L;;;;;N;;;;01BF; +01F8;LATIN CAPITAL LETTER N WITH GRAVE;Lu;0;L;004E 0300;;;;N;;;;01F9; +01F9;LATIN SMALL LETTER N WITH GRAVE;Ll;0;L;006E 0300;;;;N;;;01F8;;01F8 +01FA;LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE;Lu;0;L;00C5 0301;;;;N;;;;01FB; +01FB;LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE;Ll;0;L;00E5 0301;;;;N;;;01FA;;01FA +01FC;LATIN CAPITAL LETTER AE WITH ACUTE;Lu;0;L;00C6 0301;;;;N;;ash *;;01FD; +01FD;LATIN SMALL LETTER AE WITH ACUTE;Ll;0;L;00E6 0301;;;;N;;ash *;01FC;;01FC +01FE;LATIN CAPITAL LETTER O WITH STROKE AND ACUTE;Lu;0;L;00D8 0301;;;;N;;;;01FF; +01FF;LATIN SMALL LETTER O WITH STROKE AND ACUTE;Ll;0;L;00F8 0301;;;;N;;;01FE;;01FE +0200;LATIN CAPITAL LETTER A WITH DOUBLE GRAVE;Lu;0;L;0041 030F;;;;N;;;;0201; +0201;LATIN SMALL LETTER A WITH DOUBLE GRAVE;Ll;0;L;0061 030F;;;;N;;;0200;;0200 +0202;LATIN CAPITAL LETTER A WITH INVERTED BREVE;Lu;0;L;0041 0311;;;;N;;;;0203; +0203;LATIN SMALL LETTER A WITH INVERTED BREVE;Ll;0;L;0061 0311;;;;N;;;0202;;0202 +0204;LATIN CAPITAL LETTER E WITH DOUBLE GRAVE;Lu;0;L;0045 030F;;;;N;;;;0205; +0205;LATIN SMALL LETTER E WITH DOUBLE GRAVE;Ll;0;L;0065 030F;;;;N;;;0204;;0204 +0206;LATIN CAPITAL LETTER E WITH INVERTED BREVE;Lu;0;L;0045 0311;;;;N;;;;0207; +0207;LATIN SMALL LETTER E WITH INVERTED BREVE;Ll;0;L;0065 0311;;;;N;;;0206;;0206 +0208;LATIN CAPITAL LETTER I WITH DOUBLE GRAVE;Lu;0;L;0049 030F;;;;N;;;;0209; +0209;LATIN SMALL LETTER I WITH DOUBLE GRAVE;Ll;0;L;0069 030F;;;;N;;;0208;;0208 +020A;LATIN CAPITAL LETTER I WITH INVERTED BREVE;Lu;0;L;0049 0311;;;;N;;;;020B; +020B;LATIN SMALL LETTER I WITH INVERTED BREVE;Ll;0;L;0069 0311;;;;N;;;020A;;020A +020C;LATIN CAPITAL LETTER O WITH DOUBLE GRAVE;Lu;0;L;004F 030F;;;;N;;;;020D; +020D;LATIN SMALL LETTER O WITH DOUBLE GRAVE;Ll;0;L;006F 030F;;;;N;;;020C;;020C +020E;LATIN CAPITAL LETTER O WITH INVERTED BREVE;Lu;0;L;004F 0311;;;;N;;;;020F; +020F;LATIN SMALL LETTER O WITH INVERTED BREVE;Ll;0;L;006F 0311;;;;N;;;020E;;020E +0210;LATIN CAPITAL LETTER R WITH DOUBLE GRAVE;Lu;0;L;0052 030F;;;;N;;;;0211; +0211;LATIN SMALL LETTER R WITH DOUBLE GRAVE;Ll;0;L;0072 030F;;;;N;;;0210;;0210 +0212;LATIN CAPITAL LETTER R WITH INVERTED BREVE;Lu;0;L;0052 0311;;;;N;;;;0213; +0213;LATIN SMALL LETTER R WITH INVERTED BREVE;Ll;0;L;0072 0311;;;;N;;;0212;;0212 +0214;LATIN CAPITAL LETTER U WITH DOUBLE GRAVE;Lu;0;L;0055 030F;;;;N;;;;0215; +0215;LATIN SMALL LETTER U WITH DOUBLE GRAVE;Ll;0;L;0075 030F;;;;N;;;0214;;0214 +0216;LATIN CAPITAL LETTER U WITH INVERTED BREVE;Lu;0;L;0055 0311;;;;N;;;;0217; +0217;LATIN SMALL LETTER U WITH INVERTED BREVE;Ll;0;L;0075 0311;;;;N;;;0216;;0216 +0218;LATIN CAPITAL LETTER S WITH COMMA BELOW;Lu;0;L;0053 0326;;;;N;;*;;0219; +0219;LATIN SMALL LETTER S WITH COMMA BELOW;Ll;0;L;0073 0326;;;;N;;*;0218;;0218 +021A;LATIN CAPITAL LETTER T WITH COMMA BELOW;Lu;0;L;0054 0326;;;;N;;*;;021B; +021B;LATIN SMALL LETTER T WITH COMMA BELOW;Ll;0;L;0074 0326;;;;N;;*;021A;;021A +021C;LATIN CAPITAL LETTER YOGH;Lu;0;L;;;;;N;;;;021D; +021D;LATIN SMALL LETTER YOGH;Ll;0;L;;;;;N;;;021C;;021C +021E;LATIN CAPITAL LETTER H WITH CARON;Lu;0;L;0048 030C;;;;N;;;;021F; +021F;LATIN SMALL LETTER H WITH CARON;Ll;0;L;0068 030C;;;;N;;;021E;;021E +0220;LATIN CAPITAL LETTER N WITH LONG RIGHT LEG;Lu;0;L;;;;;N;;;;019E; +0222;LATIN CAPITAL LETTER OU;Lu;0;L;;;;;N;;;;0223; +0223;LATIN SMALL LETTER OU;Ll;0;L;;;;;N;;;0222;;0222 +0224;LATIN CAPITAL LETTER Z WITH HOOK;Lu;0;L;;;;;N;;;;0225; +0225;LATIN SMALL LETTER Z WITH HOOK;Ll;0;L;;;;;N;;;0224;;0224 +0226;LATIN CAPITAL LETTER A WITH DOT ABOVE;Lu;0;L;0041 0307;;;;N;;;;0227; +0227;LATIN SMALL LETTER A WITH DOT ABOVE;Ll;0;L;0061 0307;;;;N;;;0226;;0226 +0228;LATIN CAPITAL LETTER E WITH CEDILLA;Lu;0;L;0045 0327;;;;N;;;;0229; +0229;LATIN SMALL LETTER E WITH CEDILLA;Ll;0;L;0065 0327;;;;N;;;0228;;0228 +022A;LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON;Lu;0;L;00D6 0304;;;;N;;;;022B; +022B;LATIN SMALL LETTER O WITH DIAERESIS AND MACRON;Ll;0;L;00F6 0304;;;;N;;;022A;;022A +022C;LATIN CAPITAL LETTER O WITH TILDE AND MACRON;Lu;0;L;00D5 0304;;;;N;;;;022D; +022D;LATIN SMALL LETTER O WITH TILDE AND MACRON;Ll;0;L;00F5 0304;;;;N;;;022C;;022C +022E;LATIN CAPITAL LETTER O WITH DOT ABOVE;Lu;0;L;004F 0307;;;;N;;;;022F; +022F;LATIN SMALL LETTER O WITH DOT ABOVE;Ll;0;L;006F 0307;;;;N;;;022E;;022E +0230;LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON;Lu;0;L;022E 0304;;;;N;;;;0231; +0231;LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON;Ll;0;L;022F 0304;;;;N;;;0230;;0230 +0232;LATIN CAPITAL LETTER Y WITH MACRON;Lu;0;L;0059 0304;;;;N;;;;0233; +0233;LATIN SMALL LETTER Y WITH MACRON;Ll;0;L;0079 0304;;;;N;;;0232;;0232 +0250;LATIN SMALL LETTER TURNED A;Ll;0;L;;;;;N;;;;; +0251;LATIN SMALL LETTER ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT A;;;; +0252;LATIN SMALL LETTER TURNED ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED SCRIPT A;;;; +0253;LATIN SMALL LETTER B WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER B HOOK;;0181;;0181 +0254;LATIN SMALL LETTER OPEN O;Ll;0;L;;;;;N;;;0186;;0186 +0255;LATIN SMALL LETTER C WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER C CURL;;;; +0256;LATIN SMALL LETTER D WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER D RETROFLEX HOOK;;0189;;0189 +0257;LATIN SMALL LETTER D WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER D HOOK;;018A;;018A +0258;LATIN SMALL LETTER REVERSED E;Ll;0;L;;;;;N;;;;; +0259;LATIN SMALL LETTER SCHWA;Ll;0;L;;;;;N;;;018F;;018F +025A;LATIN SMALL LETTER SCHWA WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCHWA HOOK;;;; +025B;LATIN SMALL LETTER OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER EPSILON;;0190;;0190 +025C;LATIN SMALL LETTER REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON;;;; +025D;LATIN SMALL LETTER REVERSED OPEN E WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON HOOK;;;; +025E;LATIN SMALL LETTER CLOSED REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED REVERSED EPSILON;;;; +025F;LATIN SMALL LETTER DOTLESS J WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR;;;; +0260;LATIN SMALL LETTER G WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER G HOOK;;0193;;0193 +0261;LATIN SMALL LETTER SCRIPT G;Ll;0;L;;;;;N;;;;; +0262;LATIN LETTER SMALL CAPITAL G;Ll;0;L;;;;;N;;;;; +0263;LATIN SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0194;;0194 +0264;LATIN SMALL LETTER RAMS HORN;Ll;0;L;;;;;N;LATIN SMALL LETTER BABY GAMMA;;;; +0265;LATIN SMALL LETTER TURNED H;Ll;0;L;;;;;N;;;;; +0266;LATIN SMALL LETTER H WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER H HOOK;;;; +0267;LATIN SMALL LETTER HENG WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER HENG HOOK;;;; +0268;LATIN SMALL LETTER I WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED I;;0197;;0197 +0269;LATIN SMALL LETTER IOTA;Ll;0;L;;;;;N;;;0196;;0196 +026A;LATIN LETTER SMALL CAPITAL I;Ll;0;L;;;;;N;;;;; +026B;LATIN SMALL LETTER L WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +026C;LATIN SMALL LETTER L WITH BELT;Ll;0;L;;;;;N;LATIN SMALL LETTER L BELT;;;; +026D;LATIN SMALL LETTER L WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER L RETROFLEX HOOK;;;; +026E;LATIN SMALL LETTER LEZH;Ll;0;L;;;;;N;LATIN SMALL LETTER L YOGH;;;; +026F;LATIN SMALL LETTER TURNED M;Ll;0;L;;;;;N;;;019C;;019C +0270;LATIN SMALL LETTER TURNED M WITH LONG LEG;Ll;0;L;;;;;N;;;;; +0271;LATIN SMALL LETTER M WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER M HOOK;;;; +0272;LATIN SMALL LETTER N WITH LEFT HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER N HOOK;;019D;;019D +0273;LATIN SMALL LETTER N WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER N RETROFLEX HOOK;;;; +0274;LATIN LETTER SMALL CAPITAL N;Ll;0;L;;;;;N;;;;; +0275;LATIN SMALL LETTER BARRED O;Ll;0;L;;;;;N;;;019F;;019F +0276;LATIN LETTER SMALL CAPITAL OE;Ll;0;L;;;;;N;LATIN LETTER SMALL CAPITAL O E;;;; +0277;LATIN SMALL LETTER CLOSED OMEGA;Ll;0;L;;;;;N;;;;; +0278;LATIN SMALL LETTER PHI;Ll;0;L;;;;;N;;;;; +0279;LATIN SMALL LETTER TURNED R;Ll;0;L;;;;;N;;;;; +027A;LATIN SMALL LETTER TURNED R WITH LONG LEG;Ll;0;L;;;;;N;;;;; +027B;LATIN SMALL LETTER TURNED R WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED R HOOK;;;; +027C;LATIN SMALL LETTER R WITH LONG LEG;Ll;0;L;;;;;N;;;;; +027D;LATIN SMALL LETTER R WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER R HOOK;;;; +027E;LATIN SMALL LETTER R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER FISHHOOK R;;;; +027F;LATIN SMALL LETTER REVERSED R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED FISHHOOK R;;;; +0280;LATIN LETTER SMALL CAPITAL R;Ll;0;L;;;;;N;;*;01A6;;01A6 +0281;LATIN LETTER SMALL CAPITAL INVERTED R;Ll;0;L;;;;;N;;;;; +0282;LATIN SMALL LETTER S WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER S HOOK;;;; +0283;LATIN SMALL LETTER ESH;Ll;0;L;;;;;N;;;01A9;;01A9 +0284;LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR HOOK;;;; +0285;LATIN SMALL LETTER SQUAT REVERSED ESH;Ll;0;L;;;;;N;;;;; +0286;LATIN SMALL LETTER ESH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER ESH CURL;;;; +0287;LATIN SMALL LETTER TURNED T;Ll;0;L;;;;;N;;;;; +0288;LATIN SMALL LETTER T WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T RETROFLEX HOOK;;01AE;;01AE +0289;LATIN SMALL LETTER U BAR;Ll;0;L;;;;;N;;;;; +028A;LATIN SMALL LETTER UPSILON;Ll;0;L;;;;;N;;;01B1;;01B1 +028B;LATIN SMALL LETTER V WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT V;;01B2;;01B2 +028C;LATIN SMALL LETTER TURNED V;Ll;0;L;;;;;N;;;;; +028D;LATIN SMALL LETTER TURNED W;Ll;0;L;;;;;N;;;;; +028E;LATIN SMALL LETTER TURNED Y;Ll;0;L;;;;;N;;;;; +028F;LATIN LETTER SMALL CAPITAL Y;Ll;0;L;;;;;N;;;;; +0290;LATIN SMALL LETTER Z WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Z RETROFLEX HOOK;;;; +0291;LATIN SMALL LETTER Z WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER Z CURL;;;; +0292;LATIN SMALL LETTER EZH;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH;;01B7;;01B7 +0293;LATIN SMALL LETTER EZH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH CURL;;;; +0294;LATIN LETTER GLOTTAL STOP;Ll;0;L;;;;;N;;;;; +0295;LATIN LETTER PHARYNGEAL VOICED FRICATIVE;Ll;0;L;;;;;N;LATIN LETTER REVERSED GLOTTAL STOP;;;; +0296;LATIN LETTER INVERTED GLOTTAL STOP;Ll;0;L;;;;;N;;;;; +0297;LATIN LETTER STRETCHED C;Ll;0;L;;;;;N;;;;; +0298;LATIN LETTER BILABIAL CLICK;Ll;0;L;;;;;N;LATIN LETTER BULLSEYE;;;; +0299;LATIN LETTER SMALL CAPITAL B;Ll;0;L;;;;;N;;;;; +029A;LATIN SMALL LETTER CLOSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED EPSILON;;;; +029B;LATIN LETTER SMALL CAPITAL G WITH HOOK;Ll;0;L;;;;;N;LATIN LETTER SMALL CAPITAL G HOOK;;;; +029C;LATIN LETTER SMALL CAPITAL H;Ll;0;L;;;;;N;;;;; +029D;LATIN SMALL LETTER J WITH CROSSED-TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER CROSSED-TAIL J;;;; +029E;LATIN SMALL LETTER TURNED K;Ll;0;L;;;;;N;;;;; +029F;LATIN LETTER SMALL CAPITAL L;Ll;0;L;;;;;N;;;;; +02A0;LATIN SMALL LETTER Q WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Q HOOK;;;; +02A1;LATIN LETTER GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER GLOTTAL STOP BAR;;;; +02A2;LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER REVERSED GLOTTAL STOP BAR;;;; +02A3;LATIN SMALL LETTER DZ DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER D Z;;;; +02A4;LATIN SMALL LETTER DEZH DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER D YOGH;;;; +02A5;LATIN SMALL LETTER DZ DIGRAPH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER D Z CURL;;;; +02A6;LATIN SMALL LETTER TS DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER T S;;;; +02A7;LATIN SMALL LETTER TESH DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER T ESH;;;; +02A8;LATIN SMALL LETTER TC DIGRAPH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER T C CURL;;;; +02A9;LATIN SMALL LETTER FENG DIGRAPH;Ll;0;L;;;;;N;;;;; +02AA;LATIN SMALL LETTER LS DIGRAPH;Ll;0;L;;;;;N;;;;; +02AB;LATIN SMALL LETTER LZ DIGRAPH;Ll;0;L;;;;;N;;;;; +02AC;LATIN LETTER BILABIAL PERCUSSIVE;Ll;0;L;;;;;N;;;;; +02AD;LATIN LETTER BIDENTAL PERCUSSIVE;Ll;0;L;;;;;N;;;;; +02B0;MODIFIER LETTER SMALL H;Lm;0;L; 0068;;;;N;;;;; +02B1;MODIFIER LETTER SMALL H WITH HOOK;Lm;0;L; 0266;;;;N;MODIFIER LETTER SMALL H HOOK;;;; +02B2;MODIFIER LETTER SMALL J;Lm;0;L; 006A;;;;N;;;;; +02B3;MODIFIER LETTER SMALL R;Lm;0;L; 0072;;;;N;;;;; +02B4;MODIFIER LETTER SMALL TURNED R;Lm;0;L; 0279;;;;N;;;;; +02B5;MODIFIER LETTER SMALL TURNED R WITH HOOK;Lm;0;L; 027B;;;;N;MODIFIER LETTER SMALL TURNED R HOOK;;;; +02B6;MODIFIER LETTER SMALL CAPITAL INVERTED R;Lm;0;L; 0281;;;;N;;;;; +02B7;MODIFIER LETTER SMALL W;Lm;0;L; 0077;;;;N;;;;; +02B8;MODIFIER LETTER SMALL Y;Lm;0;L; 0079;;;;N;;;;; +02B9;MODIFIER LETTER PRIME;Sk;0;ON;;;;;N;;;;; +02BA;MODIFIER LETTER DOUBLE PRIME;Sk;0;ON;;;;;N;;;;; +02BB;MODIFIER LETTER TURNED COMMA;Lm;0;L;;;;;N;;;;; +02BC;MODIFIER LETTER APOSTROPHE;Lm;0;L;;;;;N;;;;; +02BD;MODIFIER LETTER REVERSED COMMA;Lm;0;L;;;;;N;;;;; +02BE;MODIFIER LETTER RIGHT HALF RING;Lm;0;L;;;;;N;;;;; +02BF;MODIFIER LETTER LEFT HALF RING;Lm;0;L;;;;;N;;;;; +02C0;MODIFIER LETTER GLOTTAL STOP;Lm;0;L;;;;;N;;;;; +02C1;MODIFIER LETTER REVERSED GLOTTAL STOP;Lm;0;L;;;;;N;;;;; +02C2;MODIFIER LETTER LEFT ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02C3;MODIFIER LETTER RIGHT ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02C4;MODIFIER LETTER UP ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02C5;MODIFIER LETTER DOWN ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02C6;MODIFIER LETTER CIRCUMFLEX ACCENT;Sk;0;ON;;;;;N;MODIFIER LETTER CIRCUMFLEX;;;; +02C7;CARON;Sk;0;ON;;;;;N;MODIFIER LETTER HACEK;Mandarin Chinese third tone;;; +02C8;MODIFIER LETTER VERTICAL LINE;Sk;0;ON;;;;;N;;;;; +02C9;MODIFIER LETTER MACRON;Sk;0;ON;;;;;N;;Mandarin Chinese first tone;;; +02CA;MODIFIER LETTER ACUTE ACCENT;Sk;0;ON;;;;;N;MODIFIER LETTER ACUTE;Mandarin Chinese second tone;;; +02CB;MODIFIER LETTER GRAVE ACCENT;Sk;0;ON;;;;;N;MODIFIER LETTER GRAVE;Mandarin Chinese fourth tone;;; +02CC;MODIFIER LETTER LOW VERTICAL LINE;Sk;0;ON;;;;;N;;;;; +02CD;MODIFIER LETTER LOW MACRON;Sk;0;ON;;;;;N;;;;; +02CE;MODIFIER LETTER LOW GRAVE ACCENT;Sk;0;ON;;;;;N;MODIFIER LETTER LOW GRAVE;;;; +02CF;MODIFIER LETTER LOW ACUTE ACCENT;Sk;0;ON;;;;;N;MODIFIER LETTER LOW ACUTE;;;; +02D0;MODIFIER LETTER TRIANGULAR COLON;Lm;0;L;;;;;N;;;;; +02D1;MODIFIER LETTER HALF TRIANGULAR COLON;Lm;0;L;;;;;N;;;;; +02D2;MODIFIER LETTER CENTRED RIGHT HALF RING;Sk;0;ON;;;;;N;MODIFIER LETTER CENTERED RIGHT HALF RING;;;; +02D3;MODIFIER LETTER CENTRED LEFT HALF RING;Sk;0;ON;;;;;N;MODIFIER LETTER CENTERED LEFT HALF RING;;;; +02D4;MODIFIER LETTER UP TACK;Sk;0;ON;;;;;N;;;;; +02D5;MODIFIER LETTER DOWN TACK;Sk;0;ON;;;;;N;;;;; +02D6;MODIFIER LETTER PLUS SIGN;Sk;0;ON;;;;;N;;;;; +02D7;MODIFIER LETTER MINUS SIGN;Sk;0;ON;;;;;N;;;;; +02D8;BREVE;Sk;0;ON; 0020 0306;;;;N;SPACING BREVE;;;; +02D9;DOT ABOVE;Sk;0;ON; 0020 0307;;;;N;SPACING DOT ABOVE;Mandarin Chinese light tone;;; +02DA;RING ABOVE;Sk;0;ON; 0020 030A;;;;N;SPACING RING ABOVE;;;; +02DB;OGONEK;Sk;0;ON; 0020 0328;;;;N;SPACING OGONEK;;;; +02DC;SMALL TILDE;Sk;0;ON; 0020 0303;;;;N;SPACING TILDE;;;; +02DD;DOUBLE ACUTE ACCENT;Sk;0;ON; 0020 030B;;;;N;SPACING DOUBLE ACUTE;;;; +02DE;MODIFIER LETTER RHOTIC HOOK;Sk;0;ON;;;;;N;;;;; +02DF;MODIFIER LETTER CROSS ACCENT;Sk;0;ON;;;;;N;;;;; +02E0;MODIFIER LETTER SMALL GAMMA;Lm;0;L; 0263;;;;N;;;;; +02E1;MODIFIER LETTER SMALL L;Lm;0;L; 006C;;;;N;;;;; +02E2;MODIFIER LETTER SMALL S;Lm;0;L; 0073;;;;N;;;;; +02E3;MODIFIER LETTER SMALL X;Lm;0;L; 0078;;;;N;;;;; +02E4;MODIFIER LETTER SMALL REVERSED GLOTTAL STOP;Lm;0;L; 0295;;;;N;;;;; +02E5;MODIFIER LETTER EXTRA-HIGH TONE BAR;Sk;0;ON;;;;;N;;;;; +02E6;MODIFIER LETTER HIGH TONE BAR;Sk;0;ON;;;;;N;;;;; +02E7;MODIFIER LETTER MID TONE BAR;Sk;0;ON;;;;;N;;;;; +02E8;MODIFIER LETTER LOW TONE BAR;Sk;0;ON;;;;;N;;;;; +02E9;MODIFIER LETTER EXTRA-LOW TONE BAR;Sk;0;ON;;;;;N;;;;; +02EA;MODIFIER LETTER YIN DEPARTING TONE MARK;Sk;0;ON;;;;;N;;;;; +02EB;MODIFIER LETTER YANG DEPARTING TONE MARK;Sk;0;ON;;;;;N;;;;; +02EC;MODIFIER LETTER VOICING;Sk;0;ON;;;;;N;;;;; +02ED;MODIFIER LETTER UNASPIRATED;Sk;0;ON;;;;;N;;;;; +02EE;MODIFIER LETTER DOUBLE APOSTROPHE;Lm;0;L;;;;;N;;;;; +0300;COMBINING GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING GRAVE;Varia;;; +0301;COMBINING ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING ACUTE;Oxia, Tonos;;; +0302;COMBINING CIRCUMFLEX ACCENT;Mn;230;NSM;;;;;N;NON-SPACING CIRCUMFLEX;;;; +0303;COMBINING TILDE;Mn;230;NSM;;;;;N;NON-SPACING TILDE;;;; +0304;COMBINING MACRON;Mn;230;NSM;;;;;N;NON-SPACING MACRON;;;; +0305;COMBINING OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING OVERSCORE;;;; +0306;COMBINING BREVE;Mn;230;NSM;;;;;N;NON-SPACING BREVE;Vrachy;;; +0307;COMBINING DOT ABOVE;Mn;230;NSM;;;;;N;NON-SPACING DOT ABOVE;;;; +0308;COMBINING DIAERESIS;Mn;230;NSM;;;;;N;NON-SPACING DIAERESIS;Dialytika;;; +0309;COMBINING HOOK ABOVE;Mn;230;NSM;;;;;N;NON-SPACING HOOK ABOVE;;;; +030A;COMBINING RING ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RING ABOVE;;;; +030B;COMBINING DOUBLE ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE ACUTE;;;; +030C;COMBINING CARON;Mn;230;NSM;;;;;N;NON-SPACING HACEK;;;; +030D;COMBINING VERTICAL LINE ABOVE;Mn;230;NSM;;;;;N;NON-SPACING VERTICAL LINE ABOVE;;;; +030E;COMBINING DOUBLE VERTICAL LINE ABOVE;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE VERTICAL LINE ABOVE;;;; +030F;COMBINING DOUBLE GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE GRAVE;;;; +0310;COMBINING CANDRABINDU;Mn;230;NSM;;;;;N;NON-SPACING CANDRABINDU;;;; +0311;COMBINING INVERTED BREVE;Mn;230;NSM;;;;;N;NON-SPACING INVERTED BREVE;;;; +0312;COMBINING TURNED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING TURNED COMMA ABOVE;;;; +0313;COMBINING COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING COMMA ABOVE;Psili;;; +0314;COMBINING REVERSED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING REVERSED COMMA ABOVE;Dasia;;; +0315;COMBINING COMMA ABOVE RIGHT;Mn;232;NSM;;;;;N;NON-SPACING COMMA ABOVE RIGHT;;;; +0316;COMBINING GRAVE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING GRAVE BELOW;;;; +0317;COMBINING ACUTE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING ACUTE BELOW;;;; +0318;COMBINING LEFT TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING LEFT TACK BELOW;;;; +0319;COMBINING RIGHT TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING RIGHT TACK BELOW;;;; +031A;COMBINING LEFT ANGLE ABOVE;Mn;232;NSM;;;;;N;NON-SPACING LEFT ANGLE ABOVE;;;; +031B;COMBINING HORN;Mn;216;NSM;;;;;N;NON-SPACING HORN;;;; +031C;COMBINING LEFT HALF RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING LEFT HALF RING BELOW;;;; +031D;COMBINING UP TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING UP TACK BELOW;;;; +031E;COMBINING DOWN TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOWN TACK BELOW;;;; +031F;COMBINING PLUS SIGN BELOW;Mn;220;NSM;;;;;N;NON-SPACING PLUS SIGN BELOW;;;; +0320;COMBINING MINUS SIGN BELOW;Mn;220;NSM;;;;;N;NON-SPACING MINUS SIGN BELOW;;;; +0321;COMBINING PALATALIZED HOOK BELOW;Mn;202;NSM;;;;;N;NON-SPACING PALATALIZED HOOK BELOW;;;; +0322;COMBINING RETROFLEX HOOK BELOW;Mn;202;NSM;;;;;N;NON-SPACING RETROFLEX HOOK BELOW;;;; +0323;COMBINING DOT BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOT BELOW;;;; +0324;COMBINING DIAERESIS BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOUBLE DOT BELOW;;;; +0325;COMBINING RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING RING BELOW;;;; +0326;COMBINING COMMA BELOW;Mn;220;NSM;;;;;N;NON-SPACING COMMA BELOW;;;; +0327;COMBINING CEDILLA;Mn;202;NSM;;;;;N;NON-SPACING CEDILLA;;;; +0328;COMBINING OGONEK;Mn;202;NSM;;;;;N;NON-SPACING OGONEK;;;; +0329;COMBINING VERTICAL LINE BELOW;Mn;220;NSM;;;;;N;NON-SPACING VERTICAL LINE BELOW;;;; +032A;COMBINING BRIDGE BELOW;Mn;220;NSM;;;;;N;NON-SPACING BRIDGE BELOW;;;; +032B;COMBINING INVERTED DOUBLE ARCH BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED DOUBLE ARCH BELOW;;;; +032C;COMBINING CARON BELOW;Mn;220;NSM;;;;;N;NON-SPACING HACEK BELOW;;;; +032D;COMBINING CIRCUMFLEX ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING CIRCUMFLEX BELOW;;;; +032E;COMBINING BREVE BELOW;Mn;220;NSM;;;;;N;NON-SPACING BREVE BELOW;;;; +032F;COMBINING INVERTED BREVE BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED BREVE BELOW;;;; +0330;COMBINING TILDE BELOW;Mn;220;NSM;;;;;N;NON-SPACING TILDE BELOW;;;; +0331;COMBINING MACRON BELOW;Mn;220;NSM;;;;;N;NON-SPACING MACRON BELOW;;;; +0332;COMBINING LOW LINE;Mn;220;NSM;;;;;N;NON-SPACING UNDERSCORE;;;; +0333;COMBINING DOUBLE LOW LINE;Mn;220;NSM;;;;;N;NON-SPACING DOUBLE UNDERSCORE;;;; +0334;COMBINING TILDE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING TILDE OVERLAY;;;; +0335;COMBINING SHORT STROKE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT BAR OVERLAY;;;; +0336;COMBINING LONG STROKE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG BAR OVERLAY;;;; +0337;COMBINING SHORT SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT SLASH OVERLAY;;;; +0338;COMBINING LONG SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG SLASH OVERLAY;;;; +0339;COMBINING RIGHT HALF RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING RIGHT HALF RING BELOW;;;; +033A;COMBINING INVERTED BRIDGE BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED BRIDGE BELOW;;;; +033B;COMBINING SQUARE BELOW;Mn;220;NSM;;;;;N;NON-SPACING SQUARE BELOW;;;; +033C;COMBINING SEAGULL BELOW;Mn;220;NSM;;;;;N;NON-SPACING SEAGULL BELOW;;;; +033D;COMBINING X ABOVE;Mn;230;NSM;;;;;N;NON-SPACING X ABOVE;;;; +033E;COMBINING VERTICAL TILDE;Mn;230;NSM;;;;;N;NON-SPACING VERTICAL TILDE;;;; +033F;COMBINING DOUBLE OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE OVERSCORE;;;; +0340;COMBINING GRAVE TONE MARK;Mn;230;NSM;0300;;;;N;NON-SPACING GRAVE TONE MARK;Vietnamese;;; +0341;COMBINING ACUTE TONE MARK;Mn;230;NSM;0301;;;;N;NON-SPACING ACUTE TONE MARK;Vietnamese;;; +0342;COMBINING GREEK PERISPOMENI;Mn;230;NSM;;;;;N;;;;; +0343;COMBINING GREEK KORONIS;Mn;230;NSM;0313;;;;N;;;;; +0344;COMBINING GREEK DIALYTIKA TONOS;Mn;230;NSM;0308 0301;;;;N;GREEK NON-SPACING DIAERESIS TONOS;;;; +0345;COMBINING GREEK YPOGEGRAMMENI;Mn;240;NSM;;;;;N;GREEK NON-SPACING IOTA BELOW;;0399;;0399 +0346;COMBINING BRIDGE ABOVE;Mn;230;NSM;;;;;N;;;;; +0347;COMBINING EQUALS SIGN BELOW;Mn;220;NSM;;;;;N;;;;; +0348;COMBINING DOUBLE VERTICAL LINE BELOW;Mn;220;NSM;;;;;N;;;;; +0349;COMBINING LEFT ANGLE BELOW;Mn;220;NSM;;;;;N;;;;; +034A;COMBINING NOT TILDE ABOVE;Mn;230;NSM;;;;;N;;;;; +034B;COMBINING HOMOTHETIC ABOVE;Mn;230;NSM;;;;;N;;;;; +034C;COMBINING ALMOST EQUAL TO ABOVE;Mn;230;NSM;;;;;N;;;;; +034D;COMBINING LEFT RIGHT ARROW BELOW;Mn;220;NSM;;;;;N;;;;; +034E;COMBINING UPWARDS ARROW BELOW;Mn;220;NSM;;;;;N;;;;; +034F;COMBINING GRAPHEME JOINER;Mn;0;NSM;;;;;N;;;;; +0360;COMBINING DOUBLE TILDE;Mn;234;NSM;;;;;N;;;;; +0361;COMBINING DOUBLE INVERTED BREVE;Mn;234;NSM;;;;;N;;;;; +0362;COMBINING DOUBLE RIGHTWARDS ARROW BELOW;Mn;233;NSM;;;;;N;;;;; +0363;COMBINING LATIN SMALL LETTER A;Mn;230;NSM;;;;;N;;;;; +0364;COMBINING LATIN SMALL LETTER E;Mn;230;NSM;;;;;N;;;;; +0365;COMBINING LATIN SMALL LETTER I;Mn;230;NSM;;;;;N;;;;; +0366;COMBINING LATIN SMALL LETTER O;Mn;230;NSM;;;;;N;;;;; +0367;COMBINING LATIN SMALL LETTER U;Mn;230;NSM;;;;;N;;;;; +0368;COMBINING LATIN SMALL LETTER C;Mn;230;NSM;;;;;N;;;;; +0369;COMBINING LATIN SMALL LETTER D;Mn;230;NSM;;;;;N;;;;; +036A;COMBINING LATIN SMALL LETTER H;Mn;230;NSM;;;;;N;;;;; +036B;COMBINING LATIN SMALL LETTER M;Mn;230;NSM;;;;;N;;;;; +036C;COMBINING LATIN SMALL LETTER R;Mn;230;NSM;;;;;N;;;;; +036D;COMBINING LATIN SMALL LETTER T;Mn;230;NSM;;;;;N;;;;; +036E;COMBINING LATIN SMALL LETTER V;Mn;230;NSM;;;;;N;;;;; +036F;COMBINING LATIN SMALL LETTER X;Mn;230;NSM;;;;;N;;;;; +0374;GREEK NUMERAL SIGN;Sk;0;ON;02B9;;;;N;GREEK UPPER NUMERAL SIGN;Dexia keraia;;; +0375;GREEK LOWER NUMERAL SIGN;Sk;0;ON;;;;;N;;Aristeri keraia;;; +037A;GREEK YPOGEGRAMMENI;Lm;0;L; 0020 0345;;;;N;GREEK SPACING IOTA BELOW;;;; +037E;GREEK QUESTION MARK;Po;0;ON;003B;;;;N;;Erotimatiko;;; +0384;GREEK TONOS;Sk;0;ON; 0020 0301;;;;N;GREEK SPACING TONOS;;;; +0385;GREEK DIALYTIKA TONOS;Sk;0;ON;00A8 0301;;;;N;GREEK SPACING DIAERESIS TONOS;;;; +0386;GREEK CAPITAL LETTER ALPHA WITH TONOS;Lu;0;L;0391 0301;;;;N;GREEK CAPITAL LETTER ALPHA TONOS;;;03AC; +0387;GREEK ANO TELEIA;Po;0;ON;00B7;;;;N;;;;; +0388;GREEK CAPITAL LETTER EPSILON WITH TONOS;Lu;0;L;0395 0301;;;;N;GREEK CAPITAL LETTER EPSILON TONOS;;;03AD; +0389;GREEK CAPITAL LETTER ETA WITH TONOS;Lu;0;L;0397 0301;;;;N;GREEK CAPITAL LETTER ETA TONOS;;;03AE; +038A;GREEK CAPITAL LETTER IOTA WITH TONOS;Lu;0;L;0399 0301;;;;N;GREEK CAPITAL LETTER IOTA TONOS;;;03AF; +038C;GREEK CAPITAL LETTER OMICRON WITH TONOS;Lu;0;L;039F 0301;;;;N;GREEK CAPITAL LETTER OMICRON TONOS;;;03CC; +038E;GREEK CAPITAL LETTER UPSILON WITH TONOS;Lu;0;L;03A5 0301;;;;N;GREEK CAPITAL LETTER UPSILON TONOS;;;03CD; +038F;GREEK CAPITAL LETTER OMEGA WITH TONOS;Lu;0;L;03A9 0301;;;;N;GREEK CAPITAL LETTER OMEGA TONOS;;;03CE; +0390;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS;Ll;0;L;03CA 0301;;;;N;GREEK SMALL LETTER IOTA DIAERESIS TONOS;;;; +0391;GREEK CAPITAL LETTER ALPHA;Lu;0;L;;;;;N;;;;03B1; +0392;GREEK CAPITAL LETTER BETA;Lu;0;L;;;;;N;;;;03B2; +0393;GREEK CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;03B3; +0394;GREEK CAPITAL LETTER DELTA;Lu;0;L;;;;;N;;;;03B4; +0395;GREEK CAPITAL LETTER EPSILON;Lu;0;L;;;;;N;;;;03B5; +0396;GREEK CAPITAL LETTER ZETA;Lu;0;L;;;;;N;;;;03B6; +0397;GREEK CAPITAL LETTER ETA;Lu;0;L;;;;;N;;;;03B7; +0398;GREEK CAPITAL LETTER THETA;Lu;0;L;;;;;N;;;;03B8; +0399;GREEK CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;03B9; +039A;GREEK CAPITAL LETTER KAPPA;Lu;0;L;;;;;N;;;;03BA; +039B;GREEK CAPITAL LETTER LAMDA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER LAMBDA;;;03BB; +039C;GREEK CAPITAL LETTER MU;Lu;0;L;;;;;N;;;;03BC; +039D;GREEK CAPITAL LETTER NU;Lu;0;L;;;;;N;;;;03BD; +039E;GREEK CAPITAL LETTER XI;Lu;0;L;;;;;N;;;;03BE; +039F;GREEK CAPITAL LETTER OMICRON;Lu;0;L;;;;;N;;;;03BF; +03A0;GREEK CAPITAL LETTER PI;Lu;0;L;;;;;N;;;;03C0; +03A1;GREEK CAPITAL LETTER RHO;Lu;0;L;;;;;N;;;;03C1; +03A3;GREEK CAPITAL LETTER SIGMA;Lu;0;L;;;;;N;;;;03C3; +03A4;GREEK CAPITAL LETTER TAU;Lu;0;L;;;;;N;;;;03C4; +03A5;GREEK CAPITAL LETTER UPSILON;Lu;0;L;;;;;N;;;;03C5; +03A6;GREEK CAPITAL LETTER PHI;Lu;0;L;;;;;N;;;;03C6; +03A7;GREEK CAPITAL LETTER CHI;Lu;0;L;;;;;N;;;;03C7; +03A8;GREEK CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;03C8; +03A9;GREEK CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;03C9; +03AA;GREEK CAPITAL LETTER IOTA WITH DIALYTIKA;Lu;0;L;0399 0308;;;;N;GREEK CAPITAL LETTER IOTA DIAERESIS;;;03CA; +03AB;GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA;Lu;0;L;03A5 0308;;;;N;GREEK CAPITAL LETTER UPSILON DIAERESIS;;;03CB; +03AC;GREEK SMALL LETTER ALPHA WITH TONOS;Ll;0;L;03B1 0301;;;;N;GREEK SMALL LETTER ALPHA TONOS;;0386;;0386 +03AD;GREEK SMALL LETTER EPSILON WITH TONOS;Ll;0;L;03B5 0301;;;;N;GREEK SMALL LETTER EPSILON TONOS;;0388;;0388 +03AE;GREEK SMALL LETTER ETA WITH TONOS;Ll;0;L;03B7 0301;;;;N;GREEK SMALL LETTER ETA TONOS;;0389;;0389 +03AF;GREEK SMALL LETTER IOTA WITH TONOS;Ll;0;L;03B9 0301;;;;N;GREEK SMALL LETTER IOTA TONOS;;038A;;038A +03B0;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS;Ll;0;L;03CB 0301;;;;N;GREEK SMALL LETTER UPSILON DIAERESIS TONOS;;;; +03B1;GREEK SMALL LETTER ALPHA;Ll;0;L;;;;;N;;;0391;;0391 +03B2;GREEK SMALL LETTER BETA;Ll;0;L;;;;;N;;;0392;;0392 +03B3;GREEK SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0393;;0393 +03B4;GREEK SMALL LETTER DELTA;Ll;0;L;;;;;N;;;0394;;0394 +03B5;GREEK SMALL LETTER EPSILON;Ll;0;L;;;;;N;;;0395;;0395 +03B6;GREEK SMALL LETTER ZETA;Ll;0;L;;;;;N;;;0396;;0396 +03B7;GREEK SMALL LETTER ETA;Ll;0;L;;;;;N;;;0397;;0397 +03B8;GREEK SMALL LETTER THETA;Ll;0;L;;;;;N;;;0398;;0398 +03B9;GREEK SMALL LETTER IOTA;Ll;0;L;;;;;N;;;0399;;0399 +03BA;GREEK SMALL LETTER KAPPA;Ll;0;L;;;;;N;;;039A;;039A +03BB;GREEK SMALL LETTER LAMDA;Ll;0;L;;;;;N;GREEK SMALL LETTER LAMBDA;;039B;;039B +03BC;GREEK SMALL LETTER MU;Ll;0;L;;;;;N;;;039C;;039C +03BD;GREEK SMALL LETTER NU;Ll;0;L;;;;;N;;;039D;;039D +03BE;GREEK SMALL LETTER XI;Ll;0;L;;;;;N;;;039E;;039E +03BF;GREEK SMALL LETTER OMICRON;Ll;0;L;;;;;N;;;039F;;039F +03C0;GREEK SMALL LETTER PI;Ll;0;L;;;;;N;;;03A0;;03A0 +03C1;GREEK SMALL LETTER RHO;Ll;0;L;;;;;N;;;03A1;;03A1 +03C2;GREEK SMALL LETTER FINAL SIGMA;Ll;0;L;;;;;N;;;03A3;;03A3 +03C3;GREEK SMALL LETTER SIGMA;Ll;0;L;;;;;N;;;03A3;;03A3 +03C4;GREEK SMALL LETTER TAU;Ll;0;L;;;;;N;;;03A4;;03A4 +03C5;GREEK SMALL LETTER UPSILON;Ll;0;L;;;;;N;;;03A5;;03A5 +03C6;GREEK SMALL LETTER PHI;Ll;0;L;;;;;N;;;03A6;;03A6 +03C7;GREEK SMALL LETTER CHI;Ll;0;L;;;;;N;;;03A7;;03A7 +03C8;GREEK SMALL LETTER PSI;Ll;0;L;;;;;N;;;03A8;;03A8 +03C9;GREEK SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;03A9;;03A9 +03CA;GREEK SMALL LETTER IOTA WITH DIALYTIKA;Ll;0;L;03B9 0308;;;;N;GREEK SMALL LETTER IOTA DIAERESIS;;03AA;;03AA +03CB;GREEK SMALL LETTER UPSILON WITH DIALYTIKA;Ll;0;L;03C5 0308;;;;N;GREEK SMALL LETTER UPSILON DIAERESIS;;03AB;;03AB +03CC;GREEK SMALL LETTER OMICRON WITH TONOS;Ll;0;L;03BF 0301;;;;N;GREEK SMALL LETTER OMICRON TONOS;;038C;;038C +03CD;GREEK SMALL LETTER UPSILON WITH TONOS;Ll;0;L;03C5 0301;;;;N;GREEK SMALL LETTER UPSILON TONOS;;038E;;038E +03CE;GREEK SMALL LETTER OMEGA WITH TONOS;Ll;0;L;03C9 0301;;;;N;GREEK SMALL LETTER OMEGA TONOS;;038F;;038F +03D0;GREEK BETA SYMBOL;Ll;0;L; 03B2;;;;N;GREEK SMALL LETTER CURLED BETA;;0392;;0392 +03D1;GREEK THETA SYMBOL;Ll;0;L; 03B8;;;;N;GREEK SMALL LETTER SCRIPT THETA;;0398;;0398 +03D2;GREEK UPSILON WITH HOOK SYMBOL;Lu;0;L; 03A5;;;;N;GREEK CAPITAL LETTER UPSILON HOOK;;;; +03D3;GREEK UPSILON WITH ACUTE AND HOOK SYMBOL;Lu;0;L;03D2 0301;;;;N;GREEK CAPITAL LETTER UPSILON HOOK TONOS;;;; +03D4;GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL;Lu;0;L;03D2 0308;;;;N;GREEK CAPITAL LETTER UPSILON HOOK DIAERESIS;;;; +03D5;GREEK PHI SYMBOL;Ll;0;L; 03C6;;;;N;GREEK SMALL LETTER SCRIPT PHI;;03A6;;03A6 +03D6;GREEK PI SYMBOL;Ll;0;L; 03C0;;;;N;GREEK SMALL LETTER OMEGA PI;;03A0;;03A0 +03D7;GREEK KAI SYMBOL;Ll;0;L;;;;;N;;;;; +03D8;GREEK LETTER ARCHAIC KOPPA;Lu;0;L;;;;;N;;*;;03D9; +03D9;GREEK SMALL LETTER ARCHAIC KOPPA;Ll;0;L;;;;;N;;*;03D8;;03D8 +03DA;GREEK LETTER STIGMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER STIGMA;;;03DB; +03DB;GREEK SMALL LETTER STIGMA;Ll;0;L;;;;;N;;;03DA;;03DA +03DC;GREEK LETTER DIGAMMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER DIGAMMA;;;03DD; +03DD;GREEK SMALL LETTER DIGAMMA;Ll;0;L;;;;;N;;;03DC;;03DC +03DE;GREEK LETTER KOPPA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER KOPPA;;;03DF; +03DF;GREEK SMALL LETTER KOPPA;Ll;0;L;;;;;N;;;03DE;;03DE +03E0;GREEK LETTER SAMPI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SAMPI;;;03E1; +03E1;GREEK SMALL LETTER SAMPI;Ll;0;L;;;;;N;;;03E0;;03E0 +03E2;COPTIC CAPITAL LETTER SHEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SHEI;;;03E3; +03E3;COPTIC SMALL LETTER SHEI;Ll;0;L;;;;;N;GREEK SMALL LETTER SHEI;;03E2;;03E2 +03E4;COPTIC CAPITAL LETTER FEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER FEI;;;03E5; +03E5;COPTIC SMALL LETTER FEI;Ll;0;L;;;;;N;GREEK SMALL LETTER FEI;;03E4;;03E4 +03E6;COPTIC CAPITAL LETTER KHEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER KHEI;;;03E7; +03E7;COPTIC SMALL LETTER KHEI;Ll;0;L;;;;;N;GREEK SMALL LETTER KHEI;;03E6;;03E6 +03E8;COPTIC CAPITAL LETTER HORI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER HORI;;;03E9; +03E9;COPTIC SMALL LETTER HORI;Ll;0;L;;;;;N;GREEK SMALL LETTER HORI;;03E8;;03E8 +03EA;COPTIC CAPITAL LETTER GANGIA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER GANGIA;;;03EB; +03EB;COPTIC SMALL LETTER GANGIA;Ll;0;L;;;;;N;GREEK SMALL LETTER GANGIA;;03EA;;03EA +03EC;COPTIC CAPITAL LETTER SHIMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SHIMA;;;03ED; +03ED;COPTIC SMALL LETTER SHIMA;Ll;0;L;;;;;N;GREEK SMALL LETTER SHIMA;;03EC;;03EC +03EE;COPTIC CAPITAL LETTER DEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER DEI;;;03EF; +03EF;COPTIC SMALL LETTER DEI;Ll;0;L;;;;;N;GREEK SMALL LETTER DEI;;03EE;;03EE +03F0;GREEK KAPPA SYMBOL;Ll;0;L; 03BA;;;;N;GREEK SMALL LETTER SCRIPT KAPPA;;039A;;039A +03F1;GREEK RHO SYMBOL;Ll;0;L; 03C1;;;;N;GREEK SMALL LETTER TAILED RHO;;03A1;;03A1 +03F2;GREEK LUNATE SIGMA SYMBOL;Ll;0;L; 03C2;;;;N;GREEK SMALL LETTER LUNATE SIGMA;;03A3;;03A3 +03F3;GREEK LETTER YOT;Ll;0;L;;;;;N;;;;; +03F4;GREEK CAPITAL THETA SYMBOL;Lu;0;L; 0398;;;;N;;;;03B8; +03F5;GREEK LUNATE EPSILON SYMBOL;Ll;0;L; 03B5;;;;N;;;0395;;0395 +03F6;GREEK REVERSED LUNATE EPSILON SYMBOL;Sm;0;ON;;;;;N;;;;; +0400;CYRILLIC CAPITAL LETTER IE WITH GRAVE;Lu;0;L;0415 0300;;;;N;;;;0450; +0401;CYRILLIC CAPITAL LETTER IO;Lu;0;L;0415 0308;;;;N;;;;0451; +0402;CYRILLIC CAPITAL LETTER DJE;Lu;0;L;;;;;N;;Serbocroatian;;0452; +0403;CYRILLIC CAPITAL LETTER GJE;Lu;0;L;0413 0301;;;;N;;;;0453; +0404;CYRILLIC CAPITAL LETTER UKRAINIAN IE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER E;;;0454; +0405;CYRILLIC CAPITAL LETTER DZE;Lu;0;L;;;;;N;;;;0455; +0406;CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER I;;;0456; +0407;CYRILLIC CAPITAL LETTER YI;Lu;0;L;0406 0308;;;;N;;Ukrainian;;0457; +0408;CYRILLIC CAPITAL LETTER JE;Lu;0;L;;;;;N;;;;0458; +0409;CYRILLIC CAPITAL LETTER LJE;Lu;0;L;;;;;N;;;;0459; +040A;CYRILLIC CAPITAL LETTER NJE;Lu;0;L;;;;;N;;;;045A; +040B;CYRILLIC CAPITAL LETTER TSHE;Lu;0;L;;;;;N;;Serbocroatian;;045B; +040C;CYRILLIC CAPITAL LETTER KJE;Lu;0;L;041A 0301;;;;N;;;;045C; +040D;CYRILLIC CAPITAL LETTER I WITH GRAVE;Lu;0;L;0418 0300;;;;N;;;;045D; +040E;CYRILLIC CAPITAL LETTER SHORT U;Lu;0;L;0423 0306;;;;N;;Byelorussian;;045E; +040F;CYRILLIC CAPITAL LETTER DZHE;Lu;0;L;;;;;N;;;;045F; +0410;CYRILLIC CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0430; +0411;CYRILLIC CAPITAL LETTER BE;Lu;0;L;;;;;N;;;;0431; +0412;CYRILLIC CAPITAL LETTER VE;Lu;0;L;;;;;N;;;;0432; +0413;CYRILLIC CAPITAL LETTER GHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE;;;0433; +0414;CYRILLIC CAPITAL LETTER DE;Lu;0;L;;;;;N;;;;0434; +0415;CYRILLIC CAPITAL LETTER IE;Lu;0;L;;;;;N;;;;0435; +0416;CYRILLIC CAPITAL LETTER ZHE;Lu;0;L;;;;;N;;;;0436; +0417;CYRILLIC CAPITAL LETTER ZE;Lu;0;L;;;;;N;;;;0437; +0418;CYRILLIC CAPITAL LETTER I;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER II;;;0438; +0419;CYRILLIC CAPITAL LETTER SHORT I;Lu;0;L;0418 0306;;;;N;CYRILLIC CAPITAL LETTER SHORT II;;;0439; +041A;CYRILLIC CAPITAL LETTER KA;Lu;0;L;;;;;N;;;;043A; +041B;CYRILLIC CAPITAL LETTER EL;Lu;0;L;;;;;N;;;;043B; +041C;CYRILLIC CAPITAL LETTER EM;Lu;0;L;;;;;N;;;;043C; +041D;CYRILLIC CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;043D; +041E;CYRILLIC CAPITAL LETTER O;Lu;0;L;;;;;N;;;;043E; +041F;CYRILLIC CAPITAL LETTER PE;Lu;0;L;;;;;N;;;;043F; +0420;CYRILLIC CAPITAL LETTER ER;Lu;0;L;;;;;N;;;;0440; +0421;CYRILLIC CAPITAL LETTER ES;Lu;0;L;;;;;N;;;;0441; +0422;CYRILLIC CAPITAL LETTER TE;Lu;0;L;;;;;N;;;;0442; +0423;CYRILLIC CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0443; +0424;CYRILLIC CAPITAL LETTER EF;Lu;0;L;;;;;N;;;;0444; +0425;CYRILLIC CAPITAL LETTER HA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KHA;;;0445; +0426;CYRILLIC CAPITAL LETTER TSE;Lu;0;L;;;;;N;;;;0446; +0427;CYRILLIC CAPITAL LETTER CHE;Lu;0;L;;;;;N;;;;0447; +0428;CYRILLIC CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;0448; +0429;CYRILLIC CAPITAL LETTER SHCHA;Lu;0;L;;;;;N;;;;0449; +042A;CYRILLIC CAPITAL LETTER HARD SIGN;Lu;0;L;;;;;N;;;;044A; +042B;CYRILLIC CAPITAL LETTER YERU;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER YERI;;;044B; +042C;CYRILLIC CAPITAL LETTER SOFT SIGN;Lu;0;L;;;;;N;;;;044C; +042D;CYRILLIC CAPITAL LETTER E;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER REVERSED E;;;044D; +042E;CYRILLIC CAPITAL LETTER YU;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IU;;;044E; +042F;CYRILLIC CAPITAL LETTER YA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IA;;;044F; +0430;CYRILLIC SMALL LETTER A;Ll;0;L;;;;;N;;;0410;;0410 +0431;CYRILLIC SMALL LETTER BE;Ll;0;L;;;;;N;;;0411;;0411 +0432;CYRILLIC SMALL LETTER VE;Ll;0;L;;;;;N;;;0412;;0412 +0433;CYRILLIC SMALL LETTER GHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE;;0413;;0413 +0434;CYRILLIC SMALL LETTER DE;Ll;0;L;;;;;N;;;0414;;0414 +0435;CYRILLIC SMALL LETTER IE;Ll;0;L;;;;;N;;;0415;;0415 +0436;CYRILLIC SMALL LETTER ZHE;Ll;0;L;;;;;N;;;0416;;0416 +0437;CYRILLIC SMALL LETTER ZE;Ll;0;L;;;;;N;;;0417;;0417 +0438;CYRILLIC SMALL LETTER I;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER II;;0418;;0418 +0439;CYRILLIC SMALL LETTER SHORT I;Ll;0;L;0438 0306;;;;N;CYRILLIC SMALL LETTER SHORT II;;0419;;0419 +043A;CYRILLIC SMALL LETTER KA;Ll;0;L;;;;;N;;;041A;;041A +043B;CYRILLIC SMALL LETTER EL;Ll;0;L;;;;;N;;;041B;;041B +043C;CYRILLIC SMALL LETTER EM;Ll;0;L;;;;;N;;;041C;;041C +043D;CYRILLIC SMALL LETTER EN;Ll;0;L;;;;;N;;;041D;;041D +043E;CYRILLIC SMALL LETTER O;Ll;0;L;;;;;N;;;041E;;041E +043F;CYRILLIC SMALL LETTER PE;Ll;0;L;;;;;N;;;041F;;041F +0440;CYRILLIC SMALL LETTER ER;Ll;0;L;;;;;N;;;0420;;0420 +0441;CYRILLIC SMALL LETTER ES;Ll;0;L;;;;;N;;;0421;;0421 +0442;CYRILLIC SMALL LETTER TE;Ll;0;L;;;;;N;;;0422;;0422 +0443;CYRILLIC SMALL LETTER U;Ll;0;L;;;;;N;;;0423;;0423 +0444;CYRILLIC SMALL LETTER EF;Ll;0;L;;;;;N;;;0424;;0424 +0445;CYRILLIC SMALL LETTER HA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KHA;;0425;;0425 +0446;CYRILLIC SMALL LETTER TSE;Ll;0;L;;;;;N;;;0426;;0426 +0447;CYRILLIC SMALL LETTER CHE;Ll;0;L;;;;;N;;;0427;;0427 +0448;CYRILLIC SMALL LETTER SHA;Ll;0;L;;;;;N;;;0428;;0428 +0449;CYRILLIC SMALL LETTER SHCHA;Ll;0;L;;;;;N;;;0429;;0429 +044A;CYRILLIC SMALL LETTER HARD SIGN;Ll;0;L;;;;;N;;;042A;;042A +044B;CYRILLIC SMALL LETTER YERU;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER YERI;;042B;;042B +044C;CYRILLIC SMALL LETTER SOFT SIGN;Ll;0;L;;;;;N;;;042C;;042C +044D;CYRILLIC SMALL LETTER E;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER REVERSED E;;042D;;042D +044E;CYRILLIC SMALL LETTER YU;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IU;;042E;;042E +044F;CYRILLIC SMALL LETTER YA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IA;;042F;;042F +0450;CYRILLIC SMALL LETTER IE WITH GRAVE;Ll;0;L;0435 0300;;;;N;;;0400;;0400 +0451;CYRILLIC SMALL LETTER IO;Ll;0;L;0435 0308;;;;N;;;0401;;0401 +0452;CYRILLIC SMALL LETTER DJE;Ll;0;L;;;;;N;;Serbocroatian;0402;;0402 +0453;CYRILLIC SMALL LETTER GJE;Ll;0;L;0433 0301;;;;N;;;0403;;0403 +0454;CYRILLIC SMALL LETTER UKRAINIAN IE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER E;;0404;;0404 +0455;CYRILLIC SMALL LETTER DZE;Ll;0;L;;;;;N;;;0405;;0405 +0456;CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER I;;0406;;0406 +0457;CYRILLIC SMALL LETTER YI;Ll;0;L;0456 0308;;;;N;;Ukrainian;0407;;0407 +0458;CYRILLIC SMALL LETTER JE;Ll;0;L;;;;;N;;;0408;;0408 +0459;CYRILLIC SMALL LETTER LJE;Ll;0;L;;;;;N;;;0409;;0409 +045A;CYRILLIC SMALL LETTER NJE;Ll;0;L;;;;;N;;;040A;;040A +045B;CYRILLIC SMALL LETTER TSHE;Ll;0;L;;;;;N;;Serbocroatian;040B;;040B +045C;CYRILLIC SMALL LETTER KJE;Ll;0;L;043A 0301;;;;N;;;040C;;040C +045D;CYRILLIC SMALL LETTER I WITH GRAVE;Ll;0;L;0438 0300;;;;N;;;040D;;040D +045E;CYRILLIC SMALL LETTER SHORT U;Ll;0;L;0443 0306;;;;N;;Byelorussian;040E;;040E +045F;CYRILLIC SMALL LETTER DZHE;Ll;0;L;;;;;N;;;040F;;040F +0460;CYRILLIC CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;0461; +0461;CYRILLIC SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;0460;;0460 +0462;CYRILLIC CAPITAL LETTER YAT;Lu;0;L;;;;;N;;;;0463; +0463;CYRILLIC SMALL LETTER YAT;Ll;0;L;;;;;N;;;0462;;0462 +0464;CYRILLIC CAPITAL LETTER IOTIFIED E;Lu;0;L;;;;;N;;;;0465; +0465;CYRILLIC SMALL LETTER IOTIFIED E;Ll;0;L;;;;;N;;;0464;;0464 +0466;CYRILLIC CAPITAL LETTER LITTLE YUS;Lu;0;L;;;;;N;;;;0467; +0467;CYRILLIC SMALL LETTER LITTLE YUS;Ll;0;L;;;;;N;;;0466;;0466 +0468;CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS;Lu;0;L;;;;;N;;;;0469; +0469;CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS;Ll;0;L;;;;;N;;;0468;;0468 +046A;CYRILLIC CAPITAL LETTER BIG YUS;Lu;0;L;;;;;N;;;;046B; +046B;CYRILLIC SMALL LETTER BIG YUS;Ll;0;L;;;;;N;;;046A;;046A +046C;CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS;Lu;0;L;;;;;N;;;;046D; +046D;CYRILLIC SMALL LETTER IOTIFIED BIG YUS;Ll;0;L;;;;;N;;;046C;;046C +046E;CYRILLIC CAPITAL LETTER KSI;Lu;0;L;;;;;N;;;;046F; +046F;CYRILLIC SMALL LETTER KSI;Ll;0;L;;;;;N;;;046E;;046E +0470;CYRILLIC CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;0471; +0471;CYRILLIC SMALL LETTER PSI;Ll;0;L;;;;;N;;;0470;;0470 +0472;CYRILLIC CAPITAL LETTER FITA;Lu;0;L;;;;;N;;;;0473; +0473;CYRILLIC SMALL LETTER FITA;Ll;0;L;;;;;N;;;0472;;0472 +0474;CYRILLIC CAPITAL LETTER IZHITSA;Lu;0;L;;;;;N;;;;0475; +0475;CYRILLIC SMALL LETTER IZHITSA;Ll;0;L;;;;;N;;;0474;;0474 +0476;CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT;Lu;0;L;0474 030F;;;;N;CYRILLIC CAPITAL LETTER IZHITSA DOUBLE GRAVE;;;0477; +0477;CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT;Ll;0;L;0475 030F;;;;N;CYRILLIC SMALL LETTER IZHITSA DOUBLE GRAVE;;0476;;0476 +0478;CYRILLIC CAPITAL LETTER UK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER UK DIGRAPH;;;0479; +0479;CYRILLIC SMALL LETTER UK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER UK DIGRAPH;;0478;;0478 +047A;CYRILLIC CAPITAL LETTER ROUND OMEGA;Lu;0;L;;;;;N;;;;047B; +047B;CYRILLIC SMALL LETTER ROUND OMEGA;Ll;0;L;;;;;N;;;047A;;047A +047C;CYRILLIC CAPITAL LETTER OMEGA WITH TITLO;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER OMEGA TITLO;;;047D; +047D;CYRILLIC SMALL LETTER OMEGA WITH TITLO;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER OMEGA TITLO;;047C;;047C +047E;CYRILLIC CAPITAL LETTER OT;Lu;0;L;;;;;N;;;;047F; +047F;CYRILLIC SMALL LETTER OT;Ll;0;L;;;;;N;;;047E;;047E +0480;CYRILLIC CAPITAL LETTER KOPPA;Lu;0;L;;;;;N;;;;0481; +0481;CYRILLIC SMALL LETTER KOPPA;Ll;0;L;;;;;N;;;0480;;0480 +0482;CYRILLIC THOUSANDS SIGN;So;0;L;;;;;N;;;;; +0483;COMBINING CYRILLIC TITLO;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING TITLO;;;; +0484;COMBINING CYRILLIC PALATALIZATION;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING PALATALIZATION;;;; +0485;COMBINING CYRILLIC DASIA PNEUMATA;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING DASIA PNEUMATA;;;; +0486;COMBINING CYRILLIC PSILI PNEUMATA;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING PSILI PNEUMATA;;;; +0488;COMBINING CYRILLIC HUNDRED THOUSANDS SIGN;Me;0;NSM;;;;;N;;;;; +0489;COMBINING CYRILLIC MILLIONS SIGN;Me;0;NSM;;;;;N;;;;; +048A;CYRILLIC CAPITAL LETTER SHORT I WITH TAIL;Lu;0;L;;;;;N;;;;048B; +048B;CYRILLIC SMALL LETTER SHORT I WITH TAIL;Ll;0;L;;;;;N;;;048A;;048A +048C;CYRILLIC CAPITAL LETTER SEMISOFT SIGN;Lu;0;L;;;;;N;;;;048D; +048D;CYRILLIC SMALL LETTER SEMISOFT SIGN;Ll;0;L;;;;;N;;;048C;;048C +048E;CYRILLIC CAPITAL LETTER ER WITH TICK;Lu;0;L;;;;;N;;;;048F; +048F;CYRILLIC SMALL LETTER ER WITH TICK;Ll;0;L;;;;;N;;;048E;;048E +0490;CYRILLIC CAPITAL LETTER GHE WITH UPTURN;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE WITH UPTURN;;;0491; +0491;CYRILLIC SMALL LETTER GHE WITH UPTURN;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE WITH UPTURN;;0490;;0490 +0492;CYRILLIC CAPITAL LETTER GHE WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE BAR;;;0493; +0493;CYRILLIC SMALL LETTER GHE WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE BAR;;0492;;0492 +0494;CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE HOOK;;;0495; +0495;CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE HOOK;;0494;;0494 +0496;CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ZHE WITH RIGHT DESCENDER;;;0497; +0497;CYRILLIC SMALL LETTER ZHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ZHE WITH RIGHT DESCENDER;;0496;;0496 +0498;CYRILLIC CAPITAL LETTER ZE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ZE CEDILLA;;;0499; +0499;CYRILLIC SMALL LETTER ZE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ZE CEDILLA;;0498;;0498 +049A;CYRILLIC CAPITAL LETTER KA WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA WITH RIGHT DESCENDER;;;049B; +049B;CYRILLIC SMALL LETTER KA WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA WITH RIGHT DESCENDER;;049A;;049A +049C;CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA VERTICAL BAR;;;049D; +049D;CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA VERTICAL BAR;;049C;;049C +049E;CYRILLIC CAPITAL LETTER KA WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA BAR;;;049F; +049F;CYRILLIC SMALL LETTER KA WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA BAR;;049E;;049E +04A0;CYRILLIC CAPITAL LETTER BASHKIR KA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER REVERSED GE KA;;;04A1; +04A1;CYRILLIC SMALL LETTER BASHKIR KA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER REVERSED GE KA;;04A0;;04A0 +04A2;CYRILLIC CAPITAL LETTER EN WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN WITH RIGHT DESCENDER;;;04A3; +04A3;CYRILLIC SMALL LETTER EN WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN WITH RIGHT DESCENDER;;04A2;;04A2 +04A4;CYRILLIC CAPITAL LIGATURE EN GHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN GE;;;04A5; +04A5;CYRILLIC SMALL LIGATURE EN GHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN GE;;04A4;;04A4 +04A6;CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER PE HOOK;Abkhasian;;04A7; +04A7;CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER PE HOOK;Abkhasian;04A6;;04A6 +04A8;CYRILLIC CAPITAL LETTER ABKHASIAN HA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER O HOOK;;;04A9; +04A9;CYRILLIC SMALL LETTER ABKHASIAN HA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER O HOOK;;04A8;;04A8 +04AA;CYRILLIC CAPITAL LETTER ES WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ES CEDILLA;;;04AB; +04AB;CYRILLIC SMALL LETTER ES WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ES CEDILLA;;04AA;;04AA +04AC;CYRILLIC CAPITAL LETTER TE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE WITH RIGHT DESCENDER;;;04AD; +04AD;CYRILLIC SMALL LETTER TE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE WITH RIGHT DESCENDER;;04AC;;04AC +04AE;CYRILLIC CAPITAL LETTER STRAIGHT U;Lu;0;L;;;;;N;;;;04AF; +04AF;CYRILLIC SMALL LETTER STRAIGHT U;Ll;0;L;;;;;N;;;04AE;;04AE +04B0;CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER STRAIGHT U BAR;;;04B1; +04B1;CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER STRAIGHT U BAR;;04B0;;04B0 +04B2;CYRILLIC CAPITAL LETTER HA WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KHA WITH RIGHT DESCENDER;;;04B3; +04B3;CYRILLIC SMALL LETTER HA WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KHA WITH RIGHT DESCENDER;;04B2;;04B2 +04B4;CYRILLIC CAPITAL LIGATURE TE TSE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE TSE;Abkhasian;;04B5; +04B5;CYRILLIC SMALL LIGATURE TE TSE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE TSE;Abkhasian;04B4;;04B4 +04B6;CYRILLIC CAPITAL LETTER CHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE WITH RIGHT DESCENDER;;;04B7; +04B7;CYRILLIC SMALL LETTER CHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE WITH RIGHT DESCENDER;;04B6;;04B6 +04B8;CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE VERTICAL BAR;;;04B9; +04B9;CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE VERTICAL BAR;;04B8;;04B8 +04BA;CYRILLIC CAPITAL LETTER SHHA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER H;;;04BB; +04BB;CYRILLIC SMALL LETTER SHHA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER H;;04BA;;04BA +04BC;CYRILLIC CAPITAL LETTER ABKHASIAN CHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IE HOOK;;;04BD; +04BD;CYRILLIC SMALL LETTER ABKHASIAN CHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IE HOOK;;04BC;;04BC +04BE;CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IE HOOK OGONEK;;;04BF; +04BF;CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IE HOOK OGONEK;;04BE;;04BE +04C0;CYRILLIC LETTER PALOCHKA;Lu;0;L;;;;;N;CYRILLIC LETTER I;;;; +04C1;CYRILLIC CAPITAL LETTER ZHE WITH BREVE;Lu;0;L;0416 0306;;;;N;CYRILLIC CAPITAL LETTER SHORT ZHE;;;04C2; +04C2;CYRILLIC SMALL LETTER ZHE WITH BREVE;Ll;0;L;0436 0306;;;;N;CYRILLIC SMALL LETTER SHORT ZHE;;04C1;;04C1 +04C3;CYRILLIC CAPITAL LETTER KA WITH HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA HOOK;;;04C4; +04C4;CYRILLIC SMALL LETTER KA WITH HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA HOOK;;04C3;;04C3 +04C5;CYRILLIC CAPITAL LETTER EL WITH TAIL;Lu;0;L;;;;;N;;;;04C6; +04C6;CYRILLIC SMALL LETTER EL WITH TAIL;Ll;0;L;;;;;N;;;04C5;;04C5 +04C7;CYRILLIC CAPITAL LETTER EN WITH HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN HOOK;;;04C8; +04C8;CYRILLIC SMALL LETTER EN WITH HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN HOOK;;04C7;;04C7 +04C9;CYRILLIC CAPITAL LETTER EN WITH TAIL;Lu;0;L;;;;;N;;;;04CA; +04CA;CYRILLIC SMALL LETTER EN WITH TAIL;Ll;0;L;;;;;N;;;04C9;;04C9 +04CB;CYRILLIC CAPITAL LETTER KHAKASSIAN CHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE WITH LEFT DESCENDER;;;04CC; +04CC;CYRILLIC SMALL LETTER KHAKASSIAN CHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE WITH LEFT DESCENDER;;04CB;;04CB +04CD;CYRILLIC CAPITAL LETTER EM WITH TAIL;Lu;0;L;;;;;N;;;;04CE; +04CE;CYRILLIC SMALL LETTER EM WITH TAIL;Ll;0;L;;;;;N;;;04CD;;04CD +04D0;CYRILLIC CAPITAL LETTER A WITH BREVE;Lu;0;L;0410 0306;;;;N;;;;04D1; +04D1;CYRILLIC SMALL LETTER A WITH BREVE;Ll;0;L;0430 0306;;;;N;;;04D0;;04D0 +04D2;CYRILLIC CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0410 0308;;;;N;;;;04D3; +04D3;CYRILLIC SMALL LETTER A WITH DIAERESIS;Ll;0;L;0430 0308;;;;N;;;04D2;;04D2 +04D4;CYRILLIC CAPITAL LIGATURE A IE;Lu;0;L;;;;;N;;;;04D5; +04D5;CYRILLIC SMALL LIGATURE A IE;Ll;0;L;;;;;N;;;04D4;;04D4 +04D6;CYRILLIC CAPITAL LETTER IE WITH BREVE;Lu;0;L;0415 0306;;;;N;;;;04D7; +04D7;CYRILLIC SMALL LETTER IE WITH BREVE;Ll;0;L;0435 0306;;;;N;;;04D6;;04D6 +04D8;CYRILLIC CAPITAL LETTER SCHWA;Lu;0;L;;;;;N;;;;04D9; +04D9;CYRILLIC SMALL LETTER SCHWA;Ll;0;L;;;;;N;;;04D8;;04D8 +04DA;CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS;Lu;0;L;04D8 0308;;;;N;;;;04DB; +04DB;CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS;Ll;0;L;04D9 0308;;;;N;;;04DA;;04DA +04DC;CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS;Lu;0;L;0416 0308;;;;N;;;;04DD; +04DD;CYRILLIC SMALL LETTER ZHE WITH DIAERESIS;Ll;0;L;0436 0308;;;;N;;;04DC;;04DC +04DE;CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS;Lu;0;L;0417 0308;;;;N;;;;04DF; +04DF;CYRILLIC SMALL LETTER ZE WITH DIAERESIS;Ll;0;L;0437 0308;;;;N;;;04DE;;04DE +04E0;CYRILLIC CAPITAL LETTER ABKHASIAN DZE;Lu;0;L;;;;;N;;;;04E1; +04E1;CYRILLIC SMALL LETTER ABKHASIAN DZE;Ll;0;L;;;;;N;;;04E0;;04E0 +04E2;CYRILLIC CAPITAL LETTER I WITH MACRON;Lu;0;L;0418 0304;;;;N;;;;04E3; +04E3;CYRILLIC SMALL LETTER I WITH MACRON;Ll;0;L;0438 0304;;;;N;;;04E2;;04E2 +04E4;CYRILLIC CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0418 0308;;;;N;;;;04E5; +04E5;CYRILLIC SMALL LETTER I WITH DIAERESIS;Ll;0;L;0438 0308;;;;N;;;04E4;;04E4 +04E6;CYRILLIC CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;041E 0308;;;;N;;;;04E7; +04E7;CYRILLIC SMALL LETTER O WITH DIAERESIS;Ll;0;L;043E 0308;;;;N;;;04E6;;04E6 +04E8;CYRILLIC CAPITAL LETTER BARRED O;Lu;0;L;;;;;N;;;;04E9; +04E9;CYRILLIC SMALL LETTER BARRED O;Ll;0;L;;;;;N;;;04E8;;04E8 +04EA;CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS;Lu;0;L;04E8 0308;;;;N;;;;04EB; +04EB;CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS;Ll;0;L;04E9 0308;;;;N;;;04EA;;04EA +04EC;CYRILLIC CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;042D 0308;;;;N;;;;04ED; +04ED;CYRILLIC SMALL LETTER E WITH DIAERESIS;Ll;0;L;044D 0308;;;;N;;;04EC;;04EC +04EE;CYRILLIC CAPITAL LETTER U WITH MACRON;Lu;0;L;0423 0304;;;;N;;;;04EF; +04EF;CYRILLIC SMALL LETTER U WITH MACRON;Ll;0;L;0443 0304;;;;N;;;04EE;;04EE +04F0;CYRILLIC CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0423 0308;;;;N;;;;04F1; +04F1;CYRILLIC SMALL LETTER U WITH DIAERESIS;Ll;0;L;0443 0308;;;;N;;;04F0;;04F0 +04F2;CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE;Lu;0;L;0423 030B;;;;N;;;;04F3; +04F3;CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE;Ll;0;L;0443 030B;;;;N;;;04F2;;04F2 +04F4;CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS;Lu;0;L;0427 0308;;;;N;;;;04F5; +04F5;CYRILLIC SMALL LETTER CHE WITH DIAERESIS;Ll;0;L;0447 0308;;;;N;;;04F4;;04F4 +04F8;CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS;Lu;0;L;042B 0308;;;;N;;;;04F9; +04F9;CYRILLIC SMALL LETTER YERU WITH DIAERESIS;Ll;0;L;044B 0308;;;;N;;;04F8;;04F8 +0500;CYRILLIC CAPITAL LETTER KOMI DE;Lu;0;L;;;;;N;;;;0501; +0501;CYRILLIC SMALL LETTER KOMI DE;Ll;0;L;;;;;N;;;0500;;0500 +0502;CYRILLIC CAPITAL LETTER KOMI DJE;Lu;0;L;;;;;N;;;;0503; +0503;CYRILLIC SMALL LETTER KOMI DJE;Ll;0;L;;;;;N;;;0502;;0502 +0504;CYRILLIC CAPITAL LETTER KOMI ZJE;Lu;0;L;;;;;N;;;;0505; +0505;CYRILLIC SMALL LETTER KOMI ZJE;Ll;0;L;;;;;N;;;0504;;0504 +0506;CYRILLIC CAPITAL LETTER KOMI DZJE;Lu;0;L;;;;;N;;;;0507; +0507;CYRILLIC SMALL LETTER KOMI DZJE;Ll;0;L;;;;;N;;;0506;;0506 +0508;CYRILLIC CAPITAL LETTER KOMI LJE;Lu;0;L;;;;;N;;;;0509; +0509;CYRILLIC SMALL LETTER KOMI LJE;Ll;0;L;;;;;N;;;0508;;0508 +050A;CYRILLIC CAPITAL LETTER KOMI NJE;Lu;0;L;;;;;N;;;;050B; +050B;CYRILLIC SMALL LETTER KOMI NJE;Ll;0;L;;;;;N;;;050A;;050A +050C;CYRILLIC CAPITAL LETTER KOMI SJE;Lu;0;L;;;;;N;;;;050D; +050D;CYRILLIC SMALL LETTER KOMI SJE;Ll;0;L;;;;;N;;;050C;;050C +050E;CYRILLIC CAPITAL LETTER KOMI TJE;Lu;0;L;;;;;N;;;;050F; +050F;CYRILLIC SMALL LETTER KOMI TJE;Ll;0;L;;;;;N;;;050E;;050E +0531;ARMENIAN CAPITAL LETTER AYB;Lu;0;L;;;;;N;;;;0561; +0532;ARMENIAN CAPITAL LETTER BEN;Lu;0;L;;;;;N;;;;0562; +0533;ARMENIAN CAPITAL LETTER GIM;Lu;0;L;;;;;N;;;;0563; +0534;ARMENIAN CAPITAL LETTER DA;Lu;0;L;;;;;N;;;;0564; +0535;ARMENIAN CAPITAL LETTER ECH;Lu;0;L;;;;;N;;;;0565; +0536;ARMENIAN CAPITAL LETTER ZA;Lu;0;L;;;;;N;;;;0566; +0537;ARMENIAN CAPITAL LETTER EH;Lu;0;L;;;;;N;;;;0567; +0538;ARMENIAN CAPITAL LETTER ET;Lu;0;L;;;;;N;;;;0568; +0539;ARMENIAN CAPITAL LETTER TO;Lu;0;L;;;;;N;;;;0569; +053A;ARMENIAN CAPITAL LETTER ZHE;Lu;0;L;;;;;N;;;;056A; +053B;ARMENIAN CAPITAL LETTER INI;Lu;0;L;;;;;N;;;;056B; +053C;ARMENIAN CAPITAL LETTER LIWN;Lu;0;L;;;;;N;;;;056C; +053D;ARMENIAN CAPITAL LETTER XEH;Lu;0;L;;;;;N;;;;056D; +053E;ARMENIAN CAPITAL LETTER CA;Lu;0;L;;;;;N;;;;056E; +053F;ARMENIAN CAPITAL LETTER KEN;Lu;0;L;;;;;N;;;;056F; +0540;ARMENIAN CAPITAL LETTER HO;Lu;0;L;;;;;N;;;;0570; +0541;ARMENIAN CAPITAL LETTER JA;Lu;0;L;;;;;N;;;;0571; +0542;ARMENIAN CAPITAL LETTER GHAD;Lu;0;L;;;;;N;ARMENIAN CAPITAL LETTER LAD;;;0572; +0543;ARMENIAN CAPITAL LETTER CHEH;Lu;0;L;;;;;N;;;;0573; +0544;ARMENIAN CAPITAL LETTER MEN;Lu;0;L;;;;;N;;;;0574; +0545;ARMENIAN CAPITAL LETTER YI;Lu;0;L;;;;;N;;;;0575; +0546;ARMENIAN CAPITAL LETTER NOW;Lu;0;L;;;;;N;;;;0576; +0547;ARMENIAN CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;0577; +0548;ARMENIAN CAPITAL LETTER VO;Lu;0;L;;;;;N;;;;0578; +0549;ARMENIAN CAPITAL LETTER CHA;Lu;0;L;;;;;N;;;;0579; +054A;ARMENIAN CAPITAL LETTER PEH;Lu;0;L;;;;;N;;;;057A; +054B;ARMENIAN CAPITAL LETTER JHEH;Lu;0;L;;;;;N;;;;057B; +054C;ARMENIAN CAPITAL LETTER RA;Lu;0;L;;;;;N;;;;057C; +054D;ARMENIAN CAPITAL LETTER SEH;Lu;0;L;;;;;N;;;;057D; +054E;ARMENIAN CAPITAL LETTER VEW;Lu;0;L;;;;;N;;;;057E; +054F;ARMENIAN CAPITAL LETTER TIWN;Lu;0;L;;;;;N;;;;057F; +0550;ARMENIAN CAPITAL LETTER REH;Lu;0;L;;;;;N;;;;0580; +0551;ARMENIAN CAPITAL LETTER CO;Lu;0;L;;;;;N;;;;0581; +0552;ARMENIAN CAPITAL LETTER YIWN;Lu;0;L;;;;;N;;;;0582; +0553;ARMENIAN CAPITAL LETTER PIWR;Lu;0;L;;;;;N;;;;0583; +0554;ARMENIAN CAPITAL LETTER KEH;Lu;0;L;;;;;N;;;;0584; +0555;ARMENIAN CAPITAL LETTER OH;Lu;0;L;;;;;N;;;;0585; +0556;ARMENIAN CAPITAL LETTER FEH;Lu;0;L;;;;;N;;;;0586; +0559;ARMENIAN MODIFIER LETTER LEFT HALF RING;Lm;0;L;;;;;N;;;;; +055A;ARMENIAN APOSTROPHE;Po;0;L;;;;;N;ARMENIAN MODIFIER LETTER RIGHT HALF RING;;;; +055B;ARMENIAN EMPHASIS MARK;Po;0;L;;;;;N;;;;; +055C;ARMENIAN EXCLAMATION MARK;Po;0;L;;;;;N;;;;; +055D;ARMENIAN COMMA;Po;0;L;;;;;N;;;;; +055E;ARMENIAN QUESTION MARK;Po;0;L;;;;;N;;;;; +055F;ARMENIAN ABBREVIATION MARK;Po;0;L;;;;;N;;;;; +0561;ARMENIAN SMALL LETTER AYB;Ll;0;L;;;;;N;;;0531;;0531 +0562;ARMENIAN SMALL LETTER BEN;Ll;0;L;;;;;N;;;0532;;0532 +0563;ARMENIAN SMALL LETTER GIM;Ll;0;L;;;;;N;;;0533;;0533 +0564;ARMENIAN SMALL LETTER DA;Ll;0;L;;;;;N;;;0534;;0534 +0565;ARMENIAN SMALL LETTER ECH;Ll;0;L;;;;;N;;;0535;;0535 +0566;ARMENIAN SMALL LETTER ZA;Ll;0;L;;;;;N;;;0536;;0536 +0567;ARMENIAN SMALL LETTER EH;Ll;0;L;;;;;N;;;0537;;0537 +0568;ARMENIAN SMALL LETTER ET;Ll;0;L;;;;;N;;;0538;;0538 +0569;ARMENIAN SMALL LETTER TO;Ll;0;L;;;;;N;;;0539;;0539 +056A;ARMENIAN SMALL LETTER ZHE;Ll;0;L;;;;;N;;;053A;;053A +056B;ARMENIAN SMALL LETTER INI;Ll;0;L;;;;;N;;;053B;;053B +056C;ARMENIAN SMALL LETTER LIWN;Ll;0;L;;;;;N;;;053C;;053C +056D;ARMENIAN SMALL LETTER XEH;Ll;0;L;;;;;N;;;053D;;053D +056E;ARMENIAN SMALL LETTER CA;Ll;0;L;;;;;N;;;053E;;053E +056F;ARMENIAN SMALL LETTER KEN;Ll;0;L;;;;;N;;;053F;;053F +0570;ARMENIAN SMALL LETTER HO;Ll;0;L;;;;;N;;;0540;;0540 +0571;ARMENIAN SMALL LETTER JA;Ll;0;L;;;;;N;;;0541;;0541 +0572;ARMENIAN SMALL LETTER GHAD;Ll;0;L;;;;;N;ARMENIAN SMALL LETTER LAD;;0542;;0542 +0573;ARMENIAN SMALL LETTER CHEH;Ll;0;L;;;;;N;;;0543;;0543 +0574;ARMENIAN SMALL LETTER MEN;Ll;0;L;;;;;N;;;0544;;0544 +0575;ARMENIAN SMALL LETTER YI;Ll;0;L;;;;;N;;;0545;;0545 +0576;ARMENIAN SMALL LETTER NOW;Ll;0;L;;;;;N;;;0546;;0546 +0577;ARMENIAN SMALL LETTER SHA;Ll;0;L;;;;;N;;;0547;;0547 +0578;ARMENIAN SMALL LETTER VO;Ll;0;L;;;;;N;;;0548;;0548 +0579;ARMENIAN SMALL LETTER CHA;Ll;0;L;;;;;N;;;0549;;0549 +057A;ARMENIAN SMALL LETTER PEH;Ll;0;L;;;;;N;;;054A;;054A +057B;ARMENIAN SMALL LETTER JHEH;Ll;0;L;;;;;N;;;054B;;054B +057C;ARMENIAN SMALL LETTER RA;Ll;0;L;;;;;N;;;054C;;054C +057D;ARMENIAN SMALL LETTER SEH;Ll;0;L;;;;;N;;;054D;;054D +057E;ARMENIAN SMALL LETTER VEW;Ll;0;L;;;;;N;;;054E;;054E +057F;ARMENIAN SMALL LETTER TIWN;Ll;0;L;;;;;N;;;054F;;054F +0580;ARMENIAN SMALL LETTER REH;Ll;0;L;;;;;N;;;0550;;0550 +0581;ARMENIAN SMALL LETTER CO;Ll;0;L;;;;;N;;;0551;;0551 +0582;ARMENIAN SMALL LETTER YIWN;Ll;0;L;;;;;N;;;0552;;0552 +0583;ARMENIAN SMALL LETTER PIWR;Ll;0;L;;;;;N;;;0553;;0553 +0584;ARMENIAN SMALL LETTER KEH;Ll;0;L;;;;;N;;;0554;;0554 +0585;ARMENIAN SMALL LETTER OH;Ll;0;L;;;;;N;;;0555;;0555 +0586;ARMENIAN SMALL LETTER FEH;Ll;0;L;;;;;N;;;0556;;0556 +0587;ARMENIAN SMALL LIGATURE ECH YIWN;Ll;0;L; 0565 0582;;;;N;;;;; +0589;ARMENIAN FULL STOP;Po;0;L;;;;;N;ARMENIAN PERIOD;;;; +058A;ARMENIAN HYPHEN;Pd;0;ON;;;;;N;;;;; +0591;HEBREW ACCENT ETNAHTA;Mn;220;NSM;;;;;N;;;;; +0592;HEBREW ACCENT SEGOL;Mn;230;NSM;;;;;N;;;;; +0593;HEBREW ACCENT SHALSHELET;Mn;230;NSM;;;;;N;;;;; +0594;HEBREW ACCENT ZAQEF QATAN;Mn;230;NSM;;;;;N;;;;; +0595;HEBREW ACCENT ZAQEF GADOL;Mn;230;NSM;;;;;N;;;;; +0596;HEBREW ACCENT TIPEHA;Mn;220;NSM;;;;;N;;*;;; +0597;HEBREW ACCENT REVIA;Mn;230;NSM;;;;;N;;;;; +0598;HEBREW ACCENT ZARQA;Mn;230;NSM;;;;;N;;*;;; +0599;HEBREW ACCENT PASHTA;Mn;230;NSM;;;;;N;;;;; +059A;HEBREW ACCENT YETIV;Mn;222;NSM;;;;;N;;;;; +059B;HEBREW ACCENT TEVIR;Mn;220;NSM;;;;;N;;;;; +059C;HEBREW ACCENT GERESH;Mn;230;NSM;;;;;N;;;;; +059D;HEBREW ACCENT GERESH MUQDAM;Mn;230;NSM;;;;;N;;;;; +059E;HEBREW ACCENT GERSHAYIM;Mn;230;NSM;;;;;N;;;;; +059F;HEBREW ACCENT QARNEY PARA;Mn;230;NSM;;;;;N;;;;; +05A0;HEBREW ACCENT TELISHA GEDOLA;Mn;230;NSM;;;;;N;;;;; +05A1;HEBREW ACCENT PAZER;Mn;230;NSM;;;;;N;;;;; +05A3;HEBREW ACCENT MUNAH;Mn;220;NSM;;;;;N;;;;; +05A4;HEBREW ACCENT MAHAPAKH;Mn;220;NSM;;;;;N;;;;; +05A5;HEBREW ACCENT MERKHA;Mn;220;NSM;;;;;N;;*;;; +05A6;HEBREW ACCENT MERKHA KEFULA;Mn;220;NSM;;;;;N;;;;; +05A7;HEBREW ACCENT DARGA;Mn;220;NSM;;;;;N;;;;; +05A8;HEBREW ACCENT QADMA;Mn;230;NSM;;;;;N;;*;;; +05A9;HEBREW ACCENT TELISHA QETANA;Mn;230;NSM;;;;;N;;;;; +05AA;HEBREW ACCENT YERAH BEN YOMO;Mn;220;NSM;;;;;N;;*;;; +05AB;HEBREW ACCENT OLE;Mn;230;NSM;;;;;N;;;;; +05AC;HEBREW ACCENT ILUY;Mn;230;NSM;;;;;N;;;;; +05AD;HEBREW ACCENT DEHI;Mn;222;NSM;;;;;N;;;;; +05AE;HEBREW ACCENT ZINOR;Mn;228;NSM;;;;;N;;;;; +05AF;HEBREW MARK MASORA CIRCLE;Mn;230;NSM;;;;;N;;;;; +05B0;HEBREW POINT SHEVA;Mn;10;NSM;;;;;N;;;;; +05B1;HEBREW POINT HATAF SEGOL;Mn;11;NSM;;;;;N;;;;; +05B2;HEBREW POINT HATAF PATAH;Mn;12;NSM;;;;;N;;;;; +05B3;HEBREW POINT HATAF QAMATS;Mn;13;NSM;;;;;N;;;;; +05B4;HEBREW POINT HIRIQ;Mn;14;NSM;;;;;N;;;;; +05B5;HEBREW POINT TSERE;Mn;15;NSM;;;;;N;;;;; +05B6;HEBREW POINT SEGOL;Mn;16;NSM;;;;;N;;;;; +05B7;HEBREW POINT PATAH;Mn;17;NSM;;;;;N;;;;; +05B8;HEBREW POINT QAMATS;Mn;18;NSM;;;;;N;;;;; +05B9;HEBREW POINT HOLAM;Mn;19;NSM;;;;;N;;;;; +05BB;HEBREW POINT QUBUTS;Mn;20;NSM;;;;;N;;;;; +05BC;HEBREW POINT DAGESH OR MAPIQ;Mn;21;NSM;;;;;N;HEBREW POINT DAGESH;or shuruq;;; +05BD;HEBREW POINT METEG;Mn;22;NSM;;;;;N;;*;;; +05BE;HEBREW PUNCTUATION MAQAF;Po;0;R;;;;;N;;;;; +05BF;HEBREW POINT RAFE;Mn;23;NSM;;;;;N;;;;; +05C0;HEBREW PUNCTUATION PASEQ;Po;0;R;;;;;N;HEBREW POINT PASEQ;*;;; +05C1;HEBREW POINT SHIN DOT;Mn;24;NSM;;;;;N;;;;; +05C2;HEBREW POINT SIN DOT;Mn;25;NSM;;;;;N;;;;; +05C3;HEBREW PUNCTUATION SOF PASUQ;Po;0;R;;;;;N;;*;;; +05C4;HEBREW MARK UPPER DOT;Mn;230;NSM;;;;;N;;;;; +05D0;HEBREW LETTER ALEF;Lo;0;R;;;;;N;;;;; +05D1;HEBREW LETTER BET;Lo;0;R;;;;;N;;;;; +05D2;HEBREW LETTER GIMEL;Lo;0;R;;;;;N;;;;; +05D3;HEBREW LETTER DALET;Lo;0;R;;;;;N;;;;; +05D4;HEBREW LETTER HE;Lo;0;R;;;;;N;;;;; +05D5;HEBREW LETTER VAV;Lo;0;R;;;;;N;;;;; +05D6;HEBREW LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +05D7;HEBREW LETTER HET;Lo;0;R;;;;;N;;;;; +05D8;HEBREW LETTER TET;Lo;0;R;;;;;N;;;;; +05D9;HEBREW LETTER YOD;Lo;0;R;;;;;N;;;;; +05DA;HEBREW LETTER FINAL KAF;Lo;0;R;;;;;N;;;;; +05DB;HEBREW LETTER KAF;Lo;0;R;;;;;N;;;;; +05DC;HEBREW LETTER LAMED;Lo;0;R;;;;;N;;;;; +05DD;HEBREW LETTER FINAL MEM;Lo;0;R;;;;;N;;;;; +05DE;HEBREW LETTER MEM;Lo;0;R;;;;;N;;;;; +05DF;HEBREW LETTER FINAL NUN;Lo;0;R;;;;;N;;;;; +05E0;HEBREW LETTER NUN;Lo;0;R;;;;;N;;;;; +05E1;HEBREW LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +05E2;HEBREW LETTER AYIN;Lo;0;R;;;;;N;;;;; +05E3;HEBREW LETTER FINAL PE;Lo;0;R;;;;;N;;;;; +05E4;HEBREW LETTER PE;Lo;0;R;;;;;N;;;;; +05E5;HEBREW LETTER FINAL TSADI;Lo;0;R;;;;;N;;;;; +05E6;HEBREW LETTER TSADI;Lo;0;R;;;;;N;;;;; +05E7;HEBREW LETTER QOF;Lo;0;R;;;;;N;;;;; +05E8;HEBREW LETTER RESH;Lo;0;R;;;;;N;;;;; +05E9;HEBREW LETTER SHIN;Lo;0;R;;;;;N;;;;; +05EA;HEBREW LETTER TAV;Lo;0;R;;;;;N;;;;; +05F0;HEBREW LIGATURE YIDDISH DOUBLE VAV;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE VAV;;;; +05F1;HEBREW LIGATURE YIDDISH VAV YOD;Lo;0;R;;;;;N;HEBREW LETTER VAV YOD;;;; +05F2;HEBREW LIGATURE YIDDISH DOUBLE YOD;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE YOD;;;; +05F3;HEBREW PUNCTUATION GERESH;Po;0;R;;;;;N;;;;; +05F4;HEBREW PUNCTUATION GERSHAYIM;Po;0;R;;;;;N;;;;; +060C;ARABIC COMMA;Po;0;CS;;;;;N;;;;; +061B;ARABIC SEMICOLON;Po;0;AL;;;;;N;;;;; +061F;ARABIC QUESTION MARK;Po;0;AL;;;;;N;;;;; +0621;ARABIC LETTER HAMZA;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAH;;;; +0622;ARABIC LETTER ALEF WITH MADDA ABOVE;Lo;0;AL;0627 0653;;;;N;ARABIC LETTER MADDAH ON ALEF;;;; +0623;ARABIC LETTER ALEF WITH HAMZA ABOVE;Lo;0;AL;0627 0654;;;;N;ARABIC LETTER HAMZAH ON ALEF;;;; +0624;ARABIC LETTER WAW WITH HAMZA ABOVE;Lo;0;AL;0648 0654;;;;N;ARABIC LETTER HAMZAH ON WAW;;;; +0625;ARABIC LETTER ALEF WITH HAMZA BELOW;Lo;0;AL;0627 0655;;;;N;ARABIC LETTER HAMZAH UNDER ALEF;;;; +0626;ARABIC LETTER YEH WITH HAMZA ABOVE;Lo;0;AL;064A 0654;;;;N;ARABIC LETTER HAMZAH ON YA;;;; +0627;ARABIC LETTER ALEF;Lo;0;AL;;;;;N;;;;; +0628;ARABIC LETTER BEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA;;;; +0629;ARABIC LETTER TEH MARBUTA;Lo;0;AL;;;;;N;ARABIC LETTER TAA MARBUTAH;;;; +062A;ARABIC LETTER TEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA;;;; +062B;ARABIC LETTER THEH;Lo;0;AL;;;;;N;ARABIC LETTER THAA;;;; +062C;ARABIC LETTER JEEM;Lo;0;AL;;;;;N;;;;; +062D;ARABIC LETTER HAH;Lo;0;AL;;;;;N;ARABIC LETTER HAA;;;; +062E;ARABIC LETTER KHAH;Lo;0;AL;;;;;N;ARABIC LETTER KHAA;;;; +062F;ARABIC LETTER DAL;Lo;0;AL;;;;;N;;;;; +0630;ARABIC LETTER THAL;Lo;0;AL;;;;;N;;;;; +0631;ARABIC LETTER REH;Lo;0;AL;;;;;N;ARABIC LETTER RA;;;; +0632;ARABIC LETTER ZAIN;Lo;0;AL;;;;;N;;;;; +0633;ARABIC LETTER SEEN;Lo;0;AL;;;;;N;;;;; +0634;ARABIC LETTER SHEEN;Lo;0;AL;;;;;N;;;;; +0635;ARABIC LETTER SAD;Lo;0;AL;;;;;N;;;;; +0636;ARABIC LETTER DAD;Lo;0;AL;;;;;N;;;;; +0637;ARABIC LETTER TAH;Lo;0;AL;;;;;N;;;;; +0638;ARABIC LETTER ZAH;Lo;0;AL;;;;;N;ARABIC LETTER DHAH;;;; +0639;ARABIC LETTER AIN;Lo;0;AL;;;;;N;;;;; +063A;ARABIC LETTER GHAIN;Lo;0;AL;;;;;N;;;;; +0640;ARABIC TATWEEL;Lm;0;AL;;;;;N;;;;; +0641;ARABIC LETTER FEH;Lo;0;AL;;;;;N;ARABIC LETTER FA;;;; +0642;ARABIC LETTER QAF;Lo;0;AL;;;;;N;;;;; +0643;ARABIC LETTER KAF;Lo;0;AL;;;;;N;ARABIC LETTER CAF;;;; +0644;ARABIC LETTER LAM;Lo;0;AL;;;;;N;;;;; +0645;ARABIC LETTER MEEM;Lo;0;AL;;;;;N;;;;; +0646;ARABIC LETTER NOON;Lo;0;AL;;;;;N;;;;; +0647;ARABIC LETTER HEH;Lo;0;AL;;;;;N;ARABIC LETTER HA;;;; +0648;ARABIC LETTER WAW;Lo;0;AL;;;;;N;;;;; +0649;ARABIC LETTER ALEF MAKSURA;Lo;0;AL;;;;;N;ARABIC LETTER ALEF MAQSURAH;;;; +064A;ARABIC LETTER YEH;Lo;0;AL;;;;;N;ARABIC LETTER YA;;;; +064B;ARABIC FATHATAN;Mn;27;NSM;;;;;N;;;;; +064C;ARABIC DAMMATAN;Mn;28;NSM;;;;;N;;;;; +064D;ARABIC KASRATAN;Mn;29;NSM;;;;;N;;;;; +064E;ARABIC FATHA;Mn;30;NSM;;;;;N;ARABIC FATHAH;;;; +064F;ARABIC DAMMA;Mn;31;NSM;;;;;N;ARABIC DAMMAH;;;; +0650;ARABIC KASRA;Mn;32;NSM;;;;;N;ARABIC KASRAH;;;; +0651;ARABIC SHADDA;Mn;33;NSM;;;;;N;ARABIC SHADDAH;;;; +0652;ARABIC SUKUN;Mn;34;NSM;;;;;N;;;;; +0653;ARABIC MADDAH ABOVE;Mn;230;NSM;;;;;N;;;;; +0654;ARABIC HAMZA ABOVE;Mn;230;NSM;;;;;N;;;;; +0655;ARABIC HAMZA BELOW;Mn;220;NSM;;;;;N;;;;; +0660;ARABIC-INDIC DIGIT ZERO;Nd;0;AN;;0;0;0;N;;;;; +0661;ARABIC-INDIC DIGIT ONE;Nd;0;AN;;1;1;1;N;;;;; +0662;ARABIC-INDIC DIGIT TWO;Nd;0;AN;;2;2;2;N;;;;; +0663;ARABIC-INDIC DIGIT THREE;Nd;0;AN;;3;3;3;N;;;;; +0664;ARABIC-INDIC DIGIT FOUR;Nd;0;AN;;4;4;4;N;;;;; +0665;ARABIC-INDIC DIGIT FIVE;Nd;0;AN;;5;5;5;N;;;;; +0666;ARABIC-INDIC DIGIT SIX;Nd;0;AN;;6;6;6;N;;;;; +0667;ARABIC-INDIC DIGIT SEVEN;Nd;0;AN;;7;7;7;N;;;;; +0668;ARABIC-INDIC DIGIT EIGHT;Nd;0;AN;;8;8;8;N;;;;; +0669;ARABIC-INDIC DIGIT NINE;Nd;0;AN;;9;9;9;N;;;;; +066A;ARABIC PERCENT SIGN;Po;0;ET;;;;;N;;;;; +066B;ARABIC DECIMAL SEPARATOR;Po;0;AN;;;;;N;;;;; +066C;ARABIC THOUSANDS SEPARATOR;Po;0;AN;;;;;N;;;;; +066D;ARABIC FIVE POINTED STAR;Po;0;AL;;;;;N;;;;; +066E;ARABIC LETTER DOTLESS BEH;Lo;0;AL;;;;;N;;;;; +066F;ARABIC LETTER DOTLESS QAF;Lo;0;AL;;;;;N;;;;; +0670;ARABIC LETTER SUPERSCRIPT ALEF;Mn;35;NSM;;;;;N;ARABIC ALEF ABOVE;;;; +0671;ARABIC LETTER ALEF WASLA;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAT WASL ON ALEF;;;; +0672;ARABIC LETTER ALEF WITH WAVY HAMZA ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER WAVY HAMZAH ON ALEF;;;; +0673;ARABIC LETTER ALEF WITH WAVY HAMZA BELOW;Lo;0;AL;;;;;N;ARABIC LETTER WAVY HAMZAH UNDER ALEF;;;; +0674;ARABIC LETTER HIGH HAMZA;Lo;0;AL;;;;;N;ARABIC LETTER HIGH HAMZAH;;;; +0675;ARABIC LETTER HIGH HAMZA ALEF;Lo;0;AL; 0627 0674;;;;N;ARABIC LETTER HIGH HAMZAH ALEF;;;; +0676;ARABIC LETTER HIGH HAMZA WAW;Lo;0;AL; 0648 0674;;;;N;ARABIC LETTER HIGH HAMZAH WAW;;;; +0677;ARABIC LETTER U WITH HAMZA ABOVE;Lo;0;AL; 06C7 0674;;;;N;ARABIC LETTER HIGH HAMZAH WAW WITH DAMMAH;;;; +0678;ARABIC LETTER HIGH HAMZA YEH;Lo;0;AL; 064A 0674;;;;N;ARABIC LETTER HIGH HAMZAH YA;;;; +0679;ARABIC LETTER TTEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH SMALL TAH;;;; +067A;ARABIC LETTER TTEHEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH TWO DOTS VERTICAL ABOVE;;;; +067B;ARABIC LETTER BEEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA WITH TWO DOTS VERTICAL BELOW;;;; +067C;ARABIC LETTER TEH WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH RING;;;; +067D;ARABIC LETTER TEH WITH THREE DOTS ABOVE DOWNWARDS;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH THREE DOTS ABOVE DOWNWARD;;;; +067E;ARABIC LETTER PEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH THREE DOTS BELOW;;;; +067F;ARABIC LETTER TEHEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH FOUR DOTS ABOVE;;;; +0680;ARABIC LETTER BEHEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA WITH FOUR DOTS BELOW;;;; +0681;ARABIC LETTER HAH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAH ON HAA;;;; +0682;ARABIC LETTER HAH WITH TWO DOTS VERTICAL ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH TWO DOTS VERTICAL ABOVE;;;; +0683;ARABIC LETTER NYEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE TWO DOTS;;;; +0684;ARABIC LETTER DYEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE TWO DOTS VERTICAL;;;; +0685;ARABIC LETTER HAH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH THREE DOTS ABOVE;;;; +0686;ARABIC LETTER TCHEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE THREE DOTS DOWNWARD;;;; +0687;ARABIC LETTER TCHEHEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE FOUR DOTS;;;; +0688;ARABIC LETTER DDAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH SMALL TAH;;;; +0689;ARABIC LETTER DAL WITH RING;Lo;0;AL;;;;;N;;;;; +068A;ARABIC LETTER DAL WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +068B;ARABIC LETTER DAL WITH DOT BELOW AND SMALL TAH;Lo;0;AL;;;;;N;;;;; +068C;ARABIC LETTER DAHAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH TWO DOTS ABOVE;;;; +068D;ARABIC LETTER DDAHAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH TWO DOTS BELOW;;;; +068E;ARABIC LETTER DUL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH THREE DOTS ABOVE;;;; +068F;ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARDS;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARD;;;; +0690;ARABIC LETTER DAL WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0691;ARABIC LETTER RREH;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL TAH;;;; +0692;ARABIC LETTER REH WITH SMALL V;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL V;;;; +0693;ARABIC LETTER REH WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH RING;;;; +0694;ARABIC LETTER REH WITH DOT BELOW;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH DOT BELOW;;;; +0695;ARABIC LETTER REH WITH SMALL V BELOW;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL V BELOW;;;; +0696;ARABIC LETTER REH WITH DOT BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH DOT BELOW AND DOT ABOVE;;;; +0697;ARABIC LETTER REH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH TWO DOTS ABOVE;;;; +0698;ARABIC LETTER JEH;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH THREE DOTS ABOVE;;;; +0699;ARABIC LETTER REH WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH FOUR DOTS ABOVE;;;; +069A;ARABIC LETTER SEEN WITH DOT BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;;;;; +069B;ARABIC LETTER SEEN WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;; +069C;ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +069D;ARABIC LETTER SAD WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;; +069E;ARABIC LETTER SAD WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +069F;ARABIC LETTER TAH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06A0;ARABIC LETTER AIN WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06A1;ARABIC LETTER DOTLESS FEH;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS FA;;;; +06A2;ARABIC LETTER FEH WITH DOT MOVED BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH DOT MOVED BELOW;;;; +06A3;ARABIC LETTER FEH WITH DOT BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH DOT BELOW;;;; +06A4;ARABIC LETTER VEH;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH THREE DOTS ABOVE;;;; +06A5;ARABIC LETTER FEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH THREE DOTS BELOW;;;; +06A6;ARABIC LETTER PEHEH;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH FOUR DOTS ABOVE;;;; +06A7;ARABIC LETTER QAF WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +06A8;ARABIC LETTER QAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06A9;ARABIC LETTER KEHEH;Lo;0;AL;;;;;N;ARABIC LETTER OPEN CAF;;;; +06AA;ARABIC LETTER SWASH KAF;Lo;0;AL;;;;;N;ARABIC LETTER SWASH CAF;;;; +06AB;ARABIC LETTER KAF WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH RING;;;; +06AC;ARABIC LETTER KAF WITH DOT ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH DOT ABOVE;;;; +06AD;ARABIC LETTER NG;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS ABOVE;;;; +06AE;ARABIC LETTER KAF WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS BELOW;;;; +06AF;ARABIC LETTER GAF;Lo;0;AL;;;;;N;;*;;; +06B0;ARABIC LETTER GAF WITH RING;Lo;0;AL;;;;;N;;;;; +06B1;ARABIC LETTER NGOEH;Lo;0;AL;;;;;N;ARABIC LETTER GAF WITH TWO DOTS ABOVE;;;; +06B2;ARABIC LETTER GAF WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;; +06B3;ARABIC LETTER GUEH;Lo;0;AL;;;;;N;ARABIC LETTER GAF WITH TWO DOTS VERTICAL BELOW;;;; +06B4;ARABIC LETTER GAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06B5;ARABIC LETTER LAM WITH SMALL V;Lo;0;AL;;;;;N;;;;; +06B6;ARABIC LETTER LAM WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +06B7;ARABIC LETTER LAM WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06B8;ARABIC LETTER LAM WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;; +06B9;ARABIC LETTER NOON WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +06BA;ARABIC LETTER NOON GHUNNA;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS NOON;;;; +06BB;ARABIC LETTER RNOON;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS NOON WITH SMALL TAH;;;; +06BC;ARABIC LETTER NOON WITH RING;Lo;0;AL;;;;;N;;;;; +06BD;ARABIC LETTER NOON WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06BE;ARABIC LETTER HEH DOACHASHMEE;Lo;0;AL;;;;;N;ARABIC LETTER KNOTTED HA;;;; +06BF;ARABIC LETTER TCHEH WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +06C0;ARABIC LETTER HEH WITH YEH ABOVE;Lo;0;AL;06D5 0654;;;;N;ARABIC LETTER HAMZAH ON HA;;;; +06C1;ARABIC LETTER HEH GOAL;Lo;0;AL;;;;;N;ARABIC LETTER HA GOAL;;;; +06C2;ARABIC LETTER HEH GOAL WITH HAMZA ABOVE;Lo;0;AL;06C1 0654;;;;N;ARABIC LETTER HAMZAH ON HA GOAL;;;; +06C3;ARABIC LETTER TEH MARBUTA GOAL;Lo;0;AL;;;;;N;ARABIC LETTER TAA MARBUTAH GOAL;;;; +06C4;ARABIC LETTER WAW WITH RING;Lo;0;AL;;;;;N;;;;; +06C5;ARABIC LETTER KIRGHIZ OE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH BAR;;;; +06C6;ARABIC LETTER OE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH SMALL V;;;; +06C7;ARABIC LETTER U;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH DAMMAH;;;; +06C8;ARABIC LETTER YU;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH ALEF ABOVE;;;; +06C9;ARABIC LETTER KIRGHIZ YU;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH INVERTED SMALL V;;;; +06CA;ARABIC LETTER WAW WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06CB;ARABIC LETTER VE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH THREE DOTS ABOVE;;;; +06CC;ARABIC LETTER FARSI YEH;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS YA;;;; +06CD;ARABIC LETTER YEH WITH TAIL;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TAIL;;;; +06CE;ARABIC LETTER YEH WITH SMALL V;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH SMALL V;;;; +06CF;ARABIC LETTER WAW WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +06D0;ARABIC LETTER E;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TWO DOTS VERTICAL BELOW;*;;; +06D1;ARABIC LETTER YEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH THREE DOTS BELOW;;;; +06D2;ARABIC LETTER YEH BARREE;Lo;0;AL;;;;;N;ARABIC LETTER YA BARREE;;;; +06D3;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE;Lo;0;AL;06D2 0654;;;;N;ARABIC LETTER HAMZAH ON YA BARREE;;;; +06D4;ARABIC FULL STOP;Po;0;AL;;;;;N;ARABIC PERIOD;;;; +06D5;ARABIC LETTER AE;Lo;0;AL;;;;;N;;;;; +06D6;ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA;Mn;230;NSM;;;;;N;;;;; +06D7;ARABIC SMALL HIGH LIGATURE QAF WITH LAM WITH ALEF MAKSURA;Mn;230;NSM;;;;;N;;;;; +06D8;ARABIC SMALL HIGH MEEM INITIAL FORM;Mn;230;NSM;;;;;N;;;;; +06D9;ARABIC SMALL HIGH LAM ALEF;Mn;230;NSM;;;;;N;;;;; +06DA;ARABIC SMALL HIGH JEEM;Mn;230;NSM;;;;;N;;;;; +06DB;ARABIC SMALL HIGH THREE DOTS;Mn;230;NSM;;;;;N;;;;; +06DC;ARABIC SMALL HIGH SEEN;Mn;230;NSM;;;;;N;;;;; +06DD;ARABIC END OF AYAH;Cf;0;AL;;;;;N;;;;; +06DE;ARABIC START OF RUB EL HIZB;Me;0;NSM;;;;;N;;;;; +06DF;ARABIC SMALL HIGH ROUNDED ZERO;Mn;230;NSM;;;;;N;;;;; +06E0;ARABIC SMALL HIGH UPRIGHT RECTANGULAR ZERO;Mn;230;NSM;;;;;N;;;;; +06E1;ARABIC SMALL HIGH DOTLESS HEAD OF KHAH;Mn;230;NSM;;;;;N;;;;; +06E2;ARABIC SMALL HIGH MEEM ISOLATED FORM;Mn;230;NSM;;;;;N;;;;; +06E3;ARABIC SMALL LOW SEEN;Mn;220;NSM;;;;;N;;;;; +06E4;ARABIC SMALL HIGH MADDA;Mn;230;NSM;;;;;N;;;;; +06E5;ARABIC SMALL WAW;Lm;0;AL;;;;;N;;;;; +06E6;ARABIC SMALL YEH;Lm;0;AL;;;;;N;;;;; +06E7;ARABIC SMALL HIGH YEH;Mn;230;NSM;;;;;N;;;;; +06E8;ARABIC SMALL HIGH NOON;Mn;230;NSM;;;;;N;;;;; +06E9;ARABIC PLACE OF SAJDAH;So;0;ON;;;;;N;;;;; +06EA;ARABIC EMPTY CENTRE LOW STOP;Mn;220;NSM;;;;;N;;;;; +06EB;ARABIC EMPTY CENTRE HIGH STOP;Mn;230;NSM;;;;;N;;;;; +06EC;ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE;Mn;230;NSM;;;;;N;;;;; +06ED;ARABIC SMALL LOW MEEM;Mn;220;NSM;;;;;N;;;;; +06F0;EXTENDED ARABIC-INDIC DIGIT ZERO;Nd;0;EN;;0;0;0;N;EASTERN ARABIC-INDIC DIGIT ZERO;;;; +06F1;EXTENDED ARABIC-INDIC DIGIT ONE;Nd;0;EN;;1;1;1;N;EASTERN ARABIC-INDIC DIGIT ONE;;;; +06F2;EXTENDED ARABIC-INDIC DIGIT TWO;Nd;0;EN;;2;2;2;N;EASTERN ARABIC-INDIC DIGIT TWO;;;; +06F3;EXTENDED ARABIC-INDIC DIGIT THREE;Nd;0;EN;;3;3;3;N;EASTERN ARABIC-INDIC DIGIT THREE;;;; +06F4;EXTENDED ARABIC-INDIC DIGIT FOUR;Nd;0;EN;;4;4;4;N;EASTERN ARABIC-INDIC DIGIT FOUR;;;; +06F5;EXTENDED ARABIC-INDIC DIGIT FIVE;Nd;0;EN;;5;5;5;N;EASTERN ARABIC-INDIC DIGIT FIVE;;;; +06F6;EXTENDED ARABIC-INDIC DIGIT SIX;Nd;0;EN;;6;6;6;N;EASTERN ARABIC-INDIC DIGIT SIX;;;; +06F7;EXTENDED ARABIC-INDIC DIGIT SEVEN;Nd;0;EN;;7;7;7;N;EASTERN ARABIC-INDIC DIGIT SEVEN;;;; +06F8;EXTENDED ARABIC-INDIC DIGIT EIGHT;Nd;0;EN;;8;8;8;N;EASTERN ARABIC-INDIC DIGIT EIGHT;;;; +06F9;EXTENDED ARABIC-INDIC DIGIT NINE;Nd;0;EN;;9;9;9;N;EASTERN ARABIC-INDIC DIGIT NINE;;;; +06FA;ARABIC LETTER SHEEN WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +06FB;ARABIC LETTER DAD WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +06FC;ARABIC LETTER GHAIN WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +06FD;ARABIC SIGN SINDHI AMPERSAND;So;0;AL;;;;;N;;;;; +06FE;ARABIC SIGN SINDHI POSTPOSITION MEN;So;0;AL;;;;;N;;;;; +0700;SYRIAC END OF PARAGRAPH;Po;0;AL;;;;;N;;;;; +0701;SYRIAC SUPRALINEAR FULL STOP;Po;0;AL;;;;;N;;;;; +0702;SYRIAC SUBLINEAR FULL STOP;Po;0;AL;;;;;N;;;;; +0703;SYRIAC SUPRALINEAR COLON;Po;0;AL;;;;;N;;;;; +0704;SYRIAC SUBLINEAR COLON;Po;0;AL;;;;;N;;;;; +0705;SYRIAC HORIZONTAL COLON;Po;0;AL;;;;;N;;;;; +0706;SYRIAC COLON SKEWED LEFT;Po;0;AL;;;;;N;;;;; +0707;SYRIAC COLON SKEWED RIGHT;Po;0;AL;;;;;N;;;;; +0708;SYRIAC SUPRALINEAR COLON SKEWED LEFT;Po;0;AL;;;;;N;;;;; +0709;SYRIAC SUBLINEAR COLON SKEWED RIGHT;Po;0;AL;;;;;N;;;;; +070A;SYRIAC CONTRACTION;Po;0;AL;;;;;N;;;;; +070B;SYRIAC HARKLEAN OBELUS;Po;0;AL;;;;;N;;;;; +070C;SYRIAC HARKLEAN METOBELUS;Po;0;AL;;;;;N;;;;; +070D;SYRIAC HARKLEAN ASTERISCUS;Po;0;AL;;;;;N;;;;; +070F;SYRIAC ABBREVIATION MARK;Cf;0;BN;;;;;N;;;;; +0710;SYRIAC LETTER ALAPH;Lo;0;AL;;;;;N;;;;; +0711;SYRIAC LETTER SUPERSCRIPT ALAPH;Mn;36;NSM;;;;;N;;;;; +0712;SYRIAC LETTER BETH;Lo;0;AL;;;;;N;;;;; +0713;SYRIAC LETTER GAMAL;Lo;0;AL;;;;;N;;;;; +0714;SYRIAC LETTER GAMAL GARSHUNI;Lo;0;AL;;;;;N;;;;; +0715;SYRIAC LETTER DALATH;Lo;0;AL;;;;;N;;;;; +0716;SYRIAC LETTER DOTLESS DALATH RISH;Lo;0;AL;;;;;N;;;;; +0717;SYRIAC LETTER HE;Lo;0;AL;;;;;N;;;;; +0718;SYRIAC LETTER WAW;Lo;0;AL;;;;;N;;;;; +0719;SYRIAC LETTER ZAIN;Lo;0;AL;;;;;N;;;;; +071A;SYRIAC LETTER HETH;Lo;0;AL;;;;;N;;;;; +071B;SYRIAC LETTER TETH;Lo;0;AL;;;;;N;;;;; +071C;SYRIAC LETTER TETH GARSHUNI;Lo;0;AL;;;;;N;;;;; +071D;SYRIAC LETTER YUDH;Lo;0;AL;;;;;N;;;;; +071E;SYRIAC LETTER YUDH HE;Lo;0;AL;;;;;N;;;;; +071F;SYRIAC LETTER KAPH;Lo;0;AL;;;;;N;;;;; +0720;SYRIAC LETTER LAMADH;Lo;0;AL;;;;;N;;;;; +0721;SYRIAC LETTER MIM;Lo;0;AL;;;;;N;;;;; +0722;SYRIAC LETTER NUN;Lo;0;AL;;;;;N;;;;; +0723;SYRIAC LETTER SEMKATH;Lo;0;AL;;;;;N;;;;; +0724;SYRIAC LETTER FINAL SEMKATH;Lo;0;AL;;;;;N;;;;; +0725;SYRIAC LETTER E;Lo;0;AL;;;;;N;;;;; +0726;SYRIAC LETTER PE;Lo;0;AL;;;;;N;;;;; +0727;SYRIAC LETTER REVERSED PE;Lo;0;AL;;;;;N;;;;; +0728;SYRIAC LETTER SADHE;Lo;0;AL;;;;;N;;;;; +0729;SYRIAC LETTER QAPH;Lo;0;AL;;;;;N;;;;; +072A;SYRIAC LETTER RISH;Lo;0;AL;;;;;N;;;;; +072B;SYRIAC LETTER SHIN;Lo;0;AL;;;;;N;;;;; +072C;SYRIAC LETTER TAW;Lo;0;AL;;;;;N;;;;; +0730;SYRIAC PTHAHA ABOVE;Mn;230;NSM;;;;;N;;;;; +0731;SYRIAC PTHAHA BELOW;Mn;220;NSM;;;;;N;;;;; +0732;SYRIAC PTHAHA DOTTED;Mn;230;NSM;;;;;N;;;;; +0733;SYRIAC ZQAPHA ABOVE;Mn;230;NSM;;;;;N;;;;; +0734;SYRIAC ZQAPHA BELOW;Mn;220;NSM;;;;;N;;;;; +0735;SYRIAC ZQAPHA DOTTED;Mn;230;NSM;;;;;N;;;;; +0736;SYRIAC RBASA ABOVE;Mn;230;NSM;;;;;N;;;;; +0737;SYRIAC RBASA BELOW;Mn;220;NSM;;;;;N;;;;; +0738;SYRIAC DOTTED ZLAMA HORIZONTAL;Mn;220;NSM;;;;;N;;;;; +0739;SYRIAC DOTTED ZLAMA ANGULAR;Mn;220;NSM;;;;;N;;;;; +073A;SYRIAC HBASA ABOVE;Mn;230;NSM;;;;;N;;;;; +073B;SYRIAC HBASA BELOW;Mn;220;NSM;;;;;N;;;;; +073C;SYRIAC HBASA-ESASA DOTTED;Mn;220;NSM;;;;;N;;;;; +073D;SYRIAC ESASA ABOVE;Mn;230;NSM;;;;;N;;;;; +073E;SYRIAC ESASA BELOW;Mn;220;NSM;;;;;N;;;;; +073F;SYRIAC RWAHA;Mn;230;NSM;;;;;N;;;;; +0740;SYRIAC FEMININE DOT;Mn;230;NSM;;;;;N;;;;; +0741;SYRIAC QUSHSHAYA;Mn;230;NSM;;;;;N;;;;; +0742;SYRIAC RUKKAKHA;Mn;220;NSM;;;;;N;;;;; +0743;SYRIAC TWO VERTICAL DOTS ABOVE;Mn;230;NSM;;;;;N;;;;; +0744;SYRIAC TWO VERTICAL DOTS BELOW;Mn;220;NSM;;;;;N;;;;; +0745;SYRIAC THREE DOTS ABOVE;Mn;230;NSM;;;;;N;;;;; +0746;SYRIAC THREE DOTS BELOW;Mn;220;NSM;;;;;N;;;;; +0747;SYRIAC OBLIQUE LINE ABOVE;Mn;230;NSM;;;;;N;;;;; +0748;SYRIAC OBLIQUE LINE BELOW;Mn;220;NSM;;;;;N;;;;; +0749;SYRIAC MUSIC;Mn;230;NSM;;;;;N;;;;; +074A;SYRIAC BARREKH;Mn;230;NSM;;;;;N;;;;; +0780;THAANA LETTER HAA;Lo;0;AL;;;;;N;;;;; +0781;THAANA LETTER SHAVIYANI;Lo;0;AL;;;;;N;;;;; +0782;THAANA LETTER NOONU;Lo;0;AL;;;;;N;;;;; +0783;THAANA LETTER RAA;Lo;0;AL;;;;;N;;;;; +0784;THAANA LETTER BAA;Lo;0;AL;;;;;N;;;;; +0785;THAANA LETTER LHAVIYANI;Lo;0;AL;;;;;N;;;;; +0786;THAANA LETTER KAAFU;Lo;0;AL;;;;;N;;;;; +0787;THAANA LETTER ALIFU;Lo;0;AL;;;;;N;;;;; +0788;THAANA LETTER VAAVU;Lo;0;AL;;;;;N;;;;; +0789;THAANA LETTER MEEMU;Lo;0;AL;;;;;N;;;;; +078A;THAANA LETTER FAAFU;Lo;0;AL;;;;;N;;;;; +078B;THAANA LETTER DHAALU;Lo;0;AL;;;;;N;;;;; +078C;THAANA LETTER THAA;Lo;0;AL;;;;;N;;;;; +078D;THAANA LETTER LAAMU;Lo;0;AL;;;;;N;;;;; +078E;THAANA LETTER GAAFU;Lo;0;AL;;;;;N;;;;; +078F;THAANA LETTER GNAVIYANI;Lo;0;AL;;;;;N;;;;; +0790;THAANA LETTER SEENU;Lo;0;AL;;;;;N;;;;; +0791;THAANA LETTER DAVIYANI;Lo;0;AL;;;;;N;;;;; +0792;THAANA LETTER ZAVIYANI;Lo;0;AL;;;;;N;;;;; +0793;THAANA LETTER TAVIYANI;Lo;0;AL;;;;;N;;;;; +0794;THAANA LETTER YAA;Lo;0;AL;;;;;N;;;;; +0795;THAANA LETTER PAVIYANI;Lo;0;AL;;;;;N;;;;; +0796;THAANA LETTER JAVIYANI;Lo;0;AL;;;;;N;;;;; +0797;THAANA LETTER CHAVIYANI;Lo;0;AL;;;;;N;;;;; +0798;THAANA LETTER TTAA;Lo;0;AL;;;;;N;;;;; +0799;THAANA LETTER HHAA;Lo;0;AL;;;;;N;;;;; +079A;THAANA LETTER KHAA;Lo;0;AL;;;;;N;;;;; +079B;THAANA LETTER THAALU;Lo;0;AL;;;;;N;;;;; +079C;THAANA LETTER ZAA;Lo;0;AL;;;;;N;;;;; +079D;THAANA LETTER SHEENU;Lo;0;AL;;;;;N;;;;; +079E;THAANA LETTER SAADHU;Lo;0;AL;;;;;N;;;;; +079F;THAANA LETTER DAADHU;Lo;0;AL;;;;;N;;;;; +07A0;THAANA LETTER TO;Lo;0;AL;;;;;N;;;;; +07A1;THAANA LETTER ZO;Lo;0;AL;;;;;N;;;;; +07A2;THAANA LETTER AINU;Lo;0;AL;;;;;N;;;;; +07A3;THAANA LETTER GHAINU;Lo;0;AL;;;;;N;;;;; +07A4;THAANA LETTER QAAFU;Lo;0;AL;;;;;N;;;;; +07A5;THAANA LETTER WAAVU;Lo;0;AL;;;;;N;;;;; +07A6;THAANA ABAFILI;Mn;0;NSM;;;;;N;;;;; +07A7;THAANA AABAAFILI;Mn;0;NSM;;;;;N;;;;; +07A8;THAANA IBIFILI;Mn;0;NSM;;;;;N;;;;; +07A9;THAANA EEBEEFILI;Mn;0;NSM;;;;;N;;;;; +07AA;THAANA UBUFILI;Mn;0;NSM;;;;;N;;;;; +07AB;THAANA OOBOOFILI;Mn;0;NSM;;;;;N;;;;; +07AC;THAANA EBEFILI;Mn;0;NSM;;;;;N;;;;; +07AD;THAANA EYBEYFILI;Mn;0;NSM;;;;;N;;;;; +07AE;THAANA OBOFILI;Mn;0;NSM;;;;;N;;;;; +07AF;THAANA OABOAFILI;Mn;0;NSM;;;;;N;;;;; +07B0;THAANA SUKUN;Mn;0;NSM;;;;;N;;;;; +07B1;THAANA LETTER NAA;Lo;0;AL;;;;;N;;;;; +0901;DEVANAGARI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +0902;DEVANAGARI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +0903;DEVANAGARI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0905;DEVANAGARI LETTER A;Lo;0;L;;;;;N;;;;; +0906;DEVANAGARI LETTER AA;Lo;0;L;;;;;N;;;;; +0907;DEVANAGARI LETTER I;Lo;0;L;;;;;N;;;;; +0908;DEVANAGARI LETTER II;Lo;0;L;;;;;N;;;;; +0909;DEVANAGARI LETTER U;Lo;0;L;;;;;N;;;;; +090A;DEVANAGARI LETTER UU;Lo;0;L;;;;;N;;;;; +090B;DEVANAGARI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +090C;DEVANAGARI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +090D;DEVANAGARI LETTER CANDRA E;Lo;0;L;;;;;N;;;;; +090E;DEVANAGARI LETTER SHORT E;Lo;0;L;;;;;N;;;;; +090F;DEVANAGARI LETTER E;Lo;0;L;;;;;N;;;;; +0910;DEVANAGARI LETTER AI;Lo;0;L;;;;;N;;;;; +0911;DEVANAGARI LETTER CANDRA O;Lo;0;L;;;;;N;;;;; +0912;DEVANAGARI LETTER SHORT O;Lo;0;L;;;;;N;;;;; +0913;DEVANAGARI LETTER O;Lo;0;L;;;;;N;;;;; +0914;DEVANAGARI LETTER AU;Lo;0;L;;;;;N;;;;; +0915;DEVANAGARI LETTER KA;Lo;0;L;;;;;N;;;;; +0916;DEVANAGARI LETTER KHA;Lo;0;L;;;;;N;;;;; +0917;DEVANAGARI LETTER GA;Lo;0;L;;;;;N;;;;; +0918;DEVANAGARI LETTER GHA;Lo;0;L;;;;;N;;;;; +0919;DEVANAGARI LETTER NGA;Lo;0;L;;;;;N;;;;; +091A;DEVANAGARI LETTER CA;Lo;0;L;;;;;N;;;;; +091B;DEVANAGARI LETTER CHA;Lo;0;L;;;;;N;;;;; +091C;DEVANAGARI LETTER JA;Lo;0;L;;;;;N;;;;; +091D;DEVANAGARI LETTER JHA;Lo;0;L;;;;;N;;;;; +091E;DEVANAGARI LETTER NYA;Lo;0;L;;;;;N;;;;; +091F;DEVANAGARI LETTER TTA;Lo;0;L;;;;;N;;;;; +0920;DEVANAGARI LETTER TTHA;Lo;0;L;;;;;N;;;;; +0921;DEVANAGARI LETTER DDA;Lo;0;L;;;;;N;;;;; +0922;DEVANAGARI LETTER DDHA;Lo;0;L;;;;;N;;;;; +0923;DEVANAGARI LETTER NNA;Lo;0;L;;;;;N;;;;; +0924;DEVANAGARI LETTER TA;Lo;0;L;;;;;N;;;;; +0925;DEVANAGARI LETTER THA;Lo;0;L;;;;;N;;;;; +0926;DEVANAGARI LETTER DA;Lo;0;L;;;;;N;;;;; +0927;DEVANAGARI LETTER DHA;Lo;0;L;;;;;N;;;;; +0928;DEVANAGARI LETTER NA;Lo;0;L;;;;;N;;;;; +0929;DEVANAGARI LETTER NNNA;Lo;0;L;0928 093C;;;;N;;;;; +092A;DEVANAGARI LETTER PA;Lo;0;L;;;;;N;;;;; +092B;DEVANAGARI LETTER PHA;Lo;0;L;;;;;N;;;;; +092C;DEVANAGARI LETTER BA;Lo;0;L;;;;;N;;;;; +092D;DEVANAGARI LETTER BHA;Lo;0;L;;;;;N;;;;; +092E;DEVANAGARI LETTER MA;Lo;0;L;;;;;N;;;;; +092F;DEVANAGARI LETTER YA;Lo;0;L;;;;;N;;;;; +0930;DEVANAGARI LETTER RA;Lo;0;L;;;;;N;;;;; +0931;DEVANAGARI LETTER RRA;Lo;0;L;0930 093C;;;;N;;;;; +0932;DEVANAGARI LETTER LA;Lo;0;L;;;;;N;;;;; +0933;DEVANAGARI LETTER LLA;Lo;0;L;;;;;N;;;;; +0934;DEVANAGARI LETTER LLLA;Lo;0;L;0933 093C;;;;N;;;;; +0935;DEVANAGARI LETTER VA;Lo;0;L;;;;;N;;;;; +0936;DEVANAGARI LETTER SHA;Lo;0;L;;;;;N;;;;; +0937;DEVANAGARI LETTER SSA;Lo;0;L;;;;;N;;;;; +0938;DEVANAGARI LETTER SA;Lo;0;L;;;;;N;;;;; +0939;DEVANAGARI LETTER HA;Lo;0;L;;;;;N;;;;; +093C;DEVANAGARI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +093D;DEVANAGARI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +093E;DEVANAGARI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +093F;DEVANAGARI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +0940;DEVANAGARI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +0941;DEVANAGARI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +0942;DEVANAGARI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +0943;DEVANAGARI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +0944;DEVANAGARI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +0945;DEVANAGARI VOWEL SIGN CANDRA E;Mn;0;NSM;;;;;N;;;;; +0946;DEVANAGARI VOWEL SIGN SHORT E;Mn;0;NSM;;;;;N;;;;; +0947;DEVANAGARI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +0948;DEVANAGARI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +0949;DEVANAGARI VOWEL SIGN CANDRA O;Mc;0;L;;;;;N;;;;; +094A;DEVANAGARI VOWEL SIGN SHORT O;Mc;0;L;;;;;N;;;;; +094B;DEVANAGARI VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +094C;DEVANAGARI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +094D;DEVANAGARI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0950;DEVANAGARI OM;Lo;0;L;;;;;N;;;;; +0951;DEVANAGARI STRESS SIGN UDATTA;Mn;230;NSM;;;;;N;;;;; +0952;DEVANAGARI STRESS SIGN ANUDATTA;Mn;220;NSM;;;;;N;;;;; +0953;DEVANAGARI GRAVE ACCENT;Mn;230;NSM;;;;;N;;;;; +0954;DEVANAGARI ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;; +0958;DEVANAGARI LETTER QA;Lo;0;L;0915 093C;;;;N;;;;; +0959;DEVANAGARI LETTER KHHA;Lo;0;L;0916 093C;;;;N;;;;; +095A;DEVANAGARI LETTER GHHA;Lo;0;L;0917 093C;;;;N;;;;; +095B;DEVANAGARI LETTER ZA;Lo;0;L;091C 093C;;;;N;;;;; +095C;DEVANAGARI LETTER DDDHA;Lo;0;L;0921 093C;;;;N;;;;; +095D;DEVANAGARI LETTER RHA;Lo;0;L;0922 093C;;;;N;;;;; +095E;DEVANAGARI LETTER FA;Lo;0;L;092B 093C;;;;N;;;;; +095F;DEVANAGARI LETTER YYA;Lo;0;L;092F 093C;;;;N;;;;; +0960;DEVANAGARI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0961;DEVANAGARI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0962;DEVANAGARI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +0963;DEVANAGARI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +0964;DEVANAGARI DANDA;Po;0;L;;;;;N;;;;; +0965;DEVANAGARI DOUBLE DANDA;Po;0;L;;;;;N;;;;; +0966;DEVANAGARI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0967;DEVANAGARI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0968;DEVANAGARI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0969;DEVANAGARI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +096A;DEVANAGARI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +096B;DEVANAGARI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +096C;DEVANAGARI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +096D;DEVANAGARI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +096E;DEVANAGARI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +096F;DEVANAGARI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0970;DEVANAGARI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; +0981;BENGALI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +0982;BENGALI SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +0983;BENGALI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0985;BENGALI LETTER A;Lo;0;L;;;;;N;;;;; +0986;BENGALI LETTER AA;Lo;0;L;;;;;N;;;;; +0987;BENGALI LETTER I;Lo;0;L;;;;;N;;;;; +0988;BENGALI LETTER II;Lo;0;L;;;;;N;;;;; +0989;BENGALI LETTER U;Lo;0;L;;;;;N;;;;; +098A;BENGALI LETTER UU;Lo;0;L;;;;;N;;;;; +098B;BENGALI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +098C;BENGALI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +098F;BENGALI LETTER E;Lo;0;L;;;;;N;;;;; +0990;BENGALI LETTER AI;Lo;0;L;;;;;N;;;;; +0993;BENGALI LETTER O;Lo;0;L;;;;;N;;;;; +0994;BENGALI LETTER AU;Lo;0;L;;;;;N;;;;; +0995;BENGALI LETTER KA;Lo;0;L;;;;;N;;;;; +0996;BENGALI LETTER KHA;Lo;0;L;;;;;N;;;;; +0997;BENGALI LETTER GA;Lo;0;L;;;;;N;;;;; +0998;BENGALI LETTER GHA;Lo;0;L;;;;;N;;;;; +0999;BENGALI LETTER NGA;Lo;0;L;;;;;N;;;;; +099A;BENGALI LETTER CA;Lo;0;L;;;;;N;;;;; +099B;BENGALI LETTER CHA;Lo;0;L;;;;;N;;;;; +099C;BENGALI LETTER JA;Lo;0;L;;;;;N;;;;; +099D;BENGALI LETTER JHA;Lo;0;L;;;;;N;;;;; +099E;BENGALI LETTER NYA;Lo;0;L;;;;;N;;;;; +099F;BENGALI LETTER TTA;Lo;0;L;;;;;N;;;;; +09A0;BENGALI LETTER TTHA;Lo;0;L;;;;;N;;;;; +09A1;BENGALI LETTER DDA;Lo;0;L;;;;;N;;;;; +09A2;BENGALI LETTER DDHA;Lo;0;L;;;;;N;;;;; +09A3;BENGALI LETTER NNA;Lo;0;L;;;;;N;;;;; +09A4;BENGALI LETTER TA;Lo;0;L;;;;;N;;;;; +09A5;BENGALI LETTER THA;Lo;0;L;;;;;N;;;;; +09A6;BENGALI LETTER DA;Lo;0;L;;;;;N;;;;; +09A7;BENGALI LETTER DHA;Lo;0;L;;;;;N;;;;; +09A8;BENGALI LETTER NA;Lo;0;L;;;;;N;;;;; +09AA;BENGALI LETTER PA;Lo;0;L;;;;;N;;;;; +09AB;BENGALI LETTER PHA;Lo;0;L;;;;;N;;;;; +09AC;BENGALI LETTER BA;Lo;0;L;;;;;N;;;;; +09AD;BENGALI LETTER BHA;Lo;0;L;;;;;N;;;;; +09AE;BENGALI LETTER MA;Lo;0;L;;;;;N;;;;; +09AF;BENGALI LETTER YA;Lo;0;L;;;;;N;;;;; +09B0;BENGALI LETTER RA;Lo;0;L;;;;;N;;;;; +09B2;BENGALI LETTER LA;Lo;0;L;;;;;N;;;;; +09B6;BENGALI LETTER SHA;Lo;0;L;;;;;N;;;;; +09B7;BENGALI LETTER SSA;Lo;0;L;;;;;N;;;;; +09B8;BENGALI LETTER SA;Lo;0;L;;;;;N;;;;; +09B9;BENGALI LETTER HA;Lo;0;L;;;;;N;;;;; +09BC;BENGALI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +09BE;BENGALI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +09BF;BENGALI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +09C0;BENGALI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +09C1;BENGALI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +09C2;BENGALI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +09C3;BENGALI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +09C4;BENGALI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +09C7;BENGALI VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +09C8;BENGALI VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +09CB;BENGALI VOWEL SIGN O;Mc;0;L;09C7 09BE;;;;N;;;;; +09CC;BENGALI VOWEL SIGN AU;Mc;0;L;09C7 09D7;;;;N;;;;; +09CD;BENGALI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +09D7;BENGALI AU LENGTH MARK;Mc;0;L;;;;;N;;;;; +09DC;BENGALI LETTER RRA;Lo;0;L;09A1 09BC;;;;N;;;;; +09DD;BENGALI LETTER RHA;Lo;0;L;09A2 09BC;;;;N;;;;; +09DF;BENGALI LETTER YYA;Lo;0;L;09AF 09BC;;;;N;;;;; +09E0;BENGALI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +09E1;BENGALI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +09E2;BENGALI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +09E3;BENGALI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +09E6;BENGALI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +09E7;BENGALI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +09E8;BENGALI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +09E9;BENGALI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +09EA;BENGALI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +09EB;BENGALI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +09EC;BENGALI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +09ED;BENGALI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +09EE;BENGALI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +09EF;BENGALI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +09F0;BENGALI LETTER RA WITH MIDDLE DIAGONAL;Lo;0;L;;;;;N;;Assamese;;; +09F1;BENGALI LETTER RA WITH LOWER DIAGONAL;Lo;0;L;;;;;N;BENGALI LETTER VA WITH LOWER DIAGONAL;Assamese;;; +09F2;BENGALI RUPEE MARK;Sc;0;ET;;;;;N;;;;; +09F3;BENGALI RUPEE SIGN;Sc;0;ET;;;;;N;;;;; +09F4;BENGALI CURRENCY NUMERATOR ONE;No;0;L;;;;1;N;;;;; +09F5;BENGALI CURRENCY NUMERATOR TWO;No;0;L;;;;2;N;;;;; +09F6;BENGALI CURRENCY NUMERATOR THREE;No;0;L;;;;3;N;;;;; +09F7;BENGALI CURRENCY NUMERATOR FOUR;No;0;L;;;;4;N;;;;; +09F8;BENGALI CURRENCY NUMERATOR ONE LESS THAN THE DENOMINATOR;No;0;L;;;;;N;;;;; +09F9;BENGALI CURRENCY DENOMINATOR SIXTEEN;No;0;L;;;;16;N;;;;; +09FA;BENGALI ISSHAR;So;0;L;;;;;N;;;;; +0A02;GURMUKHI SIGN BINDI;Mn;0;NSM;;;;;N;;;;; +0A05;GURMUKHI LETTER A;Lo;0;L;;;;;N;;;;; +0A06;GURMUKHI LETTER AA;Lo;0;L;;;;;N;;;;; +0A07;GURMUKHI LETTER I;Lo;0;L;;;;;N;;;;; +0A08;GURMUKHI LETTER II;Lo;0;L;;;;;N;;;;; +0A09;GURMUKHI LETTER U;Lo;0;L;;;;;N;;;;; +0A0A;GURMUKHI LETTER UU;Lo;0;L;;;;;N;;;;; +0A0F;GURMUKHI LETTER EE;Lo;0;L;;;;;N;;;;; +0A10;GURMUKHI LETTER AI;Lo;0;L;;;;;N;;;;; +0A13;GURMUKHI LETTER OO;Lo;0;L;;;;;N;;;;; +0A14;GURMUKHI LETTER AU;Lo;0;L;;;;;N;;;;; +0A15;GURMUKHI LETTER KA;Lo;0;L;;;;;N;;;;; +0A16;GURMUKHI LETTER KHA;Lo;0;L;;;;;N;;;;; +0A17;GURMUKHI LETTER GA;Lo;0;L;;;;;N;;;;; +0A18;GURMUKHI LETTER GHA;Lo;0;L;;;;;N;;;;; +0A19;GURMUKHI LETTER NGA;Lo;0;L;;;;;N;;;;; +0A1A;GURMUKHI LETTER CA;Lo;0;L;;;;;N;;;;; +0A1B;GURMUKHI LETTER CHA;Lo;0;L;;;;;N;;;;; +0A1C;GURMUKHI LETTER JA;Lo;0;L;;;;;N;;;;; +0A1D;GURMUKHI LETTER JHA;Lo;0;L;;;;;N;;;;; +0A1E;GURMUKHI LETTER NYA;Lo;0;L;;;;;N;;;;; +0A1F;GURMUKHI LETTER TTA;Lo;0;L;;;;;N;;;;; +0A20;GURMUKHI LETTER TTHA;Lo;0;L;;;;;N;;;;; +0A21;GURMUKHI LETTER DDA;Lo;0;L;;;;;N;;;;; +0A22;GURMUKHI LETTER DDHA;Lo;0;L;;;;;N;;;;; +0A23;GURMUKHI LETTER NNA;Lo;0;L;;;;;N;;;;; +0A24;GURMUKHI LETTER TA;Lo;0;L;;;;;N;;;;; +0A25;GURMUKHI LETTER THA;Lo;0;L;;;;;N;;;;; +0A26;GURMUKHI LETTER DA;Lo;0;L;;;;;N;;;;; +0A27;GURMUKHI LETTER DHA;Lo;0;L;;;;;N;;;;; +0A28;GURMUKHI LETTER NA;Lo;0;L;;;;;N;;;;; +0A2A;GURMUKHI LETTER PA;Lo;0;L;;;;;N;;;;; +0A2B;GURMUKHI LETTER PHA;Lo;0;L;;;;;N;;;;; +0A2C;GURMUKHI LETTER BA;Lo;0;L;;;;;N;;;;; +0A2D;GURMUKHI LETTER BHA;Lo;0;L;;;;;N;;;;; +0A2E;GURMUKHI LETTER MA;Lo;0;L;;;;;N;;;;; +0A2F;GURMUKHI LETTER YA;Lo;0;L;;;;;N;;;;; +0A30;GURMUKHI LETTER RA;Lo;0;L;;;;;N;;;;; +0A32;GURMUKHI LETTER LA;Lo;0;L;;;;;N;;;;; +0A33;GURMUKHI LETTER LLA;Lo;0;L;0A32 0A3C;;;;N;;;;; +0A35;GURMUKHI LETTER VA;Lo;0;L;;;;;N;;;;; +0A36;GURMUKHI LETTER SHA;Lo;0;L;0A38 0A3C;;;;N;;;;; +0A38;GURMUKHI LETTER SA;Lo;0;L;;;;;N;;;;; +0A39;GURMUKHI LETTER HA;Lo;0;L;;;;;N;;;;; +0A3C;GURMUKHI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +0A3E;GURMUKHI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0A3F;GURMUKHI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +0A40;GURMUKHI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +0A41;GURMUKHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +0A42;GURMUKHI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +0A47;GURMUKHI VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;; +0A48;GURMUKHI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +0A4B;GURMUKHI VOWEL SIGN OO;Mn;0;NSM;;;;;N;;;;; +0A4C;GURMUKHI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +0A4D;GURMUKHI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0A59;GURMUKHI LETTER KHHA;Lo;0;L;0A16 0A3C;;;;N;;;;; +0A5A;GURMUKHI LETTER GHHA;Lo;0;L;0A17 0A3C;;;;N;;;;; +0A5B;GURMUKHI LETTER ZA;Lo;0;L;0A1C 0A3C;;;;N;;;;; +0A5C;GURMUKHI LETTER RRA;Lo;0;L;;;;;N;;;;; +0A5E;GURMUKHI LETTER FA;Lo;0;L;0A2B 0A3C;;;;N;;;;; +0A66;GURMUKHI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0A67;GURMUKHI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0A68;GURMUKHI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0A69;GURMUKHI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0A6A;GURMUKHI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0A6B;GURMUKHI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0A6C;GURMUKHI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0A6D;GURMUKHI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0A6E;GURMUKHI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0A6F;GURMUKHI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0A70;GURMUKHI TIPPI;Mn;0;NSM;;;;;N;;;;; +0A71;GURMUKHI ADDAK;Mn;0;NSM;;;;;N;;;;; +0A72;GURMUKHI IRI;Lo;0;L;;;;;N;;;;; +0A73;GURMUKHI URA;Lo;0;L;;;;;N;;;;; +0A74;GURMUKHI EK ONKAR;Lo;0;L;;;;;N;;;;; +0A81;GUJARATI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +0A82;GUJARATI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +0A83;GUJARATI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0A85;GUJARATI LETTER A;Lo;0;L;;;;;N;;;;; +0A86;GUJARATI LETTER AA;Lo;0;L;;;;;N;;;;; +0A87;GUJARATI LETTER I;Lo;0;L;;;;;N;;;;; +0A88;GUJARATI LETTER II;Lo;0;L;;;;;N;;;;; +0A89;GUJARATI LETTER U;Lo;0;L;;;;;N;;;;; +0A8A;GUJARATI LETTER UU;Lo;0;L;;;;;N;;;;; +0A8B;GUJARATI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +0A8D;GUJARATI VOWEL CANDRA E;Lo;0;L;;;;;N;;;;; +0A8F;GUJARATI LETTER E;Lo;0;L;;;;;N;;;;; +0A90;GUJARATI LETTER AI;Lo;0;L;;;;;N;;;;; +0A91;GUJARATI VOWEL CANDRA O;Lo;0;L;;;;;N;;;;; +0A93;GUJARATI LETTER O;Lo;0;L;;;;;N;;;;; +0A94;GUJARATI LETTER AU;Lo;0;L;;;;;N;;;;; +0A95;GUJARATI LETTER KA;Lo;0;L;;;;;N;;;;; +0A96;GUJARATI LETTER KHA;Lo;0;L;;;;;N;;;;; +0A97;GUJARATI LETTER GA;Lo;0;L;;;;;N;;;;; +0A98;GUJARATI LETTER GHA;Lo;0;L;;;;;N;;;;; +0A99;GUJARATI LETTER NGA;Lo;0;L;;;;;N;;;;; +0A9A;GUJARATI LETTER CA;Lo;0;L;;;;;N;;;;; +0A9B;GUJARATI LETTER CHA;Lo;0;L;;;;;N;;;;; +0A9C;GUJARATI LETTER JA;Lo;0;L;;;;;N;;;;; +0A9D;GUJARATI LETTER JHA;Lo;0;L;;;;;N;;;;; +0A9E;GUJARATI LETTER NYA;Lo;0;L;;;;;N;;;;; +0A9F;GUJARATI LETTER TTA;Lo;0;L;;;;;N;;;;; +0AA0;GUJARATI LETTER TTHA;Lo;0;L;;;;;N;;;;; +0AA1;GUJARATI LETTER DDA;Lo;0;L;;;;;N;;;;; +0AA2;GUJARATI LETTER DDHA;Lo;0;L;;;;;N;;;;; +0AA3;GUJARATI LETTER NNA;Lo;0;L;;;;;N;;;;; +0AA4;GUJARATI LETTER TA;Lo;0;L;;;;;N;;;;; +0AA5;GUJARATI LETTER THA;Lo;0;L;;;;;N;;;;; +0AA6;GUJARATI LETTER DA;Lo;0;L;;;;;N;;;;; +0AA7;GUJARATI LETTER DHA;Lo;0;L;;;;;N;;;;; +0AA8;GUJARATI LETTER NA;Lo;0;L;;;;;N;;;;; +0AAA;GUJARATI LETTER PA;Lo;0;L;;;;;N;;;;; +0AAB;GUJARATI LETTER PHA;Lo;0;L;;;;;N;;;;; +0AAC;GUJARATI LETTER BA;Lo;0;L;;;;;N;;;;; +0AAD;GUJARATI LETTER BHA;Lo;0;L;;;;;N;;;;; +0AAE;GUJARATI LETTER MA;Lo;0;L;;;;;N;;;;; +0AAF;GUJARATI LETTER YA;Lo;0;L;;;;;N;;;;; +0AB0;GUJARATI LETTER RA;Lo;0;L;;;;;N;;;;; +0AB2;GUJARATI LETTER LA;Lo;0;L;;;;;N;;;;; +0AB3;GUJARATI LETTER LLA;Lo;0;L;;;;;N;;;;; +0AB5;GUJARATI LETTER VA;Lo;0;L;;;;;N;;;;; +0AB6;GUJARATI LETTER SHA;Lo;0;L;;;;;N;;;;; +0AB7;GUJARATI LETTER SSA;Lo;0;L;;;;;N;;;;; +0AB8;GUJARATI LETTER SA;Lo;0;L;;;;;N;;;;; +0AB9;GUJARATI LETTER HA;Lo;0;L;;;;;N;;;;; +0ABC;GUJARATI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +0ABD;GUJARATI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +0ABE;GUJARATI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0ABF;GUJARATI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +0AC0;GUJARATI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +0AC1;GUJARATI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +0AC2;GUJARATI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +0AC3;GUJARATI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +0AC4;GUJARATI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +0AC5;GUJARATI VOWEL SIGN CANDRA E;Mn;0;NSM;;;;;N;;;;; +0AC7;GUJARATI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +0AC8;GUJARATI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +0AC9;GUJARATI VOWEL SIGN CANDRA O;Mc;0;L;;;;;N;;;;; +0ACB;GUJARATI VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +0ACC;GUJARATI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +0ACD;GUJARATI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0AD0;GUJARATI OM;Lo;0;L;;;;;N;;;;; +0AE0;GUJARATI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0AE6;GUJARATI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0AE7;GUJARATI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0AE8;GUJARATI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0AE9;GUJARATI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0AEA;GUJARATI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0AEB;GUJARATI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0AEC;GUJARATI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0AED;GUJARATI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0AEE;GUJARATI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0AEF;GUJARATI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0B01;ORIYA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +0B02;ORIYA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +0B03;ORIYA SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0B05;ORIYA LETTER A;Lo;0;L;;;;;N;;;;; +0B06;ORIYA LETTER AA;Lo;0;L;;;;;N;;;;; +0B07;ORIYA LETTER I;Lo;0;L;;;;;N;;;;; +0B08;ORIYA LETTER II;Lo;0;L;;;;;N;;;;; +0B09;ORIYA LETTER U;Lo;0;L;;;;;N;;;;; +0B0A;ORIYA LETTER UU;Lo;0;L;;;;;N;;;;; +0B0B;ORIYA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +0B0C;ORIYA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +0B0F;ORIYA LETTER E;Lo;0;L;;;;;N;;;;; +0B10;ORIYA LETTER AI;Lo;0;L;;;;;N;;;;; +0B13;ORIYA LETTER O;Lo;0;L;;;;;N;;;;; +0B14;ORIYA LETTER AU;Lo;0;L;;;;;N;;;;; +0B15;ORIYA LETTER KA;Lo;0;L;;;;;N;;;;; +0B16;ORIYA LETTER KHA;Lo;0;L;;;;;N;;;;; +0B17;ORIYA LETTER GA;Lo;0;L;;;;;N;;;;; +0B18;ORIYA LETTER GHA;Lo;0;L;;;;;N;;;;; +0B19;ORIYA LETTER NGA;Lo;0;L;;;;;N;;;;; +0B1A;ORIYA LETTER CA;Lo;0;L;;;;;N;;;;; +0B1B;ORIYA LETTER CHA;Lo;0;L;;;;;N;;;;; +0B1C;ORIYA LETTER JA;Lo;0;L;;;;;N;;;;; +0B1D;ORIYA LETTER JHA;Lo;0;L;;;;;N;;;;; +0B1E;ORIYA LETTER NYA;Lo;0;L;;;;;N;;;;; +0B1F;ORIYA LETTER TTA;Lo;0;L;;;;;N;;;;; +0B20;ORIYA LETTER TTHA;Lo;0;L;;;;;N;;;;; +0B21;ORIYA LETTER DDA;Lo;0;L;;;;;N;;;;; +0B22;ORIYA LETTER DDHA;Lo;0;L;;;;;N;;;;; +0B23;ORIYA LETTER NNA;Lo;0;L;;;;;N;;;;; +0B24;ORIYA LETTER TA;Lo;0;L;;;;;N;;;;; +0B25;ORIYA LETTER THA;Lo;0;L;;;;;N;;;;; +0B26;ORIYA LETTER DA;Lo;0;L;;;;;N;;;;; +0B27;ORIYA LETTER DHA;Lo;0;L;;;;;N;;;;; +0B28;ORIYA LETTER NA;Lo;0;L;;;;;N;;;;; +0B2A;ORIYA LETTER PA;Lo;0;L;;;;;N;;;;; +0B2B;ORIYA LETTER PHA;Lo;0;L;;;;;N;;;;; +0B2C;ORIYA LETTER BA;Lo;0;L;;;;;N;;;;; +0B2D;ORIYA LETTER BHA;Lo;0;L;;;;;N;;;;; +0B2E;ORIYA LETTER MA;Lo;0;L;;;;;N;;;;; +0B2F;ORIYA LETTER YA;Lo;0;L;;;;;N;;;;; +0B30;ORIYA LETTER RA;Lo;0;L;;;;;N;;;;; +0B32;ORIYA LETTER LA;Lo;0;L;;;;;N;;;;; +0B33;ORIYA LETTER LLA;Lo;0;L;;;;;N;;;;; +0B36;ORIYA LETTER SHA;Lo;0;L;;;;;N;;;;; +0B37;ORIYA LETTER SSA;Lo;0;L;;;;;N;;;;; +0B38;ORIYA LETTER SA;Lo;0;L;;;;;N;;;;; +0B39;ORIYA LETTER HA;Lo;0;L;;;;;N;;;;; +0B3C;ORIYA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +0B3D;ORIYA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +0B3E;ORIYA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0B3F;ORIYA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +0B40;ORIYA VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +0B41;ORIYA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +0B42;ORIYA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +0B43;ORIYA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +0B47;ORIYA VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +0B48;ORIYA VOWEL SIGN AI;Mc;0;L;0B47 0B56;;;;N;;;;; +0B4B;ORIYA VOWEL SIGN O;Mc;0;L;0B47 0B3E;;;;N;;;;; +0B4C;ORIYA VOWEL SIGN AU;Mc;0;L;0B47 0B57;;;;N;;;;; +0B4D;ORIYA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0B56;ORIYA AI LENGTH MARK;Mn;0;NSM;;;;;N;;;;; +0B57;ORIYA AU LENGTH MARK;Mc;0;L;;;;;N;;;;; +0B5C;ORIYA LETTER RRA;Lo;0;L;0B21 0B3C;;;;N;;;;; +0B5D;ORIYA LETTER RHA;Lo;0;L;0B22 0B3C;;;;N;;;;; +0B5F;ORIYA LETTER YYA;Lo;0;L;;;;;N;;;;; +0B60;ORIYA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0B61;ORIYA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0B66;ORIYA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0B67;ORIYA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0B68;ORIYA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0B69;ORIYA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0B6A;ORIYA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0B6B;ORIYA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0B6C;ORIYA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0B6D;ORIYA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0B6E;ORIYA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0B6F;ORIYA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0B70;ORIYA ISSHAR;So;0;L;;;;;N;;;;; +0B82;TAMIL SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +0B83;TAMIL SIGN VISARGA;Lo;0;L;;;;;N;;;;; +0B85;TAMIL LETTER A;Lo;0;L;;;;;N;;;;; +0B86;TAMIL LETTER AA;Lo;0;L;;;;;N;;;;; +0B87;TAMIL LETTER I;Lo;0;L;;;;;N;;;;; +0B88;TAMIL LETTER II;Lo;0;L;;;;;N;;;;; +0B89;TAMIL LETTER U;Lo;0;L;;;;;N;;;;; +0B8A;TAMIL LETTER UU;Lo;0;L;;;;;N;;;;; +0B8E;TAMIL LETTER E;Lo;0;L;;;;;N;;;;; +0B8F;TAMIL LETTER EE;Lo;0;L;;;;;N;;;;; +0B90;TAMIL LETTER AI;Lo;0;L;;;;;N;;;;; +0B92;TAMIL LETTER O;Lo;0;L;;;;;N;;;;; +0B93;TAMIL LETTER OO;Lo;0;L;;;;;N;;;;; +0B94;TAMIL LETTER AU;Lo;0;L;0B92 0BD7;;;;N;;;;; +0B95;TAMIL LETTER KA;Lo;0;L;;;;;N;;;;; +0B99;TAMIL LETTER NGA;Lo;0;L;;;;;N;;;;; +0B9A;TAMIL LETTER CA;Lo;0;L;;;;;N;;;;; +0B9C;TAMIL LETTER JA;Lo;0;L;;;;;N;;;;; +0B9E;TAMIL LETTER NYA;Lo;0;L;;;;;N;;;;; +0B9F;TAMIL LETTER TTA;Lo;0;L;;;;;N;;;;; +0BA3;TAMIL LETTER NNA;Lo;0;L;;;;;N;;;;; +0BA4;TAMIL LETTER TA;Lo;0;L;;;;;N;;;;; +0BA8;TAMIL LETTER NA;Lo;0;L;;;;;N;;;;; +0BA9;TAMIL LETTER NNNA;Lo;0;L;;;;;N;;;;; +0BAA;TAMIL LETTER PA;Lo;0;L;;;;;N;;;;; +0BAE;TAMIL LETTER MA;Lo;0;L;;;;;N;;;;; +0BAF;TAMIL LETTER YA;Lo;0;L;;;;;N;;;;; +0BB0;TAMIL LETTER RA;Lo;0;L;;;;;N;;;;; +0BB1;TAMIL LETTER RRA;Lo;0;L;;;;;N;;;;; +0BB2;TAMIL LETTER LA;Lo;0;L;;;;;N;;;;; +0BB3;TAMIL LETTER LLA;Lo;0;L;;;;;N;;;;; +0BB4;TAMIL LETTER LLLA;Lo;0;L;;;;;N;;;;; +0BB5;TAMIL LETTER VA;Lo;0;L;;;;;N;;;;; +0BB7;TAMIL LETTER SSA;Lo;0;L;;;;;N;;;;; +0BB8;TAMIL LETTER SA;Lo;0;L;;;;;N;;;;; +0BB9;TAMIL LETTER HA;Lo;0;L;;;;;N;;;;; +0BBE;TAMIL VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0BBF;TAMIL VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +0BC0;TAMIL VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +0BC1;TAMIL VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +0BC2;TAMIL VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +0BC6;TAMIL VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +0BC7;TAMIL VOWEL SIGN EE;Mc;0;L;;;;;N;;;;; +0BC8;TAMIL VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +0BCA;TAMIL VOWEL SIGN O;Mc;0;L;0BC6 0BBE;;;;N;;;;; +0BCB;TAMIL VOWEL SIGN OO;Mc;0;L;0BC7 0BBE;;;;N;;;;; +0BCC;TAMIL VOWEL SIGN AU;Mc;0;L;0BC6 0BD7;;;;N;;;;; +0BCD;TAMIL SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0BD7;TAMIL AU LENGTH MARK;Mc;0;L;;;;;N;;;;; +0BE7;TAMIL DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0BE8;TAMIL DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0BE9;TAMIL DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0BEA;TAMIL DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0BEB;TAMIL DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0BEC;TAMIL DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0BED;TAMIL DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0BEE;TAMIL DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0BEF;TAMIL DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0BF0;TAMIL NUMBER TEN;No;0;L;;;;10;N;;;;; +0BF1;TAMIL NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;; +0BF2;TAMIL NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;; +0C01;TELUGU SIGN CANDRABINDU;Mc;0;L;;;;;N;;;;; +0C02;TELUGU SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +0C03;TELUGU SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0C05;TELUGU LETTER A;Lo;0;L;;;;;N;;;;; +0C06;TELUGU LETTER AA;Lo;0;L;;;;;N;;;;; +0C07;TELUGU LETTER I;Lo;0;L;;;;;N;;;;; +0C08;TELUGU LETTER II;Lo;0;L;;;;;N;;;;; +0C09;TELUGU LETTER U;Lo;0;L;;;;;N;;;;; +0C0A;TELUGU LETTER UU;Lo;0;L;;;;;N;;;;; +0C0B;TELUGU LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +0C0C;TELUGU LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +0C0E;TELUGU LETTER E;Lo;0;L;;;;;N;;;;; +0C0F;TELUGU LETTER EE;Lo;0;L;;;;;N;;;;; +0C10;TELUGU LETTER AI;Lo;0;L;;;;;N;;;;; +0C12;TELUGU LETTER O;Lo;0;L;;;;;N;;;;; +0C13;TELUGU LETTER OO;Lo;0;L;;;;;N;;;;; +0C14;TELUGU LETTER AU;Lo;0;L;;;;;N;;;;; +0C15;TELUGU LETTER KA;Lo;0;L;;;;;N;;;;; +0C16;TELUGU LETTER KHA;Lo;0;L;;;;;N;;;;; +0C17;TELUGU LETTER GA;Lo;0;L;;;;;N;;;;; +0C18;TELUGU LETTER GHA;Lo;0;L;;;;;N;;;;; +0C19;TELUGU LETTER NGA;Lo;0;L;;;;;N;;;;; +0C1A;TELUGU LETTER CA;Lo;0;L;;;;;N;;;;; +0C1B;TELUGU LETTER CHA;Lo;0;L;;;;;N;;;;; +0C1C;TELUGU LETTER JA;Lo;0;L;;;;;N;;;;; +0C1D;TELUGU LETTER JHA;Lo;0;L;;;;;N;;;;; +0C1E;TELUGU LETTER NYA;Lo;0;L;;;;;N;;;;; +0C1F;TELUGU LETTER TTA;Lo;0;L;;;;;N;;;;; +0C20;TELUGU LETTER TTHA;Lo;0;L;;;;;N;;;;; +0C21;TELUGU LETTER DDA;Lo;0;L;;;;;N;;;;; +0C22;TELUGU LETTER DDHA;Lo;0;L;;;;;N;;;;; +0C23;TELUGU LETTER NNA;Lo;0;L;;;;;N;;;;; +0C24;TELUGU LETTER TA;Lo;0;L;;;;;N;;;;; +0C25;TELUGU LETTER THA;Lo;0;L;;;;;N;;;;; +0C26;TELUGU LETTER DA;Lo;0;L;;;;;N;;;;; +0C27;TELUGU LETTER DHA;Lo;0;L;;;;;N;;;;; +0C28;TELUGU LETTER NA;Lo;0;L;;;;;N;;;;; +0C2A;TELUGU LETTER PA;Lo;0;L;;;;;N;;;;; +0C2B;TELUGU LETTER PHA;Lo;0;L;;;;;N;;;;; +0C2C;TELUGU LETTER BA;Lo;0;L;;;;;N;;;;; +0C2D;TELUGU LETTER BHA;Lo;0;L;;;;;N;;;;; +0C2E;TELUGU LETTER MA;Lo;0;L;;;;;N;;;;; +0C2F;TELUGU LETTER YA;Lo;0;L;;;;;N;;;;; +0C30;TELUGU LETTER RA;Lo;0;L;;;;;N;;;;; +0C31;TELUGU LETTER RRA;Lo;0;L;;;;;N;;;;; +0C32;TELUGU LETTER LA;Lo;0;L;;;;;N;;;;; +0C33;TELUGU LETTER LLA;Lo;0;L;;;;;N;;;;; +0C35;TELUGU LETTER VA;Lo;0;L;;;;;N;;;;; +0C36;TELUGU LETTER SHA;Lo;0;L;;;;;N;;;;; +0C37;TELUGU LETTER SSA;Lo;0;L;;;;;N;;;;; +0C38;TELUGU LETTER SA;Lo;0;L;;;;;N;;;;; +0C39;TELUGU LETTER HA;Lo;0;L;;;;;N;;;;; +0C3E;TELUGU VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;; +0C3F;TELUGU VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +0C40;TELUGU VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +0C41;TELUGU VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +0C42;TELUGU VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +0C43;TELUGU VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;; +0C44;TELUGU VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;; +0C46;TELUGU VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +0C47;TELUGU VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;; +0C48;TELUGU VOWEL SIGN AI;Mn;0;NSM;0C46 0C56;;;;N;;;;; +0C4A;TELUGU VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +0C4B;TELUGU VOWEL SIGN OO;Mn;0;NSM;;;;;N;;;;; +0C4C;TELUGU VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +0C4D;TELUGU SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0C55;TELUGU LENGTH MARK;Mn;84;NSM;;;;;N;;;;; +0C56;TELUGU AI LENGTH MARK;Mn;91;NSM;;;;;N;;;;; +0C60;TELUGU LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0C61;TELUGU LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0C66;TELUGU DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0C67;TELUGU DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0C68;TELUGU DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0C69;TELUGU DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0C6A;TELUGU DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0C6B;TELUGU DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0C6C;TELUGU DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0C6D;TELUGU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0C6E;TELUGU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0C6F;TELUGU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0C82;KANNADA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +0C83;KANNADA SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0C85;KANNADA LETTER A;Lo;0;L;;;;;N;;;;; +0C86;KANNADA LETTER AA;Lo;0;L;;;;;N;;;;; +0C87;KANNADA LETTER I;Lo;0;L;;;;;N;;;;; +0C88;KANNADA LETTER II;Lo;0;L;;;;;N;;;;; +0C89;KANNADA LETTER U;Lo;0;L;;;;;N;;;;; +0C8A;KANNADA LETTER UU;Lo;0;L;;;;;N;;;;; +0C8B;KANNADA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +0C8C;KANNADA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +0C8E;KANNADA LETTER E;Lo;0;L;;;;;N;;;;; +0C8F;KANNADA LETTER EE;Lo;0;L;;;;;N;;;;; +0C90;KANNADA LETTER AI;Lo;0;L;;;;;N;;;;; +0C92;KANNADA LETTER O;Lo;0;L;;;;;N;;;;; +0C93;KANNADA LETTER OO;Lo;0;L;;;;;N;;;;; +0C94;KANNADA LETTER AU;Lo;0;L;;;;;N;;;;; +0C95;KANNADA LETTER KA;Lo;0;L;;;;;N;;;;; +0C96;KANNADA LETTER KHA;Lo;0;L;;;;;N;;;;; +0C97;KANNADA LETTER GA;Lo;0;L;;;;;N;;;;; +0C98;KANNADA LETTER GHA;Lo;0;L;;;;;N;;;;; +0C99;KANNADA LETTER NGA;Lo;0;L;;;;;N;;;;; +0C9A;KANNADA LETTER CA;Lo;0;L;;;;;N;;;;; +0C9B;KANNADA LETTER CHA;Lo;0;L;;;;;N;;;;; +0C9C;KANNADA LETTER JA;Lo;0;L;;;;;N;;;;; +0C9D;KANNADA LETTER JHA;Lo;0;L;;;;;N;;;;; +0C9E;KANNADA LETTER NYA;Lo;0;L;;;;;N;;;;; +0C9F;KANNADA LETTER TTA;Lo;0;L;;;;;N;;;;; +0CA0;KANNADA LETTER TTHA;Lo;0;L;;;;;N;;;;; +0CA1;KANNADA LETTER DDA;Lo;0;L;;;;;N;;;;; +0CA2;KANNADA LETTER DDHA;Lo;0;L;;;;;N;;;;; +0CA3;KANNADA LETTER NNA;Lo;0;L;;;;;N;;;;; +0CA4;KANNADA LETTER TA;Lo;0;L;;;;;N;;;;; +0CA5;KANNADA LETTER THA;Lo;0;L;;;;;N;;;;; +0CA6;KANNADA LETTER DA;Lo;0;L;;;;;N;;;;; +0CA7;KANNADA LETTER DHA;Lo;0;L;;;;;N;;;;; +0CA8;KANNADA LETTER NA;Lo;0;L;;;;;N;;;;; +0CAA;KANNADA LETTER PA;Lo;0;L;;;;;N;;;;; +0CAB;KANNADA LETTER PHA;Lo;0;L;;;;;N;;;;; +0CAC;KANNADA LETTER BA;Lo;0;L;;;;;N;;;;; +0CAD;KANNADA LETTER BHA;Lo;0;L;;;;;N;;;;; +0CAE;KANNADA LETTER MA;Lo;0;L;;;;;N;;;;; +0CAF;KANNADA LETTER YA;Lo;0;L;;;;;N;;;;; +0CB0;KANNADA LETTER RA;Lo;0;L;;;;;N;;;;; +0CB1;KANNADA LETTER RRA;Lo;0;L;;;;;N;;;;; +0CB2;KANNADA LETTER LA;Lo;0;L;;;;;N;;;;; +0CB3;KANNADA LETTER LLA;Lo;0;L;;;;;N;;;;; +0CB5;KANNADA LETTER VA;Lo;0;L;;;;;N;;;;; +0CB6;KANNADA LETTER SHA;Lo;0;L;;;;;N;;;;; +0CB7;KANNADA LETTER SSA;Lo;0;L;;;;;N;;;;; +0CB8;KANNADA LETTER SA;Lo;0;L;;;;;N;;;;; +0CB9;KANNADA LETTER HA;Lo;0;L;;;;;N;;;;; +0CBE;KANNADA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0CBF;KANNADA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +0CC0;KANNADA VOWEL SIGN II;Mc;0;L;0CBF 0CD5;;;;N;;;;; +0CC1;KANNADA VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +0CC2;KANNADA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +0CC3;KANNADA VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;; +0CC4;KANNADA VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;; +0CC6;KANNADA VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +0CC7;KANNADA VOWEL SIGN EE;Mc;0;L;0CC6 0CD5;;;;N;;;;; +0CC8;KANNADA VOWEL SIGN AI;Mc;0;L;0CC6 0CD6;;;;N;;;;; +0CCA;KANNADA VOWEL SIGN O;Mc;0;L;0CC6 0CC2;;;;N;;;;; +0CCB;KANNADA VOWEL SIGN OO;Mc;0;L;0CCA 0CD5;;;;N;;;;; +0CCC;KANNADA VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +0CCD;KANNADA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0CD5;KANNADA LENGTH MARK;Mc;0;L;;;;;N;;;;; +0CD6;KANNADA AI LENGTH MARK;Mc;0;L;;;;;N;;;;; +0CDE;KANNADA LETTER FA;Lo;0;L;;;;;N;;;;; +0CE0;KANNADA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0CE1;KANNADA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0CE6;KANNADA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0CE7;KANNADA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0CE8;KANNADA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0CE9;KANNADA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0CEA;KANNADA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0CEB;KANNADA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0CEC;KANNADA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0CED;KANNADA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0CEE;KANNADA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0CEF;KANNADA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0D02;MALAYALAM SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +0D03;MALAYALAM SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0D05;MALAYALAM LETTER A;Lo;0;L;;;;;N;;;;; +0D06;MALAYALAM LETTER AA;Lo;0;L;;;;;N;;;;; +0D07;MALAYALAM LETTER I;Lo;0;L;;;;;N;;;;; +0D08;MALAYALAM LETTER II;Lo;0;L;;;;;N;;;;; +0D09;MALAYALAM LETTER U;Lo;0;L;;;;;N;;;;; +0D0A;MALAYALAM LETTER UU;Lo;0;L;;;;;N;;;;; +0D0B;MALAYALAM LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +0D0C;MALAYALAM LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +0D0E;MALAYALAM LETTER E;Lo;0;L;;;;;N;;;;; +0D0F;MALAYALAM LETTER EE;Lo;0;L;;;;;N;;;;; +0D10;MALAYALAM LETTER AI;Lo;0;L;;;;;N;;;;; +0D12;MALAYALAM LETTER O;Lo;0;L;;;;;N;;;;; +0D13;MALAYALAM LETTER OO;Lo;0;L;;;;;N;;;;; +0D14;MALAYALAM LETTER AU;Lo;0;L;;;;;N;;;;; +0D15;MALAYALAM LETTER KA;Lo;0;L;;;;;N;;;;; +0D16;MALAYALAM LETTER KHA;Lo;0;L;;;;;N;;;;; +0D17;MALAYALAM LETTER GA;Lo;0;L;;;;;N;;;;; +0D18;MALAYALAM LETTER GHA;Lo;0;L;;;;;N;;;;; +0D19;MALAYALAM LETTER NGA;Lo;0;L;;;;;N;;;;; +0D1A;MALAYALAM LETTER CA;Lo;0;L;;;;;N;;;;; +0D1B;MALAYALAM LETTER CHA;Lo;0;L;;;;;N;;;;; +0D1C;MALAYALAM LETTER JA;Lo;0;L;;;;;N;;;;; +0D1D;MALAYALAM LETTER JHA;Lo;0;L;;;;;N;;;;; +0D1E;MALAYALAM LETTER NYA;Lo;0;L;;;;;N;;;;; +0D1F;MALAYALAM LETTER TTA;Lo;0;L;;;;;N;;;;; +0D20;MALAYALAM LETTER TTHA;Lo;0;L;;;;;N;;;;; +0D21;MALAYALAM LETTER DDA;Lo;0;L;;;;;N;;;;; +0D22;MALAYALAM LETTER DDHA;Lo;0;L;;;;;N;;;;; +0D23;MALAYALAM LETTER NNA;Lo;0;L;;;;;N;;;;; +0D24;MALAYALAM LETTER TA;Lo;0;L;;;;;N;;;;; +0D25;MALAYALAM LETTER THA;Lo;0;L;;;;;N;;;;; +0D26;MALAYALAM LETTER DA;Lo;0;L;;;;;N;;;;; +0D27;MALAYALAM LETTER DHA;Lo;0;L;;;;;N;;;;; +0D28;MALAYALAM LETTER NA;Lo;0;L;;;;;N;;;;; +0D2A;MALAYALAM LETTER PA;Lo;0;L;;;;;N;;;;; +0D2B;MALAYALAM LETTER PHA;Lo;0;L;;;;;N;;;;; +0D2C;MALAYALAM LETTER BA;Lo;0;L;;;;;N;;;;; +0D2D;MALAYALAM LETTER BHA;Lo;0;L;;;;;N;;;;; +0D2E;MALAYALAM LETTER MA;Lo;0;L;;;;;N;;;;; +0D2F;MALAYALAM LETTER YA;Lo;0;L;;;;;N;;;;; +0D30;MALAYALAM LETTER RA;Lo;0;L;;;;;N;;;;; +0D31;MALAYALAM LETTER RRA;Lo;0;L;;;;;N;;;;; +0D32;MALAYALAM LETTER LA;Lo;0;L;;;;;N;;;;; +0D33;MALAYALAM LETTER LLA;Lo;0;L;;;;;N;;;;; +0D34;MALAYALAM LETTER LLLA;Lo;0;L;;;;;N;;;;; +0D35;MALAYALAM LETTER VA;Lo;0;L;;;;;N;;;;; +0D36;MALAYALAM LETTER SHA;Lo;0;L;;;;;N;;;;; +0D37;MALAYALAM LETTER SSA;Lo;0;L;;;;;N;;;;; +0D38;MALAYALAM LETTER SA;Lo;0;L;;;;;N;;;;; +0D39;MALAYALAM LETTER HA;Lo;0;L;;;;;N;;;;; +0D3E;MALAYALAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0D3F;MALAYALAM VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +0D40;MALAYALAM VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +0D41;MALAYALAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +0D42;MALAYALAM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +0D43;MALAYALAM VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +0D46;MALAYALAM VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +0D47;MALAYALAM VOWEL SIGN EE;Mc;0;L;;;;;N;;;;; +0D48;MALAYALAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +0D4A;MALAYALAM VOWEL SIGN O;Mc;0;L;0D46 0D3E;;;;N;;;;; +0D4B;MALAYALAM VOWEL SIGN OO;Mc;0;L;0D47 0D3E;;;;N;;;;; +0D4C;MALAYALAM VOWEL SIGN AU;Mc;0;L;0D46 0D57;;;;N;;;;; +0D4D;MALAYALAM SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0D57;MALAYALAM AU LENGTH MARK;Mc;0;L;;;;;N;;;;; +0D60;MALAYALAM LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0D61;MALAYALAM LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0D66;MALAYALAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0D67;MALAYALAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0D68;MALAYALAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0D69;MALAYALAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0D6A;MALAYALAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0D6B;MALAYALAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0D6C;MALAYALAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0D6D;MALAYALAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0D6E;MALAYALAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0D6F;MALAYALAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0D82;SINHALA SIGN ANUSVARAYA;Mc;0;L;;;;;N;;;;; +0D83;SINHALA SIGN VISARGAYA;Mc;0;L;;;;;N;;;;; +0D85;SINHALA LETTER AYANNA;Lo;0;L;;;;;N;;;;; +0D86;SINHALA LETTER AAYANNA;Lo;0;L;;;;;N;;;;; +0D87;SINHALA LETTER AEYANNA;Lo;0;L;;;;;N;;;;; +0D88;SINHALA LETTER AEEYANNA;Lo;0;L;;;;;N;;;;; +0D89;SINHALA LETTER IYANNA;Lo;0;L;;;;;N;;;;; +0D8A;SINHALA LETTER IIYANNA;Lo;0;L;;;;;N;;;;; +0D8B;SINHALA LETTER UYANNA;Lo;0;L;;;;;N;;;;; +0D8C;SINHALA LETTER UUYANNA;Lo;0;L;;;;;N;;;;; +0D8D;SINHALA LETTER IRUYANNA;Lo;0;L;;;;;N;;;;; +0D8E;SINHALA LETTER IRUUYANNA;Lo;0;L;;;;;N;;;;; +0D8F;SINHALA LETTER ILUYANNA;Lo;0;L;;;;;N;;;;; +0D90;SINHALA LETTER ILUUYANNA;Lo;0;L;;;;;N;;;;; +0D91;SINHALA LETTER EYANNA;Lo;0;L;;;;;N;;;;; +0D92;SINHALA LETTER EEYANNA;Lo;0;L;;;;;N;;;;; +0D93;SINHALA LETTER AIYANNA;Lo;0;L;;;;;N;;;;; +0D94;SINHALA LETTER OYANNA;Lo;0;L;;;;;N;;;;; +0D95;SINHALA LETTER OOYANNA;Lo;0;L;;;;;N;;;;; +0D96;SINHALA LETTER AUYANNA;Lo;0;L;;;;;N;;;;; +0D9A;SINHALA LETTER ALPAPRAANA KAYANNA;Lo;0;L;;;;;N;;;;; +0D9B;SINHALA LETTER MAHAAPRAANA KAYANNA;Lo;0;L;;;;;N;;;;; +0D9C;SINHALA LETTER ALPAPRAANA GAYANNA;Lo;0;L;;;;;N;;;;; +0D9D;SINHALA LETTER MAHAAPRAANA GAYANNA;Lo;0;L;;;;;N;;;;; +0D9E;SINHALA LETTER KANTAJA NAASIKYAYA;Lo;0;L;;;;;N;;;;; +0D9F;SINHALA LETTER SANYAKA GAYANNA;Lo;0;L;;;;;N;;;;; +0DA0;SINHALA LETTER ALPAPRAANA CAYANNA;Lo;0;L;;;;;N;;;;; +0DA1;SINHALA LETTER MAHAAPRAANA CAYANNA;Lo;0;L;;;;;N;;;;; +0DA2;SINHALA LETTER ALPAPRAANA JAYANNA;Lo;0;L;;;;;N;;;;; +0DA3;SINHALA LETTER MAHAAPRAANA JAYANNA;Lo;0;L;;;;;N;;;;; +0DA4;SINHALA LETTER TAALUJA NAASIKYAYA;Lo;0;L;;;;;N;;;;; +0DA5;SINHALA LETTER TAALUJA SANYOOGA NAAKSIKYAYA;Lo;0;L;;;;;N;;;;; +0DA6;SINHALA LETTER SANYAKA JAYANNA;Lo;0;L;;;;;N;;;;; +0DA7;SINHALA LETTER ALPAPRAANA TTAYANNA;Lo;0;L;;;;;N;;;;; +0DA8;SINHALA LETTER MAHAAPRAANA TTAYANNA;Lo;0;L;;;;;N;;;;; +0DA9;SINHALA LETTER ALPAPRAANA DDAYANNA;Lo;0;L;;;;;N;;;;; +0DAA;SINHALA LETTER MAHAAPRAANA DDAYANNA;Lo;0;L;;;;;N;;;;; +0DAB;SINHALA LETTER MUURDHAJA NAYANNA;Lo;0;L;;;;;N;;;;; +0DAC;SINHALA LETTER SANYAKA DDAYANNA;Lo;0;L;;;;;N;;;;; +0DAD;SINHALA LETTER ALPAPRAANA TAYANNA;Lo;0;L;;;;;N;;;;; +0DAE;SINHALA LETTER MAHAAPRAANA TAYANNA;Lo;0;L;;;;;N;;;;; +0DAF;SINHALA LETTER ALPAPRAANA DAYANNA;Lo;0;L;;;;;N;;;;; +0DB0;SINHALA LETTER MAHAAPRAANA DAYANNA;Lo;0;L;;;;;N;;;;; +0DB1;SINHALA LETTER DANTAJA NAYANNA;Lo;0;L;;;;;N;;;;; +0DB3;SINHALA LETTER SANYAKA DAYANNA;Lo;0;L;;;;;N;;;;; +0DB4;SINHALA LETTER ALPAPRAANA PAYANNA;Lo;0;L;;;;;N;;;;; +0DB5;SINHALA LETTER MAHAAPRAANA PAYANNA;Lo;0;L;;;;;N;;;;; +0DB6;SINHALA LETTER ALPAPRAANA BAYANNA;Lo;0;L;;;;;N;;;;; +0DB7;SINHALA LETTER MAHAAPRAANA BAYANNA;Lo;0;L;;;;;N;;;;; +0DB8;SINHALA LETTER MAYANNA;Lo;0;L;;;;;N;;;;; +0DB9;SINHALA LETTER AMBA BAYANNA;Lo;0;L;;;;;N;;;;; +0DBA;SINHALA LETTER YAYANNA;Lo;0;L;;;;;N;;;;; +0DBB;SINHALA LETTER RAYANNA;Lo;0;L;;;;;N;;;;; +0DBD;SINHALA LETTER DANTAJA LAYANNA;Lo;0;L;;;;;N;;;;; +0DC0;SINHALA LETTER VAYANNA;Lo;0;L;;;;;N;;;;; +0DC1;SINHALA LETTER TAALUJA SAYANNA;Lo;0;L;;;;;N;;;;; +0DC2;SINHALA LETTER MUURDHAJA SAYANNA;Lo;0;L;;;;;N;;;;; +0DC3;SINHALA LETTER DANTAJA SAYANNA;Lo;0;L;;;;;N;;;;; +0DC4;SINHALA LETTER HAYANNA;Lo;0;L;;;;;N;;;;; +0DC5;SINHALA LETTER MUURDHAJA LAYANNA;Lo;0;L;;;;;N;;;;; +0DC6;SINHALA LETTER FAYANNA;Lo;0;L;;;;;N;;;;; +0DCA;SINHALA SIGN AL-LAKUNA;Mn;9;NSM;;;;;N;;;;; +0DCF;SINHALA VOWEL SIGN AELA-PILLA;Mc;0;L;;;;;N;;;;; +0DD0;SINHALA VOWEL SIGN KETTI AEDA-PILLA;Mc;0;L;;;;;N;;;;; +0DD1;SINHALA VOWEL SIGN DIGA AEDA-PILLA;Mc;0;L;;;;;N;;;;; +0DD2;SINHALA VOWEL SIGN KETTI IS-PILLA;Mn;0;NSM;;;;;N;;;;; +0DD3;SINHALA VOWEL SIGN DIGA IS-PILLA;Mn;0;NSM;;;;;N;;;;; +0DD4;SINHALA VOWEL SIGN KETTI PAA-PILLA;Mn;0;NSM;;;;;N;;;;; +0DD6;SINHALA VOWEL SIGN DIGA PAA-PILLA;Mn;0;NSM;;;;;N;;;;; +0DD8;SINHALA VOWEL SIGN GAETTA-PILLA;Mc;0;L;;;;;N;;;;; +0DD9;SINHALA VOWEL SIGN KOMBUVA;Mc;0;L;;;;;N;;;;; +0DDA;SINHALA VOWEL SIGN DIGA KOMBUVA;Mc;0;L;0DD9 0DCA;;;;N;;;;; +0DDB;SINHALA VOWEL SIGN KOMBU DEKA;Mc;0;L;;;;;N;;;;; +0DDC;SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA;Mc;0;L;0DD9 0DCF;;;;N;;;;; +0DDD;SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA;Mc;0;L;0DDC 0DCA;;;;N;;;;; +0DDE;SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA;Mc;0;L;0DD9 0DDF;;;;N;;;;; +0DDF;SINHALA VOWEL SIGN GAYANUKITTA;Mc;0;L;;;;;N;;;;; +0DF2;SINHALA VOWEL SIGN DIGA GAETTA-PILLA;Mc;0;L;;;;;N;;;;; +0DF3;SINHALA VOWEL SIGN DIGA GAYANUKITTA;Mc;0;L;;;;;N;;;;; +0DF4;SINHALA PUNCTUATION KUNDDALIYA;Po;0;L;;;;;N;;;;; +0E01;THAI CHARACTER KO KAI;Lo;0;L;;;;;N;THAI LETTER KO KAI;;;; +0E02;THAI CHARACTER KHO KHAI;Lo;0;L;;;;;N;THAI LETTER KHO KHAI;;;; +0E03;THAI CHARACTER KHO KHUAT;Lo;0;L;;;;;N;THAI LETTER KHO KHUAT;;;; +0E04;THAI CHARACTER KHO KHWAI;Lo;0;L;;;;;N;THAI LETTER KHO KHWAI;;;; +0E05;THAI CHARACTER KHO KHON;Lo;0;L;;;;;N;THAI LETTER KHO KHON;;;; +0E06;THAI CHARACTER KHO RAKHANG;Lo;0;L;;;;;N;THAI LETTER KHO RAKHANG;;;; +0E07;THAI CHARACTER NGO NGU;Lo;0;L;;;;;N;THAI LETTER NGO NGU;;;; +0E08;THAI CHARACTER CHO CHAN;Lo;0;L;;;;;N;THAI LETTER CHO CHAN;;;; +0E09;THAI CHARACTER CHO CHING;Lo;0;L;;;;;N;THAI LETTER CHO CHING;;;; +0E0A;THAI CHARACTER CHO CHANG;Lo;0;L;;;;;N;THAI LETTER CHO CHANG;;;; +0E0B;THAI CHARACTER SO SO;Lo;0;L;;;;;N;THAI LETTER SO SO;;;; +0E0C;THAI CHARACTER CHO CHOE;Lo;0;L;;;;;N;THAI LETTER CHO CHOE;;;; +0E0D;THAI CHARACTER YO YING;Lo;0;L;;;;;N;THAI LETTER YO YING;;;; +0E0E;THAI CHARACTER DO CHADA;Lo;0;L;;;;;N;THAI LETTER DO CHADA;;;; +0E0F;THAI CHARACTER TO PATAK;Lo;0;L;;;;;N;THAI LETTER TO PATAK;;;; +0E10;THAI CHARACTER THO THAN;Lo;0;L;;;;;N;THAI LETTER THO THAN;;;; +0E11;THAI CHARACTER THO NANGMONTHO;Lo;0;L;;;;;N;THAI LETTER THO NANGMONTHO;;;; +0E12;THAI CHARACTER THO PHUTHAO;Lo;0;L;;;;;N;THAI LETTER THO PHUTHAO;;;; +0E13;THAI CHARACTER NO NEN;Lo;0;L;;;;;N;THAI LETTER NO NEN;;;; +0E14;THAI CHARACTER DO DEK;Lo;0;L;;;;;N;THAI LETTER DO DEK;;;; +0E15;THAI CHARACTER TO TAO;Lo;0;L;;;;;N;THAI LETTER TO TAO;;;; +0E16;THAI CHARACTER THO THUNG;Lo;0;L;;;;;N;THAI LETTER THO THUNG;;;; +0E17;THAI CHARACTER THO THAHAN;Lo;0;L;;;;;N;THAI LETTER THO THAHAN;;;; +0E18;THAI CHARACTER THO THONG;Lo;0;L;;;;;N;THAI LETTER THO THONG;;;; +0E19;THAI CHARACTER NO NU;Lo;0;L;;;;;N;THAI LETTER NO NU;;;; +0E1A;THAI CHARACTER BO BAIMAI;Lo;0;L;;;;;N;THAI LETTER BO BAIMAI;;;; +0E1B;THAI CHARACTER PO PLA;Lo;0;L;;;;;N;THAI LETTER PO PLA;;;; +0E1C;THAI CHARACTER PHO PHUNG;Lo;0;L;;;;;N;THAI LETTER PHO PHUNG;;;; +0E1D;THAI CHARACTER FO FA;Lo;0;L;;;;;N;THAI LETTER FO FA;;;; +0E1E;THAI CHARACTER PHO PHAN;Lo;0;L;;;;;N;THAI LETTER PHO PHAN;;;; +0E1F;THAI CHARACTER FO FAN;Lo;0;L;;;;;N;THAI LETTER FO FAN;;;; +0E20;THAI CHARACTER PHO SAMPHAO;Lo;0;L;;;;;N;THAI LETTER PHO SAMPHAO;;;; +0E21;THAI CHARACTER MO MA;Lo;0;L;;;;;N;THAI LETTER MO MA;;;; +0E22;THAI CHARACTER YO YAK;Lo;0;L;;;;;N;THAI LETTER YO YAK;;;; +0E23;THAI CHARACTER RO RUA;Lo;0;L;;;;;N;THAI LETTER RO RUA;;;; +0E24;THAI CHARACTER RU;Lo;0;L;;;;;N;THAI LETTER RU;;;; +0E25;THAI CHARACTER LO LING;Lo;0;L;;;;;N;THAI LETTER LO LING;;;; +0E26;THAI CHARACTER LU;Lo;0;L;;;;;N;THAI LETTER LU;;;; +0E27;THAI CHARACTER WO WAEN;Lo;0;L;;;;;N;THAI LETTER WO WAEN;;;; +0E28;THAI CHARACTER SO SALA;Lo;0;L;;;;;N;THAI LETTER SO SALA;;;; +0E29;THAI CHARACTER SO RUSI;Lo;0;L;;;;;N;THAI LETTER SO RUSI;;;; +0E2A;THAI CHARACTER SO SUA;Lo;0;L;;;;;N;THAI LETTER SO SUA;;;; +0E2B;THAI CHARACTER HO HIP;Lo;0;L;;;;;N;THAI LETTER HO HIP;;;; +0E2C;THAI CHARACTER LO CHULA;Lo;0;L;;;;;N;THAI LETTER LO CHULA;;;; +0E2D;THAI CHARACTER O ANG;Lo;0;L;;;;;N;THAI LETTER O ANG;;;; +0E2E;THAI CHARACTER HO NOKHUK;Lo;0;L;;;;;N;THAI LETTER HO NOK HUK;;;; +0E2F;THAI CHARACTER PAIYANNOI;Lo;0;L;;;;;N;THAI PAI YAN NOI;paiyan noi;;; +0E30;THAI CHARACTER SARA A;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA A;;;; +0E31;THAI CHARACTER MAI HAN-AKAT;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI HAN-AKAT;;;; +0E32;THAI CHARACTER SARA AA;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AA;;;; +0E33;THAI CHARACTER SARA AM;Lo;0;L; 0E4D 0E32;;;;N;THAI VOWEL SIGN SARA AM;;;; +0E34;THAI CHARACTER SARA I;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA I;;;; +0E35;THAI CHARACTER SARA II;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA II;;;; +0E36;THAI CHARACTER SARA UE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UE;;;; +0E37;THAI CHARACTER SARA UEE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UEE;sara uue;;; +0E38;THAI CHARACTER SARA U;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA U;;;; +0E39;THAI CHARACTER SARA UU;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA UU;;;; +0E3A;THAI CHARACTER PHINTHU;Mn;9;NSM;;;;;N;THAI VOWEL SIGN PHINTHU;;;; +0E3F;THAI CURRENCY SYMBOL BAHT;Sc;0;ET;;;;;N;THAI BAHT SIGN;;;; +0E40;THAI CHARACTER SARA E;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA E;;;; +0E41;THAI CHARACTER SARA AE;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AE;;;; +0E42;THAI CHARACTER SARA O;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA O;;;; +0E43;THAI CHARACTER SARA AI MAIMUAN;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MUAN;sara ai mai muan;;; +0E44;THAI CHARACTER SARA AI MAIMALAI;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MALAI;sara ai mai malai;;; +0E45;THAI CHARACTER LAKKHANGYAO;Lo;0;L;;;;;N;THAI LAK KHANG YAO;lakkhang yao;;; +0E46;THAI CHARACTER MAIYAMOK;Lm;0;L;;;;;N;THAI MAI YAMOK;mai yamok;;; +0E47;THAI CHARACTER MAITAIKHU;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI TAI KHU;mai taikhu;;; +0E48;THAI CHARACTER MAI EK;Mn;107;NSM;;;;;N;THAI TONE MAI EK;;;; +0E49;THAI CHARACTER MAI THO;Mn;107;NSM;;;;;N;THAI TONE MAI THO;;;; +0E4A;THAI CHARACTER MAI TRI;Mn;107;NSM;;;;;N;THAI TONE MAI TRI;;;; +0E4B;THAI CHARACTER MAI CHATTAWA;Mn;107;NSM;;;;;N;THAI TONE MAI CHATTAWA;;;; +0E4C;THAI CHARACTER THANTHAKHAT;Mn;0;NSM;;;;;N;THAI THANTHAKHAT;;;; +0E4D;THAI CHARACTER NIKHAHIT;Mn;0;NSM;;;;;N;THAI NIKKHAHIT;nikkhahit;;; +0E4E;THAI CHARACTER YAMAKKAN;Mn;0;NSM;;;;;N;THAI YAMAKKAN;;;; +0E4F;THAI CHARACTER FONGMAN;Po;0;L;;;;;N;THAI FONGMAN;;;; +0E50;THAI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0E51;THAI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0E52;THAI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0E53;THAI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0E54;THAI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0E55;THAI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0E56;THAI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0E57;THAI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0E58;THAI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0E59;THAI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0E5A;THAI CHARACTER ANGKHANKHU;Po;0;L;;;;;N;THAI ANGKHANKHU;;;; +0E5B;THAI CHARACTER KHOMUT;Po;0;L;;;;;N;THAI KHOMUT;;;; +0E81;LAO LETTER KO;Lo;0;L;;;;;N;;;;; +0E82;LAO LETTER KHO SUNG;Lo;0;L;;;;;N;;;;; +0E84;LAO LETTER KHO TAM;Lo;0;L;;;;;N;;;;; +0E87;LAO LETTER NGO;Lo;0;L;;;;;N;;;;; +0E88;LAO LETTER CO;Lo;0;L;;;;;N;;;;; +0E8A;LAO LETTER SO TAM;Lo;0;L;;;;;N;;;;; +0E8D;LAO LETTER NYO;Lo;0;L;;;;;N;;;;; +0E94;LAO LETTER DO;Lo;0;L;;;;;N;;;;; +0E95;LAO LETTER TO;Lo;0;L;;;;;N;;;;; +0E96;LAO LETTER THO SUNG;Lo;0;L;;;;;N;;;;; +0E97;LAO LETTER THO TAM;Lo;0;L;;;;;N;;;;; +0E99;LAO LETTER NO;Lo;0;L;;;;;N;;;;; +0E9A;LAO LETTER BO;Lo;0;L;;;;;N;;;;; +0E9B;LAO LETTER PO;Lo;0;L;;;;;N;;;;; +0E9C;LAO LETTER PHO SUNG;Lo;0;L;;;;;N;;;;; +0E9D;LAO LETTER FO TAM;Lo;0;L;;;;;N;;;;; +0E9E;LAO LETTER PHO TAM;Lo;0;L;;;;;N;;;;; +0E9F;LAO LETTER FO SUNG;Lo;0;L;;;;;N;;;;; +0EA1;LAO LETTER MO;Lo;0;L;;;;;N;;;;; +0EA2;LAO LETTER YO;Lo;0;L;;;;;N;;;;; +0EA3;LAO LETTER LO LING;Lo;0;L;;;;;N;;;;; +0EA5;LAO LETTER LO LOOT;Lo;0;L;;;;;N;;;;; +0EA7;LAO LETTER WO;Lo;0;L;;;;;N;;;;; +0EAA;LAO LETTER SO SUNG;Lo;0;L;;;;;N;;;;; +0EAB;LAO LETTER HO SUNG;Lo;0;L;;;;;N;;;;; +0EAD;LAO LETTER O;Lo;0;L;;;;;N;;;;; +0EAE;LAO LETTER HO TAM;Lo;0;L;;;;;N;;;;; +0EAF;LAO ELLIPSIS;Lo;0;L;;;;;N;;;;; +0EB0;LAO VOWEL SIGN A;Lo;0;L;;;;;N;;;;; +0EB1;LAO VOWEL SIGN MAI KAN;Mn;0;NSM;;;;;N;;;;; +0EB2;LAO VOWEL SIGN AA;Lo;0;L;;;;;N;;;;; +0EB3;LAO VOWEL SIGN AM;Lo;0;L; 0ECD 0EB2;;;;N;;;;; +0EB4;LAO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +0EB5;LAO VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +0EB6;LAO VOWEL SIGN Y;Mn;0;NSM;;;;;N;;;;; +0EB7;LAO VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;; +0EB8;LAO VOWEL SIGN U;Mn;118;NSM;;;;;N;;;;; +0EB9;LAO VOWEL SIGN UU;Mn;118;NSM;;;;;N;;;;; +0EBB;LAO VOWEL SIGN MAI KON;Mn;0;NSM;;;;;N;;;;; +0EBC;LAO SEMIVOWEL SIGN LO;Mn;0;NSM;;;;;N;;;;; +0EBD;LAO SEMIVOWEL SIGN NYO;Lo;0;L;;;;;N;;;;; +0EC0;LAO VOWEL SIGN E;Lo;0;L;;;;;N;;;;; +0EC1;LAO VOWEL SIGN EI;Lo;0;L;;;;;N;;;;; +0EC2;LAO VOWEL SIGN O;Lo;0;L;;;;;N;;;;; +0EC3;LAO VOWEL SIGN AY;Lo;0;L;;;;;N;;;;; +0EC4;LAO VOWEL SIGN AI;Lo;0;L;;;;;N;;;;; +0EC6;LAO KO LA;Lm;0;L;;;;;N;;;;; +0EC8;LAO TONE MAI EK;Mn;122;NSM;;;;;N;;;;; +0EC9;LAO TONE MAI THO;Mn;122;NSM;;;;;N;;;;; +0ECA;LAO TONE MAI TI;Mn;122;NSM;;;;;N;;;;; +0ECB;LAO TONE MAI CATAWA;Mn;122;NSM;;;;;N;;;;; +0ECC;LAO CANCELLATION MARK;Mn;0;NSM;;;;;N;;;;; +0ECD;LAO NIGGAHITA;Mn;0;NSM;;;;;N;;;;; +0ED0;LAO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0ED1;LAO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0ED2;LAO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0ED3;LAO DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0ED4;LAO DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0ED5;LAO DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0ED6;LAO DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0ED7;LAO DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0ED8;LAO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0ED9;LAO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0EDC;LAO HO NO;Lo;0;L; 0EAB 0E99;;;;N;;;;; +0EDD;LAO HO MO;Lo;0;L; 0EAB 0EA1;;;;N;;;;; +0F00;TIBETAN SYLLABLE OM;Lo;0;L;;;;;N;;;;; +0F01;TIBETAN MARK GTER YIG MGO TRUNCATED A;So;0;L;;;;;N;;ter yik go a thung;;; +0F02;TIBETAN MARK GTER YIG MGO -UM RNAM BCAD MA;So;0;L;;;;;N;;ter yik go wum nam chey ma;;; +0F03;TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA;So;0;L;;;;;N;;ter yik go wum ter tsek ma;;; +0F04;TIBETAN MARK INITIAL YIG MGO MDUN MA;Po;0;L;;;;;N;TIBETAN SINGLE ORNAMENT;yik go dun ma;;; +0F05;TIBETAN MARK CLOSING YIG MGO SGAB MA;Po;0;L;;;;;N;;yik go kab ma;;; +0F06;TIBETAN MARK CARET YIG MGO PHUR SHAD MA;Po;0;L;;;;;N;;yik go pur shey ma;;; +0F07;TIBETAN MARK YIG MGO TSHEG SHAD MA;Po;0;L;;;;;N;;yik go tsek shey ma;;; +0F08;TIBETAN MARK SBRUL SHAD;Po;0;L;;;;;N;TIBETAN RGYANSHAD;drul shey;;; +0F09;TIBETAN MARK BSKUR YIG MGO;Po;0;L;;;;;N;;kur yik go;;; +0F0A;TIBETAN MARK BKA- SHOG YIG MGO;Po;0;L;;;;;N;;ka sho yik go;;; +0F0B;TIBETAN MARK INTERSYLLABIC TSHEG;Po;0;L;;;;;N;TIBETAN TSEG;tsek;;; +0F0C;TIBETAN MARK DELIMITER TSHEG BSTAR;Po;0;L; 0F0B;;;;N;;tsek tar;;; +0F0D;TIBETAN MARK SHAD;Po;0;L;;;;;N;TIBETAN SHAD;shey;;; +0F0E;TIBETAN MARK NYIS SHAD;Po;0;L;;;;;N;TIBETAN DOUBLE SHAD;nyi shey;;; +0F0F;TIBETAN MARK TSHEG SHAD;Po;0;L;;;;;N;;tsek shey;;; +0F10;TIBETAN MARK NYIS TSHEG SHAD;Po;0;L;;;;;N;;nyi tsek shey;;; +0F11;TIBETAN MARK RIN CHEN SPUNGS SHAD;Po;0;L;;;;;N;TIBETAN RINCHANPHUNGSHAD;rinchen pung shey;;; +0F12;TIBETAN MARK RGYA GRAM SHAD;Po;0;L;;;;;N;;gya tram shey;;; +0F13;TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN;So;0;L;;;;;N;;dzu ta me long chen;;; +0F14;TIBETAN MARK GTER TSHEG;So;0;L;;;;;N;TIBETAN COMMA;ter tsek;;; +0F15;TIBETAN LOGOTYPE SIGN CHAD RTAGS;So;0;L;;;;;N;;che ta;;; +0F16;TIBETAN LOGOTYPE SIGN LHAG RTAGS;So;0;L;;;;;N;;hlak ta;;; +0F17;TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS;So;0;L;;;;;N;;trachen char ta;;; +0F18;TIBETAN ASTROLOGICAL SIGN -KHYUD PA;Mn;220;NSM;;;;;N;;kyu pa;;; +0F19;TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS;Mn;220;NSM;;;;;N;;dong tsu;;; +0F1A;TIBETAN SIGN RDEL DKAR GCIG;So;0;L;;;;;N;;deka chig;;; +0F1B;TIBETAN SIGN RDEL DKAR GNYIS;So;0;L;;;;;N;;deka nyi;;; +0F1C;TIBETAN SIGN RDEL DKAR GSUM;So;0;L;;;;;N;;deka sum;;; +0F1D;TIBETAN SIGN RDEL NAG GCIG;So;0;L;;;;;N;;dena chig;;; +0F1E;TIBETAN SIGN RDEL NAG GNYIS;So;0;L;;;;;N;;dena nyi;;; +0F1F;TIBETAN SIGN RDEL DKAR RDEL NAG;So;0;L;;;;;N;;deka dena;;; +0F20;TIBETAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0F21;TIBETAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0F22;TIBETAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0F23;TIBETAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0F24;TIBETAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0F25;TIBETAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0F26;TIBETAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0F27;TIBETAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0F28;TIBETAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0F29;TIBETAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0F2A;TIBETAN DIGIT HALF ONE;No;0;L;;;;1/2;N;;;;; +0F2B;TIBETAN DIGIT HALF TWO;No;0;L;;;;3/2;N;;;;; +0F2C;TIBETAN DIGIT HALF THREE;No;0;L;;;;5/2;N;;;;; +0F2D;TIBETAN DIGIT HALF FOUR;No;0;L;;;;7/2;N;;;;; +0F2E;TIBETAN DIGIT HALF FIVE;No;0;L;;;;9/2;N;;;;; +0F2F;TIBETAN DIGIT HALF SIX;No;0;L;;;;11/2;N;;;;; +0F30;TIBETAN DIGIT HALF SEVEN;No;0;L;;;;13/2;N;;;;; +0F31;TIBETAN DIGIT HALF EIGHT;No;0;L;;;;15/2;N;;;;; +0F32;TIBETAN DIGIT HALF NINE;No;0;L;;;;17/2;N;;;;; +0F33;TIBETAN DIGIT HALF ZERO;No;0;L;;;;-1/2;N;;;;; +0F34;TIBETAN MARK BSDUS RTAGS;So;0;L;;;;;N;;du ta;;; +0F35;TIBETAN MARK NGAS BZUNG NYI ZLA;Mn;220;NSM;;;;;N;TIBETAN HONORIFIC UNDER RING;nge zung nyi da;;; +0F36;TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN;So;0;L;;;;;N;;dzu ta shi mig chen;;; +0F37;TIBETAN MARK NGAS BZUNG SGOR RTAGS;Mn;220;NSM;;;;;N;TIBETAN UNDER RING;nge zung gor ta;;; +0F38;TIBETAN MARK CHE MGO;So;0;L;;;;;N;;che go;;; +0F39;TIBETAN MARK TSA -PHRU;Mn;216;NSM;;;;;N;TIBETAN LENITION MARK;tsa tru;;; +0F3A;TIBETAN MARK GUG RTAGS GYON;Ps;0;ON;;;;;N;;gug ta yun;;; +0F3B;TIBETAN MARK GUG RTAGS GYAS;Pe;0;ON;;;;;N;;gug ta ye;;; +0F3C;TIBETAN MARK ANG KHANG GYON;Ps;0;ON;;;;;N;TIBETAN LEFT BRACE;ang kang yun;;; +0F3D;TIBETAN MARK ANG KHANG GYAS;Pe;0;ON;;;;;N;TIBETAN RIGHT BRACE;ang kang ye;;; +0F3E;TIBETAN SIGN YAR TSHES;Mc;0;L;;;;;N;;yar tse;;; +0F3F;TIBETAN SIGN MAR TSHES;Mc;0;L;;;;;N;;mar tse;;; +0F40;TIBETAN LETTER KA;Lo;0;L;;;;;N;;;;; +0F41;TIBETAN LETTER KHA;Lo;0;L;;;;;N;;;;; +0F42;TIBETAN LETTER GA;Lo;0;L;;;;;N;;;;; +0F43;TIBETAN LETTER GHA;Lo;0;L;0F42 0FB7;;;;N;;;;; +0F44;TIBETAN LETTER NGA;Lo;0;L;;;;;N;;;;; +0F45;TIBETAN LETTER CA;Lo;0;L;;;;;N;;;;; +0F46;TIBETAN LETTER CHA;Lo;0;L;;;;;N;;;;; +0F47;TIBETAN LETTER JA;Lo;0;L;;;;;N;;;;; +0F49;TIBETAN LETTER NYA;Lo;0;L;;;;;N;;;;; +0F4A;TIBETAN LETTER TTA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED TA;;;; +0F4B;TIBETAN LETTER TTHA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED THA;;;; +0F4C;TIBETAN LETTER DDA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED DA;;;; +0F4D;TIBETAN LETTER DDHA;Lo;0;L;0F4C 0FB7;;;;N;;;;; +0F4E;TIBETAN LETTER NNA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED NA;;;; +0F4F;TIBETAN LETTER TA;Lo;0;L;;;;;N;;;;; +0F50;TIBETAN LETTER THA;Lo;0;L;;;;;N;;;;; +0F51;TIBETAN LETTER DA;Lo;0;L;;;;;N;;;;; +0F52;TIBETAN LETTER DHA;Lo;0;L;0F51 0FB7;;;;N;;;;; +0F53;TIBETAN LETTER NA;Lo;0;L;;;;;N;;;;; +0F54;TIBETAN LETTER PA;Lo;0;L;;;;;N;;;;; +0F55;TIBETAN LETTER PHA;Lo;0;L;;;;;N;;;;; +0F56;TIBETAN LETTER BA;Lo;0;L;;;;;N;;;;; +0F57;TIBETAN LETTER BHA;Lo;0;L;0F56 0FB7;;;;N;;;;; +0F58;TIBETAN LETTER MA;Lo;0;L;;;;;N;;;;; +0F59;TIBETAN LETTER TSA;Lo;0;L;;;;;N;;;;; +0F5A;TIBETAN LETTER TSHA;Lo;0;L;;;;;N;;;;; +0F5B;TIBETAN LETTER DZA;Lo;0;L;;;;;N;;;;; +0F5C;TIBETAN LETTER DZHA;Lo;0;L;0F5B 0FB7;;;;N;;;;; +0F5D;TIBETAN LETTER WA;Lo;0;L;;;;;N;;;;; +0F5E;TIBETAN LETTER ZHA;Lo;0;L;;;;;N;;;;; +0F5F;TIBETAN LETTER ZA;Lo;0;L;;;;;N;;;;; +0F60;TIBETAN LETTER -A;Lo;0;L;;;;;N;TIBETAN LETTER AA;;;; +0F61;TIBETAN LETTER YA;Lo;0;L;;;;;N;;;;; +0F62;TIBETAN LETTER RA;Lo;0;L;;;;;N;;*;;; +0F63;TIBETAN LETTER LA;Lo;0;L;;;;;N;;;;; +0F64;TIBETAN LETTER SHA;Lo;0;L;;;;;N;;;;; +0F65;TIBETAN LETTER SSA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED SHA;;;; +0F66;TIBETAN LETTER SA;Lo;0;L;;;;;N;;;;; +0F67;TIBETAN LETTER HA;Lo;0;L;;;;;N;;;;; +0F68;TIBETAN LETTER A;Lo;0;L;;;;;N;;;;; +0F69;TIBETAN LETTER KSSA;Lo;0;L;0F40 0FB5;;;;N;;;;; +0F6A;TIBETAN LETTER FIXED-FORM RA;Lo;0;L;;;;;N;;*;;; +0F71;TIBETAN VOWEL SIGN AA;Mn;129;NSM;;;;;N;;;;; +0F72;TIBETAN VOWEL SIGN I;Mn;130;NSM;;;;;N;;;;; +0F73;TIBETAN VOWEL SIGN II;Mn;0;NSM;0F71 0F72;;;;N;;;;; +0F74;TIBETAN VOWEL SIGN U;Mn;132;NSM;;;;;N;;;;; +0F75;TIBETAN VOWEL SIGN UU;Mn;0;NSM;0F71 0F74;;;;N;;;;; +0F76;TIBETAN VOWEL SIGN VOCALIC R;Mn;0;NSM;0FB2 0F80;;;;N;;;;; +0F77;TIBETAN VOWEL SIGN VOCALIC RR;Mn;0;NSM; 0FB2 0F81;;;;N;;;;; +0F78;TIBETAN VOWEL SIGN VOCALIC L;Mn;0;NSM;0FB3 0F80;;;;N;;;;; +0F79;TIBETAN VOWEL SIGN VOCALIC LL;Mn;0;NSM; 0FB3 0F81;;;;N;;;;; +0F7A;TIBETAN VOWEL SIGN E;Mn;130;NSM;;;;;N;;;;; +0F7B;TIBETAN VOWEL SIGN EE;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AI;;;; +0F7C;TIBETAN VOWEL SIGN O;Mn;130;NSM;;;;;N;;;;; +0F7D;TIBETAN VOWEL SIGN OO;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AU;;;; +0F7E;TIBETAN SIGN RJES SU NGA RO;Mn;0;NSM;;;;;N;TIBETAN ANUSVARA;je su nga ro;;; +0F7F;TIBETAN SIGN RNAM BCAD;Mc;0;L;;;;;N;TIBETAN VISARGA;nam chey;;; +0F80;TIBETAN VOWEL SIGN REVERSED I;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN SHORT I;;;; +0F81;TIBETAN VOWEL SIGN REVERSED II;Mn;0;NSM;0F71 0F80;;;;N;;;;; +0F82;TIBETAN SIGN NYI ZLA NAA DA;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU WITH ORNAMENT;nyi da na da;;; +0F83;TIBETAN SIGN SNA LDAN;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU;nan de;;; +0F84;TIBETAN MARK HALANTA;Mn;9;NSM;;;;;N;TIBETAN VIRAMA;;;; +0F85;TIBETAN MARK PALUTA;Po;0;L;;;;;N;TIBETAN CHUCHENYIGE;;;; +0F86;TIBETAN SIGN LCI RTAGS;Mn;230;NSM;;;;;N;;ji ta;;; +0F87;TIBETAN SIGN YANG RTAGS;Mn;230;NSM;;;;;N;;yang ta;;; +0F88;TIBETAN SIGN LCE TSA CAN;Lo;0;L;;;;;N;;che tsa chen;;; +0F89;TIBETAN SIGN MCHU CAN;Lo;0;L;;;;;N;;chu chen;;; +0F8A;TIBETAN SIGN GRU CAN RGYINGS;Lo;0;L;;;;;N;;tru chen ging;;; +0F8B;TIBETAN SIGN GRU MED RGYINGS;Lo;0;L;;;;;N;;tru me ging;;; +0F90;TIBETAN SUBJOINED LETTER KA;Mn;0;NSM;;;;;N;;;;; +0F91;TIBETAN SUBJOINED LETTER KHA;Mn;0;NSM;;;;;N;;;;; +0F92;TIBETAN SUBJOINED LETTER GA;Mn;0;NSM;;;;;N;;;;; +0F93;TIBETAN SUBJOINED LETTER GHA;Mn;0;NSM;0F92 0FB7;;;;N;;;;; +0F94;TIBETAN SUBJOINED LETTER NGA;Mn;0;NSM;;;;;N;;;;; +0F95;TIBETAN SUBJOINED LETTER CA;Mn;0;NSM;;;;;N;;;;; +0F96;TIBETAN SUBJOINED LETTER CHA;Mn;0;NSM;;;;;N;;;;; +0F97;TIBETAN SUBJOINED LETTER JA;Mn;0;NSM;;;;;N;;;;; +0F99;TIBETAN SUBJOINED LETTER NYA;Mn;0;NSM;;;;;N;;;;; +0F9A;TIBETAN SUBJOINED LETTER TTA;Mn;0;NSM;;;;;N;;;;; +0F9B;TIBETAN SUBJOINED LETTER TTHA;Mn;0;NSM;;;;;N;;;;; +0F9C;TIBETAN SUBJOINED LETTER DDA;Mn;0;NSM;;;;;N;;;;; +0F9D;TIBETAN SUBJOINED LETTER DDHA;Mn;0;NSM;0F9C 0FB7;;;;N;;;;; +0F9E;TIBETAN SUBJOINED LETTER NNA;Mn;0;NSM;;;;;N;;;;; +0F9F;TIBETAN SUBJOINED LETTER TA;Mn;0;NSM;;;;;N;;;;; +0FA0;TIBETAN SUBJOINED LETTER THA;Mn;0;NSM;;;;;N;;;;; +0FA1;TIBETAN SUBJOINED LETTER DA;Mn;0;NSM;;;;;N;;;;; +0FA2;TIBETAN SUBJOINED LETTER DHA;Mn;0;NSM;0FA1 0FB7;;;;N;;;;; +0FA3;TIBETAN SUBJOINED LETTER NA;Mn;0;NSM;;;;;N;;;;; +0FA4;TIBETAN SUBJOINED LETTER PA;Mn;0;NSM;;;;;N;;;;; +0FA5;TIBETAN SUBJOINED LETTER PHA;Mn;0;NSM;;;;;N;;;;; +0FA6;TIBETAN SUBJOINED LETTER BA;Mn;0;NSM;;;;;N;;;;; +0FA7;TIBETAN SUBJOINED LETTER BHA;Mn;0;NSM;0FA6 0FB7;;;;N;;;;; +0FA8;TIBETAN SUBJOINED LETTER MA;Mn;0;NSM;;;;;N;;;;; +0FA9;TIBETAN SUBJOINED LETTER TSA;Mn;0;NSM;;;;;N;;;;; +0FAA;TIBETAN SUBJOINED LETTER TSHA;Mn;0;NSM;;;;;N;;;;; +0FAB;TIBETAN SUBJOINED LETTER DZA;Mn;0;NSM;;;;;N;;;;; +0FAC;TIBETAN SUBJOINED LETTER DZHA;Mn;0;NSM;0FAB 0FB7;;;;N;;;;; +0FAD;TIBETAN SUBJOINED LETTER WA;Mn;0;NSM;;;;;N;;*;;; +0FAE;TIBETAN SUBJOINED LETTER ZHA;Mn;0;NSM;;;;;N;;;;; +0FAF;TIBETAN SUBJOINED LETTER ZA;Mn;0;NSM;;;;;N;;;;; +0FB0;TIBETAN SUBJOINED LETTER -A;Mn;0;NSM;;;;;N;;;;; +0FB1;TIBETAN SUBJOINED LETTER YA;Mn;0;NSM;;;;;N;;*;;; +0FB2;TIBETAN SUBJOINED LETTER RA;Mn;0;NSM;;;;;N;;*;;; +0FB3;TIBETAN SUBJOINED LETTER LA;Mn;0;NSM;;;;;N;;;;; +0FB4;TIBETAN SUBJOINED LETTER SHA;Mn;0;NSM;;;;;N;;;;; +0FB5;TIBETAN SUBJOINED LETTER SSA;Mn;0;NSM;;;;;N;;;;; +0FB6;TIBETAN SUBJOINED LETTER SA;Mn;0;NSM;;;;;N;;;;; +0FB7;TIBETAN SUBJOINED LETTER HA;Mn;0;NSM;;;;;N;;;;; +0FB8;TIBETAN SUBJOINED LETTER A;Mn;0;NSM;;;;;N;;;;; +0FB9;TIBETAN SUBJOINED LETTER KSSA;Mn;0;NSM;0F90 0FB5;;;;N;;;;; +0FBA;TIBETAN SUBJOINED LETTER FIXED-FORM WA;Mn;0;NSM;;;;;N;;*;;; +0FBB;TIBETAN SUBJOINED LETTER FIXED-FORM YA;Mn;0;NSM;;;;;N;;*;;; +0FBC;TIBETAN SUBJOINED LETTER FIXED-FORM RA;Mn;0;NSM;;;;;N;;*;;; +0FBE;TIBETAN KU RU KHA;So;0;L;;;;;N;;kuruka;;; +0FBF;TIBETAN KU RU KHA BZHI MIG CAN;So;0;L;;;;;N;;kuruka shi mik chen;;; +0FC0;TIBETAN CANTILLATION SIGN HEAVY BEAT;So;0;L;;;;;N;;;;; +0FC1;TIBETAN CANTILLATION SIGN LIGHT BEAT;So;0;L;;;;;N;;;;; +0FC2;TIBETAN CANTILLATION SIGN CANG TE-U;So;0;L;;;;;N;;chang tyu;;; +0FC3;TIBETAN CANTILLATION SIGN SBUB -CHAL;So;0;L;;;;;N;;bub chey;;; +0FC4;TIBETAN SYMBOL DRIL BU;So;0;L;;;;;N;;drilbu;;; +0FC5;TIBETAN SYMBOL RDO RJE;So;0;L;;;;;N;;dorje;;; +0FC6;TIBETAN SYMBOL PADMA GDAN;Mn;220;NSM;;;;;N;;pema den;;; +0FC7;TIBETAN SYMBOL RDO RJE RGYA GRAM;So;0;L;;;;;N;;dorje gya dram;;; +0FC8;TIBETAN SYMBOL PHUR PA;So;0;L;;;;;N;;phurba;;; +0FC9;TIBETAN SYMBOL NOR BU;So;0;L;;;;;N;;norbu;;; +0FCA;TIBETAN SYMBOL NOR BU NYIS -KHYIL;So;0;L;;;;;N;;norbu nyi khyi;;; +0FCB;TIBETAN SYMBOL NOR BU GSUM -KHYIL;So;0;L;;;;;N;;norbu sum khyi;;; +0FCC;TIBETAN SYMBOL NOR BU BZHI -KHYIL;So;0;L;;;;;N;;norbu shi khyi;;; +0FCF;TIBETAN SIGN RDEL NAG GSUM;So;0;L;;;;;N;;dena sum;;; +1000;MYANMAR LETTER KA;Lo;0;L;;;;;N;;;;; +1001;MYANMAR LETTER KHA;Lo;0;L;;;;;N;;;;; +1002;MYANMAR LETTER GA;Lo;0;L;;;;;N;;;;; +1003;MYANMAR LETTER GHA;Lo;0;L;;;;;N;;;;; +1004;MYANMAR LETTER NGA;Lo;0;L;;;;;N;;;;; +1005;MYANMAR LETTER CA;Lo;0;L;;;;;N;;;;; +1006;MYANMAR LETTER CHA;Lo;0;L;;;;;N;;;;; +1007;MYANMAR LETTER JA;Lo;0;L;;;;;N;;;;; +1008;MYANMAR LETTER JHA;Lo;0;L;;;;;N;;;;; +1009;MYANMAR LETTER NYA;Lo;0;L;;;;;N;;;;; +100A;MYANMAR LETTER NNYA;Lo;0;L;;;;;N;;;;; +100B;MYANMAR LETTER TTA;Lo;0;L;;;;;N;;;;; +100C;MYANMAR LETTER TTHA;Lo;0;L;;;;;N;;;;; +100D;MYANMAR LETTER DDA;Lo;0;L;;;;;N;;;;; +100E;MYANMAR LETTER DDHA;Lo;0;L;;;;;N;;;;; +100F;MYANMAR LETTER NNA;Lo;0;L;;;;;N;;;;; +1010;MYANMAR LETTER TA;Lo;0;L;;;;;N;;;;; +1011;MYANMAR LETTER THA;Lo;0;L;;;;;N;;;;; +1012;MYANMAR LETTER DA;Lo;0;L;;;;;N;;;;; +1013;MYANMAR LETTER DHA;Lo;0;L;;;;;N;;;;; +1014;MYANMAR LETTER NA;Lo;0;L;;;;;N;;;;; +1015;MYANMAR LETTER PA;Lo;0;L;;;;;N;;;;; +1016;MYANMAR LETTER PHA;Lo;0;L;;;;;N;;;;; +1017;MYANMAR LETTER BA;Lo;0;L;;;;;N;;;;; +1018;MYANMAR LETTER BHA;Lo;0;L;;;;;N;;;;; +1019;MYANMAR LETTER MA;Lo;0;L;;;;;N;;;;; +101A;MYANMAR LETTER YA;Lo;0;L;;;;;N;;;;; +101B;MYANMAR LETTER RA;Lo;0;L;;;;;N;;;;; +101C;MYANMAR LETTER LA;Lo;0;L;;;;;N;;;;; +101D;MYANMAR LETTER WA;Lo;0;L;;;;;N;;;;; +101E;MYANMAR LETTER SA;Lo;0;L;;;;;N;;;;; +101F;MYANMAR LETTER HA;Lo;0;L;;;;;N;;;;; +1020;MYANMAR LETTER LLA;Lo;0;L;;;;;N;;;;; +1021;MYANMAR LETTER A;Lo;0;L;;;;;N;;;;; +1023;MYANMAR LETTER I;Lo;0;L;;;;;N;;;;; +1024;MYANMAR LETTER II;Lo;0;L;;;;;N;;;;; +1025;MYANMAR LETTER U;Lo;0;L;;;;;N;;;;; +1026;MYANMAR LETTER UU;Lo;0;L;1025 102E;;;;N;;;;; +1027;MYANMAR LETTER E;Lo;0;L;;;;;N;;;;; +1029;MYANMAR LETTER O;Lo;0;L;;;;;N;;;;; +102A;MYANMAR LETTER AU;Lo;0;L;;;;;N;;;;; +102C;MYANMAR VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +102D;MYANMAR VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +102E;MYANMAR VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +102F;MYANMAR VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1030;MYANMAR VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +1031;MYANMAR VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +1032;MYANMAR VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +1036;MYANMAR SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +1037;MYANMAR SIGN DOT BELOW;Mn;7;NSM;;;;;N;;;;; +1038;MYANMAR SIGN VISARGA;Mc;0;L;;;;;N;;;;; +1039;MYANMAR SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +1040;MYANMAR DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1041;MYANMAR DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1042;MYANMAR DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1043;MYANMAR DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1044;MYANMAR DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1045;MYANMAR DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1046;MYANMAR DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1047;MYANMAR DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1048;MYANMAR DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1049;MYANMAR DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +104A;MYANMAR SIGN LITTLE SECTION;Po;0;L;;;;;N;;;;; +104B;MYANMAR SIGN SECTION;Po;0;L;;;;;N;;;;; +104C;MYANMAR SYMBOL LOCATIVE;Po;0;L;;;;;N;;;;; +104D;MYANMAR SYMBOL COMPLETED;Po;0;L;;;;;N;;;;; +104E;MYANMAR SYMBOL AFOREMENTIONED;Po;0;L;;;;;N;;;;; +104F;MYANMAR SYMBOL GENITIVE;Po;0;L;;;;;N;;;;; +1050;MYANMAR LETTER SHA;Lo;0;L;;;;;N;;;;; +1051;MYANMAR LETTER SSA;Lo;0;L;;;;;N;;;;; +1052;MYANMAR LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +1053;MYANMAR LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +1054;MYANMAR LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +1055;MYANMAR LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +1056;MYANMAR VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;; +1057;MYANMAR VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;; +1058;MYANMAR VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +1059;MYANMAR VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +10A0;GEORGIAN CAPITAL LETTER AN;Lu;0;L;;;;;N;;Khutsuri;;; +10A1;GEORGIAN CAPITAL LETTER BAN;Lu;0;L;;;;;N;;Khutsuri;;; +10A2;GEORGIAN CAPITAL LETTER GAN;Lu;0;L;;;;;N;;Khutsuri;;; +10A3;GEORGIAN CAPITAL LETTER DON;Lu;0;L;;;;;N;;Khutsuri;;; +10A4;GEORGIAN CAPITAL LETTER EN;Lu;0;L;;;;;N;;Khutsuri;;; +10A5;GEORGIAN CAPITAL LETTER VIN;Lu;0;L;;;;;N;;Khutsuri;;; +10A6;GEORGIAN CAPITAL LETTER ZEN;Lu;0;L;;;;;N;;Khutsuri;;; +10A7;GEORGIAN CAPITAL LETTER TAN;Lu;0;L;;;;;N;;Khutsuri;;; +10A8;GEORGIAN CAPITAL LETTER IN;Lu;0;L;;;;;N;;Khutsuri;;; +10A9;GEORGIAN CAPITAL LETTER KAN;Lu;0;L;;;;;N;;Khutsuri;;; +10AA;GEORGIAN CAPITAL LETTER LAS;Lu;0;L;;;;;N;;Khutsuri;;; +10AB;GEORGIAN CAPITAL LETTER MAN;Lu;0;L;;;;;N;;Khutsuri;;; +10AC;GEORGIAN CAPITAL LETTER NAR;Lu;0;L;;;;;N;;Khutsuri;;; +10AD;GEORGIAN CAPITAL LETTER ON;Lu;0;L;;;;;N;;Khutsuri;;; +10AE;GEORGIAN CAPITAL LETTER PAR;Lu;0;L;;;;;N;;Khutsuri;;; +10AF;GEORGIAN CAPITAL LETTER ZHAR;Lu;0;L;;;;;N;;Khutsuri;;; +10B0;GEORGIAN CAPITAL LETTER RAE;Lu;0;L;;;;;N;;Khutsuri;;; +10B1;GEORGIAN CAPITAL LETTER SAN;Lu;0;L;;;;;N;;Khutsuri;;; +10B2;GEORGIAN CAPITAL LETTER TAR;Lu;0;L;;;;;N;;Khutsuri;;; +10B3;GEORGIAN CAPITAL LETTER UN;Lu;0;L;;;;;N;;Khutsuri;;; +10B4;GEORGIAN CAPITAL LETTER PHAR;Lu;0;L;;;;;N;;Khutsuri;;; +10B5;GEORGIAN CAPITAL LETTER KHAR;Lu;0;L;;;;;N;;Khutsuri;;; +10B6;GEORGIAN CAPITAL LETTER GHAN;Lu;0;L;;;;;N;;Khutsuri;;; +10B7;GEORGIAN CAPITAL LETTER QAR;Lu;0;L;;;;;N;;Khutsuri;;; +10B8;GEORGIAN CAPITAL LETTER SHIN;Lu;0;L;;;;;N;;Khutsuri;;; +10B9;GEORGIAN CAPITAL LETTER CHIN;Lu;0;L;;;;;N;;Khutsuri;;; +10BA;GEORGIAN CAPITAL LETTER CAN;Lu;0;L;;;;;N;;Khutsuri;;; +10BB;GEORGIAN CAPITAL LETTER JIL;Lu;0;L;;;;;N;;Khutsuri;;; +10BC;GEORGIAN CAPITAL LETTER CIL;Lu;0;L;;;;;N;;Khutsuri;;; +10BD;GEORGIAN CAPITAL LETTER CHAR;Lu;0;L;;;;;N;;Khutsuri;;; +10BE;GEORGIAN CAPITAL LETTER XAN;Lu;0;L;;;;;N;;Khutsuri;;; +10BF;GEORGIAN CAPITAL LETTER JHAN;Lu;0;L;;;;;N;;Khutsuri;;; +10C0;GEORGIAN CAPITAL LETTER HAE;Lu;0;L;;;;;N;;Khutsuri;;; +10C1;GEORGIAN CAPITAL LETTER HE;Lu;0;L;;;;;N;;Khutsuri;;; +10C2;GEORGIAN CAPITAL LETTER HIE;Lu;0;L;;;;;N;;Khutsuri;;; +10C3;GEORGIAN CAPITAL LETTER WE;Lu;0;L;;;;;N;;Khutsuri;;; +10C4;GEORGIAN CAPITAL LETTER HAR;Lu;0;L;;;;;N;;Khutsuri;;; +10C5;GEORGIAN CAPITAL LETTER HOE;Lu;0;L;;;;;N;;Khutsuri;;; +10D0;GEORGIAN LETTER AN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER AN;;;; +10D1;GEORGIAN LETTER BAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER BAN;;;; +10D2;GEORGIAN LETTER GAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER GAN;;;; +10D3;GEORGIAN LETTER DON;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER DON;;;; +10D4;GEORGIAN LETTER EN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER EN;;;; +10D5;GEORGIAN LETTER VIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER VIN;;;; +10D6;GEORGIAN LETTER ZEN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ZEN;;;; +10D7;GEORGIAN LETTER TAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER TAN;;;; +10D8;GEORGIAN LETTER IN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER IN;;;; +10D9;GEORGIAN LETTER KAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER KAN;;;; +10DA;GEORGIAN LETTER LAS;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER LAS;;;; +10DB;GEORGIAN LETTER MAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER MAN;;;; +10DC;GEORGIAN LETTER NAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER NAR;;;; +10DD;GEORGIAN LETTER ON;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ON;;;; +10DE;GEORGIAN LETTER PAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER PAR;;;; +10DF;GEORGIAN LETTER ZHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ZHAR;;;; +10E0;GEORGIAN LETTER RAE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER RAE;;;; +10E1;GEORGIAN LETTER SAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER SAN;;;; +10E2;GEORGIAN LETTER TAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER TAR;;;; +10E3;GEORGIAN LETTER UN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER UN;;;; +10E4;GEORGIAN LETTER PHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER PHAR;;;; +10E5;GEORGIAN LETTER KHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER KHAR;;;; +10E6;GEORGIAN LETTER GHAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER GHAN;;;; +10E7;GEORGIAN LETTER QAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER QAR;;;; +10E8;GEORGIAN LETTER SHIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER SHIN;;;; +10E9;GEORGIAN LETTER CHIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CHIN;;;; +10EA;GEORGIAN LETTER CAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CAN;;;; +10EB;GEORGIAN LETTER JIL;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER JIL;;;; +10EC;GEORGIAN LETTER CIL;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CIL;;;; +10ED;GEORGIAN LETTER CHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CHAR;;;; +10EE;GEORGIAN LETTER XAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER XAN;;;; +10EF;GEORGIAN LETTER JHAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER JHAN;;;; +10F0;GEORGIAN LETTER HAE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HAE;;;; +10F1;GEORGIAN LETTER HE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HE;;;; +10F2;GEORGIAN LETTER HIE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HIE;;;; +10F3;GEORGIAN LETTER WE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER WE;;;; +10F4;GEORGIAN LETTER HAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HAR;;;; +10F5;GEORGIAN LETTER HOE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HOE;;;; +10F6;GEORGIAN LETTER FI;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER FI;;;; +10F7;GEORGIAN LETTER YN;Lo;0;L;;;;;N;;;;; +10F8;GEORGIAN LETTER ELIFI;Lo;0;L;;;;;N;;;;; +10FB;GEORGIAN PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;; +1100;HANGUL CHOSEONG KIYEOK;Lo;0;L;;;;;N;;g *;;; +1101;HANGUL CHOSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;gg *;;; +1102;HANGUL CHOSEONG NIEUN;Lo;0;L;;;;;N;;n *;;; +1103;HANGUL CHOSEONG TIKEUT;Lo;0;L;;;;;N;;d *;;; +1104;HANGUL CHOSEONG SSANGTIKEUT;Lo;0;L;;;;;N;;dd *;;; +1105;HANGUL CHOSEONG RIEUL;Lo;0;L;;;;;N;;r *;;; +1106;HANGUL CHOSEONG MIEUM;Lo;0;L;;;;;N;;m *;;; +1107;HANGUL CHOSEONG PIEUP;Lo;0;L;;;;;N;;b *;;; +1108;HANGUL CHOSEONG SSANGPIEUP;Lo;0;L;;;;;N;;bb *;;; +1109;HANGUL CHOSEONG SIOS;Lo;0;L;;;;;N;;s *;;; +110A;HANGUL CHOSEONG SSANGSIOS;Lo;0;L;;;;;N;;ss *;;; +110B;HANGUL CHOSEONG IEUNG;Lo;0;L;;;;;N;;;;; +110C;HANGUL CHOSEONG CIEUC;Lo;0;L;;;;;N;;j *;;; +110D;HANGUL CHOSEONG SSANGCIEUC;Lo;0;L;;;;;N;;jj *;;; +110E;HANGUL CHOSEONG CHIEUCH;Lo;0;L;;;;;N;;c *;;; +110F;HANGUL CHOSEONG KHIEUKH;Lo;0;L;;;;;N;;k *;;; +1110;HANGUL CHOSEONG THIEUTH;Lo;0;L;;;;;N;;t *;;; +1111;HANGUL CHOSEONG PHIEUPH;Lo;0;L;;;;;N;;p *;;; +1112;HANGUL CHOSEONG HIEUH;Lo;0;L;;;;;N;;h *;;; +1113;HANGUL CHOSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;; +1114;HANGUL CHOSEONG SSANGNIEUN;Lo;0;L;;;;;N;;;;; +1115;HANGUL CHOSEONG NIEUN-TIKEUT;Lo;0;L;;;;;N;;;;; +1116;HANGUL CHOSEONG NIEUN-PIEUP;Lo;0;L;;;;;N;;;;; +1117;HANGUL CHOSEONG TIKEUT-KIYEOK;Lo;0;L;;;;;N;;;;; +1118;HANGUL CHOSEONG RIEUL-NIEUN;Lo;0;L;;;;;N;;;;; +1119;HANGUL CHOSEONG SSANGRIEUL;Lo;0;L;;;;;N;;;;; +111A;HANGUL CHOSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;;;; +111B;HANGUL CHOSEONG KAPYEOUNRIEUL;Lo;0;L;;;;;N;;;;; +111C;HANGUL CHOSEONG MIEUM-PIEUP;Lo;0;L;;;;;N;;;;; +111D;HANGUL CHOSEONG KAPYEOUNMIEUM;Lo;0;L;;;;;N;;;;; +111E;HANGUL CHOSEONG PIEUP-KIYEOK;Lo;0;L;;;;;N;;;;; +111F;HANGUL CHOSEONG PIEUP-NIEUN;Lo;0;L;;;;;N;;;;; +1120;HANGUL CHOSEONG PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;; +1121;HANGUL CHOSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;;;; +1122;HANGUL CHOSEONG PIEUP-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +1123;HANGUL CHOSEONG PIEUP-SIOS-TIKEUT;Lo;0;L;;;;;N;;;;; +1124;HANGUL CHOSEONG PIEUP-SIOS-PIEUP;Lo;0;L;;;;;N;;;;; +1125;HANGUL CHOSEONG PIEUP-SSANGSIOS;Lo;0;L;;;;;N;;;;; +1126;HANGUL CHOSEONG PIEUP-SIOS-CIEUC;Lo;0;L;;;;;N;;;;; +1127;HANGUL CHOSEONG PIEUP-CIEUC;Lo;0;L;;;;;N;;;;; +1128;HANGUL CHOSEONG PIEUP-CHIEUCH;Lo;0;L;;;;;N;;;;; +1129;HANGUL CHOSEONG PIEUP-THIEUTH;Lo;0;L;;;;;N;;;;; +112A;HANGUL CHOSEONG PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;; +112B;HANGUL CHOSEONG KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; +112C;HANGUL CHOSEONG KAPYEOUNSSANGPIEUP;Lo;0;L;;;;;N;;;;; +112D;HANGUL CHOSEONG SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +112E;HANGUL CHOSEONG SIOS-NIEUN;Lo;0;L;;;;;N;;;;; +112F;HANGUL CHOSEONG SIOS-TIKEUT;Lo;0;L;;;;;N;;;;; +1130;HANGUL CHOSEONG SIOS-RIEUL;Lo;0;L;;;;;N;;;;; +1131;HANGUL CHOSEONG SIOS-MIEUM;Lo;0;L;;;;;N;;;;; +1132;HANGUL CHOSEONG SIOS-PIEUP;Lo;0;L;;;;;N;;;;; +1133;HANGUL CHOSEONG SIOS-PIEUP-KIYEOK;Lo;0;L;;;;;N;;;;; +1134;HANGUL CHOSEONG SIOS-SSANGSIOS;Lo;0;L;;;;;N;;;;; +1135;HANGUL CHOSEONG SIOS-IEUNG;Lo;0;L;;;;;N;;;;; +1136;HANGUL CHOSEONG SIOS-CIEUC;Lo;0;L;;;;;N;;;;; +1137;HANGUL CHOSEONG SIOS-CHIEUCH;Lo;0;L;;;;;N;;;;; +1138;HANGUL CHOSEONG SIOS-KHIEUKH;Lo;0;L;;;;;N;;;;; +1139;HANGUL CHOSEONG SIOS-THIEUTH;Lo;0;L;;;;;N;;;;; +113A;HANGUL CHOSEONG SIOS-PHIEUPH;Lo;0;L;;;;;N;;;;; +113B;HANGUL CHOSEONG SIOS-HIEUH;Lo;0;L;;;;;N;;;;; +113C;HANGUL CHOSEONG CHITUEUMSIOS;Lo;0;L;;;;;N;;;;; +113D;HANGUL CHOSEONG CHITUEUMSSANGSIOS;Lo;0;L;;;;;N;;;;; +113E;HANGUL CHOSEONG CEONGCHIEUMSIOS;Lo;0;L;;;;;N;;;;; +113F;HANGUL CHOSEONG CEONGCHIEUMSSANGSIOS;Lo;0;L;;;;;N;;;;; +1140;HANGUL CHOSEONG PANSIOS;Lo;0;L;;;;;N;;;;; +1141;HANGUL CHOSEONG IEUNG-KIYEOK;Lo;0;L;;;;;N;;;;; +1142;HANGUL CHOSEONG IEUNG-TIKEUT;Lo;0;L;;;;;N;;;;; +1143;HANGUL CHOSEONG IEUNG-MIEUM;Lo;0;L;;;;;N;;;;; +1144;HANGUL CHOSEONG IEUNG-PIEUP;Lo;0;L;;;;;N;;;;; +1145;HANGUL CHOSEONG IEUNG-SIOS;Lo;0;L;;;;;N;;;;; +1146;HANGUL CHOSEONG IEUNG-PANSIOS;Lo;0;L;;;;;N;;;;; +1147;HANGUL CHOSEONG SSANGIEUNG;Lo;0;L;;;;;N;;;;; +1148;HANGUL CHOSEONG IEUNG-CIEUC;Lo;0;L;;;;;N;;;;; +1149;HANGUL CHOSEONG IEUNG-CHIEUCH;Lo;0;L;;;;;N;;;;; +114A;HANGUL CHOSEONG IEUNG-THIEUTH;Lo;0;L;;;;;N;;;;; +114B;HANGUL CHOSEONG IEUNG-PHIEUPH;Lo;0;L;;;;;N;;;;; +114C;HANGUL CHOSEONG YESIEUNG;Lo;0;L;;;;;N;;;;; +114D;HANGUL CHOSEONG CIEUC-IEUNG;Lo;0;L;;;;;N;;;;; +114E;HANGUL CHOSEONG CHITUEUMCIEUC;Lo;0;L;;;;;N;;;;; +114F;HANGUL CHOSEONG CHITUEUMSSANGCIEUC;Lo;0;L;;;;;N;;;;; +1150;HANGUL CHOSEONG CEONGCHIEUMCIEUC;Lo;0;L;;;;;N;;;;; +1151;HANGUL CHOSEONG CEONGCHIEUMSSANGCIEUC;Lo;0;L;;;;;N;;;;; +1152;HANGUL CHOSEONG CHIEUCH-KHIEUKH;Lo;0;L;;;;;N;;;;; +1153;HANGUL CHOSEONG CHIEUCH-HIEUH;Lo;0;L;;;;;N;;;;; +1154;HANGUL CHOSEONG CHITUEUMCHIEUCH;Lo;0;L;;;;;N;;;;; +1155;HANGUL CHOSEONG CEONGCHIEUMCHIEUCH;Lo;0;L;;;;;N;;;;; +1156;HANGUL CHOSEONG PHIEUPH-PIEUP;Lo;0;L;;;;;N;;;;; +1157;HANGUL CHOSEONG KAPYEOUNPHIEUPH;Lo;0;L;;;;;N;;;;; +1158;HANGUL CHOSEONG SSANGHIEUH;Lo;0;L;;;;;N;;;;; +1159;HANGUL CHOSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;; +115F;HANGUL CHOSEONG FILLER;Lo;0;L;;;;;N;;;;; +1160;HANGUL JUNGSEONG FILLER;Lo;0;L;;;;;N;;;;; +1161;HANGUL JUNGSEONG A;Lo;0;L;;;;;N;;;;; +1162;HANGUL JUNGSEONG AE;Lo;0;L;;;;;N;;;;; +1163;HANGUL JUNGSEONG YA;Lo;0;L;;;;;N;;;;; +1164;HANGUL JUNGSEONG YAE;Lo;0;L;;;;;N;;;;; +1165;HANGUL JUNGSEONG EO;Lo;0;L;;;;;N;;;;; +1166;HANGUL JUNGSEONG E;Lo;0;L;;;;;N;;;;; +1167;HANGUL JUNGSEONG YEO;Lo;0;L;;;;;N;;;;; +1168;HANGUL JUNGSEONG YE;Lo;0;L;;;;;N;;;;; +1169;HANGUL JUNGSEONG O;Lo;0;L;;;;;N;;;;; +116A;HANGUL JUNGSEONG WA;Lo;0;L;;;;;N;;;;; +116B;HANGUL JUNGSEONG WAE;Lo;0;L;;;;;N;;;;; +116C;HANGUL JUNGSEONG OE;Lo;0;L;;;;;N;;;;; +116D;HANGUL JUNGSEONG YO;Lo;0;L;;;;;N;;;;; +116E;HANGUL JUNGSEONG U;Lo;0;L;;;;;N;;;;; +116F;HANGUL JUNGSEONG WEO;Lo;0;L;;;;;N;;;;; +1170;HANGUL JUNGSEONG WE;Lo;0;L;;;;;N;;;;; +1171;HANGUL JUNGSEONG WI;Lo;0;L;;;;;N;;;;; +1172;HANGUL JUNGSEONG YU;Lo;0;L;;;;;N;;;;; +1173;HANGUL JUNGSEONG EU;Lo;0;L;;;;;N;;;;; +1174;HANGUL JUNGSEONG YI;Lo;0;L;;;;;N;;;;; +1175;HANGUL JUNGSEONG I;Lo;0;L;;;;;N;;;;; +1176;HANGUL JUNGSEONG A-O;Lo;0;L;;;;;N;;;;; +1177;HANGUL JUNGSEONG A-U;Lo;0;L;;;;;N;;;;; +1178;HANGUL JUNGSEONG YA-O;Lo;0;L;;;;;N;;;;; +1179;HANGUL JUNGSEONG YA-YO;Lo;0;L;;;;;N;;;;; +117A;HANGUL JUNGSEONG EO-O;Lo;0;L;;;;;N;;;;; +117B;HANGUL JUNGSEONG EO-U;Lo;0;L;;;;;N;;;;; +117C;HANGUL JUNGSEONG EO-EU;Lo;0;L;;;;;N;;;;; +117D;HANGUL JUNGSEONG YEO-O;Lo;0;L;;;;;N;;;;; +117E;HANGUL JUNGSEONG YEO-U;Lo;0;L;;;;;N;;;;; +117F;HANGUL JUNGSEONG O-EO;Lo;0;L;;;;;N;;;;; +1180;HANGUL JUNGSEONG O-E;Lo;0;L;;;;;N;;;;; +1181;HANGUL JUNGSEONG O-YE;Lo;0;L;;;;;N;;;;; +1182;HANGUL JUNGSEONG O-O;Lo;0;L;;;;;N;;;;; +1183;HANGUL JUNGSEONG O-U;Lo;0;L;;;;;N;;;;; +1184;HANGUL JUNGSEONG YO-YA;Lo;0;L;;;;;N;;;;; +1185;HANGUL JUNGSEONG YO-YAE;Lo;0;L;;;;;N;;;;; +1186;HANGUL JUNGSEONG YO-YEO;Lo;0;L;;;;;N;;;;; +1187;HANGUL JUNGSEONG YO-O;Lo;0;L;;;;;N;;;;; +1188;HANGUL JUNGSEONG YO-I;Lo;0;L;;;;;N;;;;; +1189;HANGUL JUNGSEONG U-A;Lo;0;L;;;;;N;;;;; +118A;HANGUL JUNGSEONG U-AE;Lo;0;L;;;;;N;;;;; +118B;HANGUL JUNGSEONG U-EO-EU;Lo;0;L;;;;;N;;;;; +118C;HANGUL JUNGSEONG U-YE;Lo;0;L;;;;;N;;;;; +118D;HANGUL JUNGSEONG U-U;Lo;0;L;;;;;N;;;;; +118E;HANGUL JUNGSEONG YU-A;Lo;0;L;;;;;N;;;;; +118F;HANGUL JUNGSEONG YU-EO;Lo;0;L;;;;;N;;;;; +1190;HANGUL JUNGSEONG YU-E;Lo;0;L;;;;;N;;;;; +1191;HANGUL JUNGSEONG YU-YEO;Lo;0;L;;;;;N;;;;; +1192;HANGUL JUNGSEONG YU-YE;Lo;0;L;;;;;N;;;;; +1193;HANGUL JUNGSEONG YU-U;Lo;0;L;;;;;N;;;;; +1194;HANGUL JUNGSEONG YU-I;Lo;0;L;;;;;N;;;;; +1195;HANGUL JUNGSEONG EU-U;Lo;0;L;;;;;N;;;;; +1196;HANGUL JUNGSEONG EU-EU;Lo;0;L;;;;;N;;;;; +1197;HANGUL JUNGSEONG YI-U;Lo;0;L;;;;;N;;;;; +1198;HANGUL JUNGSEONG I-A;Lo;0;L;;;;;N;;;;; +1199;HANGUL JUNGSEONG I-YA;Lo;0;L;;;;;N;;;;; +119A;HANGUL JUNGSEONG I-O;Lo;0;L;;;;;N;;;;; +119B;HANGUL JUNGSEONG I-U;Lo;0;L;;;;;N;;;;; +119C;HANGUL JUNGSEONG I-EU;Lo;0;L;;;;;N;;;;; +119D;HANGUL JUNGSEONG I-ARAEA;Lo;0;L;;;;;N;;;;; +119E;HANGUL JUNGSEONG ARAEA;Lo;0;L;;;;;N;;;;; +119F;HANGUL JUNGSEONG ARAEA-EO;Lo;0;L;;;;;N;;;;; +11A0;HANGUL JUNGSEONG ARAEA-U;Lo;0;L;;;;;N;;;;; +11A1;HANGUL JUNGSEONG ARAEA-I;Lo;0;L;;;;;N;;;;; +11A2;HANGUL JUNGSEONG SSANGARAEA;Lo;0;L;;;;;N;;;;; +11A8;HANGUL JONGSEONG KIYEOK;Lo;0;L;;;;;N;;g *;;; +11A9;HANGUL JONGSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;gg *;;; +11AA;HANGUL JONGSEONG KIYEOK-SIOS;Lo;0;L;;;;;N;;gs *;;; +11AB;HANGUL JONGSEONG NIEUN;Lo;0;L;;;;;N;;n *;;; +11AC;HANGUL JONGSEONG NIEUN-CIEUC;Lo;0;L;;;;;N;;nj *;;; +11AD;HANGUL JONGSEONG NIEUN-HIEUH;Lo;0;L;;;;;N;;nh *;;; +11AE;HANGUL JONGSEONG TIKEUT;Lo;0;L;;;;;N;;d *;;; +11AF;HANGUL JONGSEONG RIEUL;Lo;0;L;;;;;N;;l *;;; +11B0;HANGUL JONGSEONG RIEUL-KIYEOK;Lo;0;L;;;;;N;;lg *;;; +11B1;HANGUL JONGSEONG RIEUL-MIEUM;Lo;0;L;;;;;N;;lm *;;; +11B2;HANGUL JONGSEONG RIEUL-PIEUP;Lo;0;L;;;;;N;;lb *;;; +11B3;HANGUL JONGSEONG RIEUL-SIOS;Lo;0;L;;;;;N;;ls *;;; +11B4;HANGUL JONGSEONG RIEUL-THIEUTH;Lo;0;L;;;;;N;;lt *;;; +11B5;HANGUL JONGSEONG RIEUL-PHIEUPH;Lo;0;L;;;;;N;;lp *;;; +11B6;HANGUL JONGSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;lh *;;; +11B7;HANGUL JONGSEONG MIEUM;Lo;0;L;;;;;N;;m *;;; +11B8;HANGUL JONGSEONG PIEUP;Lo;0;L;;;;;N;;b *;;; +11B9;HANGUL JONGSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;bs *;;; +11BA;HANGUL JONGSEONG SIOS;Lo;0;L;;;;;N;;s *;;; +11BB;HANGUL JONGSEONG SSANGSIOS;Lo;0;L;;;;;N;;ss *;;; +11BC;HANGUL JONGSEONG IEUNG;Lo;0;L;;;;;N;;ng *;;; +11BD;HANGUL JONGSEONG CIEUC;Lo;0;L;;;;;N;;j *;;; +11BE;HANGUL JONGSEONG CHIEUCH;Lo;0;L;;;;;N;;c *;;; +11BF;HANGUL JONGSEONG KHIEUKH;Lo;0;L;;;;;N;;k *;;; +11C0;HANGUL JONGSEONG THIEUTH;Lo;0;L;;;;;N;;t *;;; +11C1;HANGUL JONGSEONG PHIEUPH;Lo;0;L;;;;;N;;p *;;; +11C2;HANGUL JONGSEONG HIEUH;Lo;0;L;;;;;N;;h *;;; +11C3;HANGUL JONGSEONG KIYEOK-RIEUL;Lo;0;L;;;;;N;;;;; +11C4;HANGUL JONGSEONG KIYEOK-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +11C5;HANGUL JONGSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;; +11C6;HANGUL JONGSEONG NIEUN-TIKEUT;Lo;0;L;;;;;N;;;;; +11C7;HANGUL JONGSEONG NIEUN-SIOS;Lo;0;L;;;;;N;;;;; +11C8;HANGUL JONGSEONG NIEUN-PANSIOS;Lo;0;L;;;;;N;;;;; +11C9;HANGUL JONGSEONG NIEUN-THIEUTH;Lo;0;L;;;;;N;;;;; +11CA;HANGUL JONGSEONG TIKEUT-KIYEOK;Lo;0;L;;;;;N;;;;; +11CB;HANGUL JONGSEONG TIKEUT-RIEUL;Lo;0;L;;;;;N;;;;; +11CC;HANGUL JONGSEONG RIEUL-KIYEOK-SIOS;Lo;0;L;;;;;N;;;;; +11CD;HANGUL JONGSEONG RIEUL-NIEUN;Lo;0;L;;;;;N;;;;; +11CE;HANGUL JONGSEONG RIEUL-TIKEUT;Lo;0;L;;;;;N;;;;; +11CF;HANGUL JONGSEONG RIEUL-TIKEUT-HIEUH;Lo;0;L;;;;;N;;;;; +11D0;HANGUL JONGSEONG SSANGRIEUL;Lo;0;L;;;;;N;;;;; +11D1;HANGUL JONGSEONG RIEUL-MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;; +11D2;HANGUL JONGSEONG RIEUL-MIEUM-SIOS;Lo;0;L;;;;;N;;;;; +11D3;HANGUL JONGSEONG RIEUL-PIEUP-SIOS;Lo;0;L;;;;;N;;;;; +11D4;HANGUL JONGSEONG RIEUL-PIEUP-HIEUH;Lo;0;L;;;;;N;;;;; +11D5;HANGUL JONGSEONG RIEUL-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; +11D6;HANGUL JONGSEONG RIEUL-SSANGSIOS;Lo;0;L;;;;;N;;;;; +11D7;HANGUL JONGSEONG RIEUL-PANSIOS;Lo;0;L;;;;;N;;;;; +11D8;HANGUL JONGSEONG RIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;; +11D9;HANGUL JONGSEONG RIEUL-YEORINHIEUH;Lo;0;L;;;;;N;;;;; +11DA;HANGUL JONGSEONG MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;; +11DB;HANGUL JONGSEONG MIEUM-RIEUL;Lo;0;L;;;;;N;;;;; +11DC;HANGUL JONGSEONG MIEUM-PIEUP;Lo;0;L;;;;;N;;;;; +11DD;HANGUL JONGSEONG MIEUM-SIOS;Lo;0;L;;;;;N;;;;; +11DE;HANGUL JONGSEONG MIEUM-SSANGSIOS;Lo;0;L;;;;;N;;;;; +11DF;HANGUL JONGSEONG MIEUM-PANSIOS;Lo;0;L;;;;;N;;;;; +11E0;HANGUL JONGSEONG MIEUM-CHIEUCH;Lo;0;L;;;;;N;;;;; +11E1;HANGUL JONGSEONG MIEUM-HIEUH;Lo;0;L;;;;;N;;;;; +11E2;HANGUL JONGSEONG KAPYEOUNMIEUM;Lo;0;L;;;;;N;;;;; +11E3;HANGUL JONGSEONG PIEUP-RIEUL;Lo;0;L;;;;;N;;;;; +11E4;HANGUL JONGSEONG PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;; +11E5;HANGUL JONGSEONG PIEUP-HIEUH;Lo;0;L;;;;;N;;;;; +11E6;HANGUL JONGSEONG KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; +11E7;HANGUL JONGSEONG SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +11E8;HANGUL JONGSEONG SIOS-TIKEUT;Lo;0;L;;;;;N;;;;; +11E9;HANGUL JONGSEONG SIOS-RIEUL;Lo;0;L;;;;;N;;;;; +11EA;HANGUL JONGSEONG SIOS-PIEUP;Lo;0;L;;;;;N;;;;; +11EB;HANGUL JONGSEONG PANSIOS;Lo;0;L;;;;;N;;;;; +11EC;HANGUL JONGSEONG IEUNG-KIYEOK;Lo;0;L;;;;;N;;;;; +11ED;HANGUL JONGSEONG IEUNG-SSANGKIYEOK;Lo;0;L;;;;;N;;;;; +11EE;HANGUL JONGSEONG SSANGIEUNG;Lo;0;L;;;;;N;;;;; +11EF;HANGUL JONGSEONG IEUNG-KHIEUKH;Lo;0;L;;;;;N;;;;; +11F0;HANGUL JONGSEONG YESIEUNG;Lo;0;L;;;;;N;;;;; +11F1;HANGUL JONGSEONG YESIEUNG-SIOS;Lo;0;L;;;;;N;;;;; +11F2;HANGUL JONGSEONG YESIEUNG-PANSIOS;Lo;0;L;;;;;N;;;;; +11F3;HANGUL JONGSEONG PHIEUPH-PIEUP;Lo;0;L;;;;;N;;;;; +11F4;HANGUL JONGSEONG KAPYEOUNPHIEUPH;Lo;0;L;;;;;N;;;;; +11F5;HANGUL JONGSEONG HIEUH-NIEUN;Lo;0;L;;;;;N;;;;; +11F6;HANGUL JONGSEONG HIEUH-RIEUL;Lo;0;L;;;;;N;;;;; +11F7;HANGUL JONGSEONG HIEUH-MIEUM;Lo;0;L;;;;;N;;;;; +11F8;HANGUL JONGSEONG HIEUH-PIEUP;Lo;0;L;;;;;N;;;;; +11F9;HANGUL JONGSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;; +1200;ETHIOPIC SYLLABLE HA;Lo;0;L;;;;;N;;;;; +1201;ETHIOPIC SYLLABLE HU;Lo;0;L;;;;;N;;;;; +1202;ETHIOPIC SYLLABLE HI;Lo;0;L;;;;;N;;;;; +1203;ETHIOPIC SYLLABLE HAA;Lo;0;L;;;;;N;;;;; +1204;ETHIOPIC SYLLABLE HEE;Lo;0;L;;;;;N;;;;; +1205;ETHIOPIC SYLLABLE HE;Lo;0;L;;;;;N;;;;; +1206;ETHIOPIC SYLLABLE HO;Lo;0;L;;;;;N;;;;; +1208;ETHIOPIC SYLLABLE LA;Lo;0;L;;;;;N;;;;; +1209;ETHIOPIC SYLLABLE LU;Lo;0;L;;;;;N;;;;; +120A;ETHIOPIC SYLLABLE LI;Lo;0;L;;;;;N;;;;; +120B;ETHIOPIC SYLLABLE LAA;Lo;0;L;;;;;N;;;;; +120C;ETHIOPIC SYLLABLE LEE;Lo;0;L;;;;;N;;;;; +120D;ETHIOPIC SYLLABLE LE;Lo;0;L;;;;;N;;;;; +120E;ETHIOPIC SYLLABLE LO;Lo;0;L;;;;;N;;;;; +120F;ETHIOPIC SYLLABLE LWA;Lo;0;L;;;;;N;;;;; +1210;ETHIOPIC SYLLABLE HHA;Lo;0;L;;;;;N;;;;; +1211;ETHIOPIC SYLLABLE HHU;Lo;0;L;;;;;N;;;;; +1212;ETHIOPIC SYLLABLE HHI;Lo;0;L;;;;;N;;;;; +1213;ETHIOPIC SYLLABLE HHAA;Lo;0;L;;;;;N;;;;; +1214;ETHIOPIC SYLLABLE HHEE;Lo;0;L;;;;;N;;;;; +1215;ETHIOPIC SYLLABLE HHE;Lo;0;L;;;;;N;;;;; +1216;ETHIOPIC SYLLABLE HHO;Lo;0;L;;;;;N;;;;; +1217;ETHIOPIC SYLLABLE HHWA;Lo;0;L;;;;;N;;;;; +1218;ETHIOPIC SYLLABLE MA;Lo;0;L;;;;;N;;;;; +1219;ETHIOPIC SYLLABLE MU;Lo;0;L;;;;;N;;;;; +121A;ETHIOPIC SYLLABLE MI;Lo;0;L;;;;;N;;;;; +121B;ETHIOPIC SYLLABLE MAA;Lo;0;L;;;;;N;;;;; +121C;ETHIOPIC SYLLABLE MEE;Lo;0;L;;;;;N;;;;; +121D;ETHIOPIC SYLLABLE ME;Lo;0;L;;;;;N;;;;; +121E;ETHIOPIC SYLLABLE MO;Lo;0;L;;;;;N;;;;; +121F;ETHIOPIC SYLLABLE MWA;Lo;0;L;;;;;N;;;;; +1220;ETHIOPIC SYLLABLE SZA;Lo;0;L;;;;;N;;;;; +1221;ETHIOPIC SYLLABLE SZU;Lo;0;L;;;;;N;;;;; +1222;ETHIOPIC SYLLABLE SZI;Lo;0;L;;;;;N;;;;; +1223;ETHIOPIC SYLLABLE SZAA;Lo;0;L;;;;;N;;;;; +1224;ETHIOPIC SYLLABLE SZEE;Lo;0;L;;;;;N;;;;; +1225;ETHIOPIC SYLLABLE SZE;Lo;0;L;;;;;N;;;;; +1226;ETHIOPIC SYLLABLE SZO;Lo;0;L;;;;;N;;;;; +1227;ETHIOPIC SYLLABLE SZWA;Lo;0;L;;;;;N;;;;; +1228;ETHIOPIC SYLLABLE RA;Lo;0;L;;;;;N;;;;; +1229;ETHIOPIC SYLLABLE RU;Lo;0;L;;;;;N;;;;; +122A;ETHIOPIC SYLLABLE RI;Lo;0;L;;;;;N;;;;; +122B;ETHIOPIC SYLLABLE RAA;Lo;0;L;;;;;N;;;;; +122C;ETHIOPIC SYLLABLE REE;Lo;0;L;;;;;N;;;;; +122D;ETHIOPIC SYLLABLE RE;Lo;0;L;;;;;N;;;;; +122E;ETHIOPIC SYLLABLE RO;Lo;0;L;;;;;N;;;;; +122F;ETHIOPIC SYLLABLE RWA;Lo;0;L;;;;;N;;;;; +1230;ETHIOPIC SYLLABLE SA;Lo;0;L;;;;;N;;;;; +1231;ETHIOPIC SYLLABLE SU;Lo;0;L;;;;;N;;;;; +1232;ETHIOPIC SYLLABLE SI;Lo;0;L;;;;;N;;;;; +1233;ETHIOPIC SYLLABLE SAA;Lo;0;L;;;;;N;;;;; +1234;ETHIOPIC SYLLABLE SEE;Lo;0;L;;;;;N;;;;; +1235;ETHIOPIC SYLLABLE SE;Lo;0;L;;;;;N;;;;; +1236;ETHIOPIC SYLLABLE SO;Lo;0;L;;;;;N;;;;; +1237;ETHIOPIC SYLLABLE SWA;Lo;0;L;;;;;N;;;;; +1238;ETHIOPIC SYLLABLE SHA;Lo;0;L;;;;;N;;;;; +1239;ETHIOPIC SYLLABLE SHU;Lo;0;L;;;;;N;;;;; +123A;ETHIOPIC SYLLABLE SHI;Lo;0;L;;;;;N;;;;; +123B;ETHIOPIC SYLLABLE SHAA;Lo;0;L;;;;;N;;;;; +123C;ETHIOPIC SYLLABLE SHEE;Lo;0;L;;;;;N;;;;; +123D;ETHIOPIC SYLLABLE SHE;Lo;0;L;;;;;N;;;;; +123E;ETHIOPIC SYLLABLE SHO;Lo;0;L;;;;;N;;;;; +123F;ETHIOPIC SYLLABLE SHWA;Lo;0;L;;;;;N;;;;; +1240;ETHIOPIC SYLLABLE QA;Lo;0;L;;;;;N;;;;; +1241;ETHIOPIC SYLLABLE QU;Lo;0;L;;;;;N;;;;; +1242;ETHIOPIC SYLLABLE QI;Lo;0;L;;;;;N;;;;; +1243;ETHIOPIC SYLLABLE QAA;Lo;0;L;;;;;N;;;;; +1244;ETHIOPIC SYLLABLE QEE;Lo;0;L;;;;;N;;;;; +1245;ETHIOPIC SYLLABLE QE;Lo;0;L;;;;;N;;;;; +1246;ETHIOPIC SYLLABLE QO;Lo;0;L;;;;;N;;;;; +1248;ETHIOPIC SYLLABLE QWA;Lo;0;L;;;;;N;;;;; +124A;ETHIOPIC SYLLABLE QWI;Lo;0;L;;;;;N;;;;; +124B;ETHIOPIC SYLLABLE QWAA;Lo;0;L;;;;;N;;;;; +124C;ETHIOPIC SYLLABLE QWEE;Lo;0;L;;;;;N;;;;; +124D;ETHIOPIC SYLLABLE QWE;Lo;0;L;;;;;N;;;;; +1250;ETHIOPIC SYLLABLE QHA;Lo;0;L;;;;;N;;;;; +1251;ETHIOPIC SYLLABLE QHU;Lo;0;L;;;;;N;;;;; +1252;ETHIOPIC SYLLABLE QHI;Lo;0;L;;;;;N;;;;; +1253;ETHIOPIC SYLLABLE QHAA;Lo;0;L;;;;;N;;;;; +1254;ETHIOPIC SYLLABLE QHEE;Lo;0;L;;;;;N;;;;; +1255;ETHIOPIC SYLLABLE QHE;Lo;0;L;;;;;N;;;;; +1256;ETHIOPIC SYLLABLE QHO;Lo;0;L;;;;;N;;;;; +1258;ETHIOPIC SYLLABLE QHWA;Lo;0;L;;;;;N;;;;; +125A;ETHIOPIC SYLLABLE QHWI;Lo;0;L;;;;;N;;;;; +125B;ETHIOPIC SYLLABLE QHWAA;Lo;0;L;;;;;N;;;;; +125C;ETHIOPIC SYLLABLE QHWEE;Lo;0;L;;;;;N;;;;; +125D;ETHIOPIC SYLLABLE QHWE;Lo;0;L;;;;;N;;;;; +1260;ETHIOPIC SYLLABLE BA;Lo;0;L;;;;;N;;;;; +1261;ETHIOPIC SYLLABLE BU;Lo;0;L;;;;;N;;;;; +1262;ETHIOPIC SYLLABLE BI;Lo;0;L;;;;;N;;;;; +1263;ETHIOPIC SYLLABLE BAA;Lo;0;L;;;;;N;;;;; +1264;ETHIOPIC SYLLABLE BEE;Lo;0;L;;;;;N;;;;; +1265;ETHIOPIC SYLLABLE BE;Lo;0;L;;;;;N;;;;; +1266;ETHIOPIC SYLLABLE BO;Lo;0;L;;;;;N;;;;; +1267;ETHIOPIC SYLLABLE BWA;Lo;0;L;;;;;N;;;;; +1268;ETHIOPIC SYLLABLE VA;Lo;0;L;;;;;N;;;;; +1269;ETHIOPIC SYLLABLE VU;Lo;0;L;;;;;N;;;;; +126A;ETHIOPIC SYLLABLE VI;Lo;0;L;;;;;N;;;;; +126B;ETHIOPIC SYLLABLE VAA;Lo;0;L;;;;;N;;;;; +126C;ETHIOPIC SYLLABLE VEE;Lo;0;L;;;;;N;;;;; +126D;ETHIOPIC SYLLABLE VE;Lo;0;L;;;;;N;;;;; +126E;ETHIOPIC SYLLABLE VO;Lo;0;L;;;;;N;;;;; +126F;ETHIOPIC SYLLABLE VWA;Lo;0;L;;;;;N;;;;; +1270;ETHIOPIC SYLLABLE TA;Lo;0;L;;;;;N;;;;; +1271;ETHIOPIC SYLLABLE TU;Lo;0;L;;;;;N;;;;; +1272;ETHIOPIC SYLLABLE TI;Lo;0;L;;;;;N;;;;; +1273;ETHIOPIC SYLLABLE TAA;Lo;0;L;;;;;N;;;;; +1274;ETHIOPIC SYLLABLE TEE;Lo;0;L;;;;;N;;;;; +1275;ETHIOPIC SYLLABLE TE;Lo;0;L;;;;;N;;;;; +1276;ETHIOPIC SYLLABLE TO;Lo;0;L;;;;;N;;;;; +1277;ETHIOPIC SYLLABLE TWA;Lo;0;L;;;;;N;;;;; +1278;ETHIOPIC SYLLABLE CA;Lo;0;L;;;;;N;;;;; +1279;ETHIOPIC SYLLABLE CU;Lo;0;L;;;;;N;;;;; +127A;ETHIOPIC SYLLABLE CI;Lo;0;L;;;;;N;;;;; +127B;ETHIOPIC SYLLABLE CAA;Lo;0;L;;;;;N;;;;; +127C;ETHIOPIC SYLLABLE CEE;Lo;0;L;;;;;N;;;;; +127D;ETHIOPIC SYLLABLE CE;Lo;0;L;;;;;N;;;;; +127E;ETHIOPIC SYLLABLE CO;Lo;0;L;;;;;N;;;;; +127F;ETHIOPIC SYLLABLE CWA;Lo;0;L;;;;;N;;;;; +1280;ETHIOPIC SYLLABLE XA;Lo;0;L;;;;;N;;;;; +1281;ETHIOPIC SYLLABLE XU;Lo;0;L;;;;;N;;;;; +1282;ETHIOPIC SYLLABLE XI;Lo;0;L;;;;;N;;;;; +1283;ETHIOPIC SYLLABLE XAA;Lo;0;L;;;;;N;;;;; +1284;ETHIOPIC SYLLABLE XEE;Lo;0;L;;;;;N;;;;; +1285;ETHIOPIC SYLLABLE XE;Lo;0;L;;;;;N;;;;; +1286;ETHIOPIC SYLLABLE XO;Lo;0;L;;;;;N;;;;; +1288;ETHIOPIC SYLLABLE XWA;Lo;0;L;;;;;N;;;;; +128A;ETHIOPIC SYLLABLE XWI;Lo;0;L;;;;;N;;;;; +128B;ETHIOPIC SYLLABLE XWAA;Lo;0;L;;;;;N;;;;; +128C;ETHIOPIC SYLLABLE XWEE;Lo;0;L;;;;;N;;;;; +128D;ETHIOPIC SYLLABLE XWE;Lo;0;L;;;;;N;;;;; +1290;ETHIOPIC SYLLABLE NA;Lo;0;L;;;;;N;;;;; +1291;ETHIOPIC SYLLABLE NU;Lo;0;L;;;;;N;;;;; +1292;ETHIOPIC SYLLABLE NI;Lo;0;L;;;;;N;;;;; +1293;ETHIOPIC SYLLABLE NAA;Lo;0;L;;;;;N;;;;; +1294;ETHIOPIC SYLLABLE NEE;Lo;0;L;;;;;N;;;;; +1295;ETHIOPIC SYLLABLE NE;Lo;0;L;;;;;N;;;;; +1296;ETHIOPIC SYLLABLE NO;Lo;0;L;;;;;N;;;;; +1297;ETHIOPIC SYLLABLE NWA;Lo;0;L;;;;;N;;;;; +1298;ETHIOPIC SYLLABLE NYA;Lo;0;L;;;;;N;;;;; +1299;ETHIOPIC SYLLABLE NYU;Lo;0;L;;;;;N;;;;; +129A;ETHIOPIC SYLLABLE NYI;Lo;0;L;;;;;N;;;;; +129B;ETHIOPIC SYLLABLE NYAA;Lo;0;L;;;;;N;;;;; +129C;ETHIOPIC SYLLABLE NYEE;Lo;0;L;;;;;N;;;;; +129D;ETHIOPIC SYLLABLE NYE;Lo;0;L;;;;;N;;;;; +129E;ETHIOPIC SYLLABLE NYO;Lo;0;L;;;;;N;;;;; +129F;ETHIOPIC SYLLABLE NYWA;Lo;0;L;;;;;N;;;;; +12A0;ETHIOPIC SYLLABLE GLOTTAL A;Lo;0;L;;;;;N;;;;; +12A1;ETHIOPIC SYLLABLE GLOTTAL U;Lo;0;L;;;;;N;;;;; +12A2;ETHIOPIC SYLLABLE GLOTTAL I;Lo;0;L;;;;;N;;;;; +12A3;ETHIOPIC SYLLABLE GLOTTAL AA;Lo;0;L;;;;;N;;;;; +12A4;ETHIOPIC SYLLABLE GLOTTAL EE;Lo;0;L;;;;;N;;;;; +12A5;ETHIOPIC SYLLABLE GLOTTAL E;Lo;0;L;;;;;N;;;;; +12A6;ETHIOPIC SYLLABLE GLOTTAL O;Lo;0;L;;;;;N;;;;; +12A7;ETHIOPIC SYLLABLE GLOTTAL WA;Lo;0;L;;;;;N;;;;; +12A8;ETHIOPIC SYLLABLE KA;Lo;0;L;;;;;N;;;;; +12A9;ETHIOPIC SYLLABLE KU;Lo;0;L;;;;;N;;;;; +12AA;ETHIOPIC SYLLABLE KI;Lo;0;L;;;;;N;;;;; +12AB;ETHIOPIC SYLLABLE KAA;Lo;0;L;;;;;N;;;;; +12AC;ETHIOPIC SYLLABLE KEE;Lo;0;L;;;;;N;;;;; +12AD;ETHIOPIC SYLLABLE KE;Lo;0;L;;;;;N;;;;; +12AE;ETHIOPIC SYLLABLE KO;Lo;0;L;;;;;N;;;;; +12B0;ETHIOPIC SYLLABLE KWA;Lo;0;L;;;;;N;;;;; +12B2;ETHIOPIC SYLLABLE KWI;Lo;0;L;;;;;N;;;;; +12B3;ETHIOPIC SYLLABLE KWAA;Lo;0;L;;;;;N;;;;; +12B4;ETHIOPIC SYLLABLE KWEE;Lo;0;L;;;;;N;;;;; +12B5;ETHIOPIC SYLLABLE KWE;Lo;0;L;;;;;N;;;;; +12B8;ETHIOPIC SYLLABLE KXA;Lo;0;L;;;;;N;;;;; +12B9;ETHIOPIC SYLLABLE KXU;Lo;0;L;;;;;N;;;;; +12BA;ETHIOPIC SYLLABLE KXI;Lo;0;L;;;;;N;;;;; +12BB;ETHIOPIC SYLLABLE KXAA;Lo;0;L;;;;;N;;;;; +12BC;ETHIOPIC SYLLABLE KXEE;Lo;0;L;;;;;N;;;;; +12BD;ETHIOPIC SYLLABLE KXE;Lo;0;L;;;;;N;;;;; +12BE;ETHIOPIC SYLLABLE KXO;Lo;0;L;;;;;N;;;;; +12C0;ETHIOPIC SYLLABLE KXWA;Lo;0;L;;;;;N;;;;; +12C2;ETHIOPIC SYLLABLE KXWI;Lo;0;L;;;;;N;;;;; +12C3;ETHIOPIC SYLLABLE KXWAA;Lo;0;L;;;;;N;;;;; +12C4;ETHIOPIC SYLLABLE KXWEE;Lo;0;L;;;;;N;;;;; +12C5;ETHIOPIC SYLLABLE KXWE;Lo;0;L;;;;;N;;;;; +12C8;ETHIOPIC SYLLABLE WA;Lo;0;L;;;;;N;;;;; +12C9;ETHIOPIC SYLLABLE WU;Lo;0;L;;;;;N;;;;; +12CA;ETHIOPIC SYLLABLE WI;Lo;0;L;;;;;N;;;;; +12CB;ETHIOPIC SYLLABLE WAA;Lo;0;L;;;;;N;;;;; +12CC;ETHIOPIC SYLLABLE WEE;Lo;0;L;;;;;N;;;;; +12CD;ETHIOPIC SYLLABLE WE;Lo;0;L;;;;;N;;;;; +12CE;ETHIOPIC SYLLABLE WO;Lo;0;L;;;;;N;;;;; +12D0;ETHIOPIC SYLLABLE PHARYNGEAL A;Lo;0;L;;;;;N;;;;; +12D1;ETHIOPIC SYLLABLE PHARYNGEAL U;Lo;0;L;;;;;N;;;;; +12D2;ETHIOPIC SYLLABLE PHARYNGEAL I;Lo;0;L;;;;;N;;;;; +12D3;ETHIOPIC SYLLABLE PHARYNGEAL AA;Lo;0;L;;;;;N;;;;; +12D4;ETHIOPIC SYLLABLE PHARYNGEAL EE;Lo;0;L;;;;;N;;;;; +12D5;ETHIOPIC SYLLABLE PHARYNGEAL E;Lo;0;L;;;;;N;;;;; +12D6;ETHIOPIC SYLLABLE PHARYNGEAL O;Lo;0;L;;;;;N;;;;; +12D8;ETHIOPIC SYLLABLE ZA;Lo;0;L;;;;;N;;;;; +12D9;ETHIOPIC SYLLABLE ZU;Lo;0;L;;;;;N;;;;; +12DA;ETHIOPIC SYLLABLE ZI;Lo;0;L;;;;;N;;;;; +12DB;ETHIOPIC SYLLABLE ZAA;Lo;0;L;;;;;N;;;;; +12DC;ETHIOPIC SYLLABLE ZEE;Lo;0;L;;;;;N;;;;; +12DD;ETHIOPIC SYLLABLE ZE;Lo;0;L;;;;;N;;;;; +12DE;ETHIOPIC SYLLABLE ZO;Lo;0;L;;;;;N;;;;; +12DF;ETHIOPIC SYLLABLE ZWA;Lo;0;L;;;;;N;;;;; +12E0;ETHIOPIC SYLLABLE ZHA;Lo;0;L;;;;;N;;;;; +12E1;ETHIOPIC SYLLABLE ZHU;Lo;0;L;;;;;N;;;;; +12E2;ETHIOPIC SYLLABLE ZHI;Lo;0;L;;;;;N;;;;; +12E3;ETHIOPIC SYLLABLE ZHAA;Lo;0;L;;;;;N;;;;; +12E4;ETHIOPIC SYLLABLE ZHEE;Lo;0;L;;;;;N;;;;; +12E5;ETHIOPIC SYLLABLE ZHE;Lo;0;L;;;;;N;;;;; +12E6;ETHIOPIC SYLLABLE ZHO;Lo;0;L;;;;;N;;;;; +12E7;ETHIOPIC SYLLABLE ZHWA;Lo;0;L;;;;;N;;;;; +12E8;ETHIOPIC SYLLABLE YA;Lo;0;L;;;;;N;;;;; +12E9;ETHIOPIC SYLLABLE YU;Lo;0;L;;;;;N;;;;; +12EA;ETHIOPIC SYLLABLE YI;Lo;0;L;;;;;N;;;;; +12EB;ETHIOPIC SYLLABLE YAA;Lo;0;L;;;;;N;;;;; +12EC;ETHIOPIC SYLLABLE YEE;Lo;0;L;;;;;N;;;;; +12ED;ETHIOPIC SYLLABLE YE;Lo;0;L;;;;;N;;;;; +12EE;ETHIOPIC SYLLABLE YO;Lo;0;L;;;;;N;;;;; +12F0;ETHIOPIC SYLLABLE DA;Lo;0;L;;;;;N;;;;; +12F1;ETHIOPIC SYLLABLE DU;Lo;0;L;;;;;N;;;;; +12F2;ETHIOPIC SYLLABLE DI;Lo;0;L;;;;;N;;;;; +12F3;ETHIOPIC SYLLABLE DAA;Lo;0;L;;;;;N;;;;; +12F4;ETHIOPIC SYLLABLE DEE;Lo;0;L;;;;;N;;;;; +12F5;ETHIOPIC SYLLABLE DE;Lo;0;L;;;;;N;;;;; +12F6;ETHIOPIC SYLLABLE DO;Lo;0;L;;;;;N;;;;; +12F7;ETHIOPIC SYLLABLE DWA;Lo;0;L;;;;;N;;;;; +12F8;ETHIOPIC SYLLABLE DDA;Lo;0;L;;;;;N;;;;; +12F9;ETHIOPIC SYLLABLE DDU;Lo;0;L;;;;;N;;;;; +12FA;ETHIOPIC SYLLABLE DDI;Lo;0;L;;;;;N;;;;; +12FB;ETHIOPIC SYLLABLE DDAA;Lo;0;L;;;;;N;;;;; +12FC;ETHIOPIC SYLLABLE DDEE;Lo;0;L;;;;;N;;;;; +12FD;ETHIOPIC SYLLABLE DDE;Lo;0;L;;;;;N;;;;; +12FE;ETHIOPIC SYLLABLE DDO;Lo;0;L;;;;;N;;;;; +12FF;ETHIOPIC SYLLABLE DDWA;Lo;0;L;;;;;N;;;;; +1300;ETHIOPIC SYLLABLE JA;Lo;0;L;;;;;N;;;;; +1301;ETHIOPIC SYLLABLE JU;Lo;0;L;;;;;N;;;;; +1302;ETHIOPIC SYLLABLE JI;Lo;0;L;;;;;N;;;;; +1303;ETHIOPIC SYLLABLE JAA;Lo;0;L;;;;;N;;;;; +1304;ETHIOPIC SYLLABLE JEE;Lo;0;L;;;;;N;;;;; +1305;ETHIOPIC SYLLABLE JE;Lo;0;L;;;;;N;;;;; +1306;ETHIOPIC SYLLABLE JO;Lo;0;L;;;;;N;;;;; +1307;ETHIOPIC SYLLABLE JWA;Lo;0;L;;;;;N;;;;; +1308;ETHIOPIC SYLLABLE GA;Lo;0;L;;;;;N;;;;; +1309;ETHIOPIC SYLLABLE GU;Lo;0;L;;;;;N;;;;; +130A;ETHIOPIC SYLLABLE GI;Lo;0;L;;;;;N;;;;; +130B;ETHIOPIC SYLLABLE GAA;Lo;0;L;;;;;N;;;;; +130C;ETHIOPIC SYLLABLE GEE;Lo;0;L;;;;;N;;;;; +130D;ETHIOPIC SYLLABLE GE;Lo;0;L;;;;;N;;;;; +130E;ETHIOPIC SYLLABLE GO;Lo;0;L;;;;;N;;;;; +1310;ETHIOPIC SYLLABLE GWA;Lo;0;L;;;;;N;;;;; +1312;ETHIOPIC SYLLABLE GWI;Lo;0;L;;;;;N;;;;; +1313;ETHIOPIC SYLLABLE GWAA;Lo;0;L;;;;;N;;;;; +1314;ETHIOPIC SYLLABLE GWEE;Lo;0;L;;;;;N;;;;; +1315;ETHIOPIC SYLLABLE GWE;Lo;0;L;;;;;N;;;;; +1318;ETHIOPIC SYLLABLE GGA;Lo;0;L;;;;;N;;;;; +1319;ETHIOPIC SYLLABLE GGU;Lo;0;L;;;;;N;;;;; +131A;ETHIOPIC SYLLABLE GGI;Lo;0;L;;;;;N;;;;; +131B;ETHIOPIC SYLLABLE GGAA;Lo;0;L;;;;;N;;;;; +131C;ETHIOPIC SYLLABLE GGEE;Lo;0;L;;;;;N;;;;; +131D;ETHIOPIC SYLLABLE GGE;Lo;0;L;;;;;N;;;;; +131E;ETHIOPIC SYLLABLE GGO;Lo;0;L;;;;;N;;;;; +1320;ETHIOPIC SYLLABLE THA;Lo;0;L;;;;;N;;;;; +1321;ETHIOPIC SYLLABLE THU;Lo;0;L;;;;;N;;;;; +1322;ETHIOPIC SYLLABLE THI;Lo;0;L;;;;;N;;;;; +1323;ETHIOPIC SYLLABLE THAA;Lo;0;L;;;;;N;;;;; +1324;ETHIOPIC SYLLABLE THEE;Lo;0;L;;;;;N;;;;; +1325;ETHIOPIC SYLLABLE THE;Lo;0;L;;;;;N;;;;; +1326;ETHIOPIC SYLLABLE THO;Lo;0;L;;;;;N;;;;; +1327;ETHIOPIC SYLLABLE THWA;Lo;0;L;;;;;N;;;;; +1328;ETHIOPIC SYLLABLE CHA;Lo;0;L;;;;;N;;;;; +1329;ETHIOPIC SYLLABLE CHU;Lo;0;L;;;;;N;;;;; +132A;ETHIOPIC SYLLABLE CHI;Lo;0;L;;;;;N;;;;; +132B;ETHIOPIC SYLLABLE CHAA;Lo;0;L;;;;;N;;;;; +132C;ETHIOPIC SYLLABLE CHEE;Lo;0;L;;;;;N;;;;; +132D;ETHIOPIC SYLLABLE CHE;Lo;0;L;;;;;N;;;;; +132E;ETHIOPIC SYLLABLE CHO;Lo;0;L;;;;;N;;;;; +132F;ETHIOPIC SYLLABLE CHWA;Lo;0;L;;;;;N;;;;; +1330;ETHIOPIC SYLLABLE PHA;Lo;0;L;;;;;N;;;;; +1331;ETHIOPIC SYLLABLE PHU;Lo;0;L;;;;;N;;;;; +1332;ETHIOPIC SYLLABLE PHI;Lo;0;L;;;;;N;;;;; +1333;ETHIOPIC SYLLABLE PHAA;Lo;0;L;;;;;N;;;;; +1334;ETHIOPIC SYLLABLE PHEE;Lo;0;L;;;;;N;;;;; +1335;ETHIOPIC SYLLABLE PHE;Lo;0;L;;;;;N;;;;; +1336;ETHIOPIC SYLLABLE PHO;Lo;0;L;;;;;N;;;;; +1337;ETHIOPIC SYLLABLE PHWA;Lo;0;L;;;;;N;;;;; +1338;ETHIOPIC SYLLABLE TSA;Lo;0;L;;;;;N;;;;; +1339;ETHIOPIC SYLLABLE TSU;Lo;0;L;;;;;N;;;;; +133A;ETHIOPIC SYLLABLE TSI;Lo;0;L;;;;;N;;;;; +133B;ETHIOPIC SYLLABLE TSAA;Lo;0;L;;;;;N;;;;; +133C;ETHIOPIC SYLLABLE TSEE;Lo;0;L;;;;;N;;;;; +133D;ETHIOPIC SYLLABLE TSE;Lo;0;L;;;;;N;;;;; +133E;ETHIOPIC SYLLABLE TSO;Lo;0;L;;;;;N;;;;; +133F;ETHIOPIC SYLLABLE TSWA;Lo;0;L;;;;;N;;;;; +1340;ETHIOPIC SYLLABLE TZA;Lo;0;L;;;;;N;;;;; +1341;ETHIOPIC SYLLABLE TZU;Lo;0;L;;;;;N;;;;; +1342;ETHIOPIC SYLLABLE TZI;Lo;0;L;;;;;N;;;;; +1343;ETHIOPIC SYLLABLE TZAA;Lo;0;L;;;;;N;;;;; +1344;ETHIOPIC SYLLABLE TZEE;Lo;0;L;;;;;N;;;;; +1345;ETHIOPIC SYLLABLE TZE;Lo;0;L;;;;;N;;;;; +1346;ETHIOPIC SYLLABLE TZO;Lo;0;L;;;;;N;;;;; +1348;ETHIOPIC SYLLABLE FA;Lo;0;L;;;;;N;;;;; +1349;ETHIOPIC SYLLABLE FU;Lo;0;L;;;;;N;;;;; +134A;ETHIOPIC SYLLABLE FI;Lo;0;L;;;;;N;;;;; +134B;ETHIOPIC SYLLABLE FAA;Lo;0;L;;;;;N;;;;; +134C;ETHIOPIC SYLLABLE FEE;Lo;0;L;;;;;N;;;;; +134D;ETHIOPIC SYLLABLE FE;Lo;0;L;;;;;N;;;;; +134E;ETHIOPIC SYLLABLE FO;Lo;0;L;;;;;N;;;;; +134F;ETHIOPIC SYLLABLE FWA;Lo;0;L;;;;;N;;;;; +1350;ETHIOPIC SYLLABLE PA;Lo;0;L;;;;;N;;;;; +1351;ETHIOPIC SYLLABLE PU;Lo;0;L;;;;;N;;;;; +1352;ETHIOPIC SYLLABLE PI;Lo;0;L;;;;;N;;;;; +1353;ETHIOPIC SYLLABLE PAA;Lo;0;L;;;;;N;;;;; +1354;ETHIOPIC SYLLABLE PEE;Lo;0;L;;;;;N;;;;; +1355;ETHIOPIC SYLLABLE PE;Lo;0;L;;;;;N;;;;; +1356;ETHIOPIC SYLLABLE PO;Lo;0;L;;;;;N;;;;; +1357;ETHIOPIC SYLLABLE PWA;Lo;0;L;;;;;N;;;;; +1358;ETHIOPIC SYLLABLE RYA;Lo;0;L;;;;;N;;;;; +1359;ETHIOPIC SYLLABLE MYA;Lo;0;L;;;;;N;;;;; +135A;ETHIOPIC SYLLABLE FYA;Lo;0;L;;;;;N;;;;; +1361;ETHIOPIC WORDSPACE;Po;0;L;;;;;N;;;;; +1362;ETHIOPIC FULL STOP;Po;0;L;;;;;N;;;;; +1363;ETHIOPIC COMMA;Po;0;L;;;;;N;;;;; +1364;ETHIOPIC SEMICOLON;Po;0;L;;;;;N;;;;; +1365;ETHIOPIC COLON;Po;0;L;;;;;N;;;;; +1366;ETHIOPIC PREFACE COLON;Po;0;L;;;;;N;;;;; +1367;ETHIOPIC QUESTION MARK;Po;0;L;;;;;N;;;;; +1368;ETHIOPIC PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;; +1369;ETHIOPIC DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +136A;ETHIOPIC DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +136B;ETHIOPIC DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +136C;ETHIOPIC DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +136D;ETHIOPIC DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +136E;ETHIOPIC DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +136F;ETHIOPIC DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1370;ETHIOPIC DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1371;ETHIOPIC DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1372;ETHIOPIC NUMBER TEN;No;0;L;;;;10;N;;;;; +1373;ETHIOPIC NUMBER TWENTY;No;0;L;;;;20;N;;;;; +1374;ETHIOPIC NUMBER THIRTY;No;0;L;;;;30;N;;;;; +1375;ETHIOPIC NUMBER FORTY;No;0;L;;;;40;N;;;;; +1376;ETHIOPIC NUMBER FIFTY;No;0;L;;;;50;N;;;;; +1377;ETHIOPIC NUMBER SIXTY;No;0;L;;;;60;N;;;;; +1378;ETHIOPIC NUMBER SEVENTY;No;0;L;;;;70;N;;;;; +1379;ETHIOPIC NUMBER EIGHTY;No;0;L;;;;80;N;;;;; +137A;ETHIOPIC NUMBER NINETY;No;0;L;;;;90;N;;;;; +137B;ETHIOPIC NUMBER HUNDRED;No;0;L;;;;100;N;;;;; +137C;ETHIOPIC NUMBER TEN THOUSAND;No;0;L;;;;10000;N;;;;; +13A0;CHEROKEE LETTER A;Lo;0;L;;;;;N;;;;; +13A1;CHEROKEE LETTER E;Lo;0;L;;;;;N;;;;; +13A2;CHEROKEE LETTER I;Lo;0;L;;;;;N;;;;; +13A3;CHEROKEE LETTER O;Lo;0;L;;;;;N;;;;; +13A4;CHEROKEE LETTER U;Lo;0;L;;;;;N;;;;; +13A5;CHEROKEE LETTER V;Lo;0;L;;;;;N;;;;; +13A6;CHEROKEE LETTER GA;Lo;0;L;;;;;N;;;;; +13A7;CHEROKEE LETTER KA;Lo;0;L;;;;;N;;;;; +13A8;CHEROKEE LETTER GE;Lo;0;L;;;;;N;;;;; +13A9;CHEROKEE LETTER GI;Lo;0;L;;;;;N;;;;; +13AA;CHEROKEE LETTER GO;Lo;0;L;;;;;N;;;;; +13AB;CHEROKEE LETTER GU;Lo;0;L;;;;;N;;;;; +13AC;CHEROKEE LETTER GV;Lo;0;L;;;;;N;;;;; +13AD;CHEROKEE LETTER HA;Lo;0;L;;;;;N;;;;; +13AE;CHEROKEE LETTER HE;Lo;0;L;;;;;N;;;;; +13AF;CHEROKEE LETTER HI;Lo;0;L;;;;;N;;;;; +13B0;CHEROKEE LETTER HO;Lo;0;L;;;;;N;;;;; +13B1;CHEROKEE LETTER HU;Lo;0;L;;;;;N;;;;; +13B2;CHEROKEE LETTER HV;Lo;0;L;;;;;N;;;;; +13B3;CHEROKEE LETTER LA;Lo;0;L;;;;;N;;;;; +13B4;CHEROKEE LETTER LE;Lo;0;L;;;;;N;;;;; +13B5;CHEROKEE LETTER LI;Lo;0;L;;;;;N;;;;; +13B6;CHEROKEE LETTER LO;Lo;0;L;;;;;N;;;;; +13B7;CHEROKEE LETTER LU;Lo;0;L;;;;;N;;;;; +13B8;CHEROKEE LETTER LV;Lo;0;L;;;;;N;;;;; +13B9;CHEROKEE LETTER MA;Lo;0;L;;;;;N;;;;; +13BA;CHEROKEE LETTER ME;Lo;0;L;;;;;N;;;;; +13BB;CHEROKEE LETTER MI;Lo;0;L;;;;;N;;;;; +13BC;CHEROKEE LETTER MO;Lo;0;L;;;;;N;;;;; +13BD;CHEROKEE LETTER MU;Lo;0;L;;;;;N;;;;; +13BE;CHEROKEE LETTER NA;Lo;0;L;;;;;N;;;;; +13BF;CHEROKEE LETTER HNA;Lo;0;L;;;;;N;;;;; +13C0;CHEROKEE LETTER NAH;Lo;0;L;;;;;N;;;;; +13C1;CHEROKEE LETTER NE;Lo;0;L;;;;;N;;;;; +13C2;CHEROKEE LETTER NI;Lo;0;L;;;;;N;;;;; +13C3;CHEROKEE LETTER NO;Lo;0;L;;;;;N;;;;; +13C4;CHEROKEE LETTER NU;Lo;0;L;;;;;N;;;;; +13C5;CHEROKEE LETTER NV;Lo;0;L;;;;;N;;;;; +13C6;CHEROKEE LETTER QUA;Lo;0;L;;;;;N;;;;; +13C7;CHEROKEE LETTER QUE;Lo;0;L;;;;;N;;;;; +13C8;CHEROKEE LETTER QUI;Lo;0;L;;;;;N;;;;; +13C9;CHEROKEE LETTER QUO;Lo;0;L;;;;;N;;;;; +13CA;CHEROKEE LETTER QUU;Lo;0;L;;;;;N;;;;; +13CB;CHEROKEE LETTER QUV;Lo;0;L;;;;;N;;;;; +13CC;CHEROKEE LETTER SA;Lo;0;L;;;;;N;;;;; +13CD;CHEROKEE LETTER S;Lo;0;L;;;;;N;;;;; +13CE;CHEROKEE LETTER SE;Lo;0;L;;;;;N;;;;; +13CF;CHEROKEE LETTER SI;Lo;0;L;;;;;N;;;;; +13D0;CHEROKEE LETTER SO;Lo;0;L;;;;;N;;;;; +13D1;CHEROKEE LETTER SU;Lo;0;L;;;;;N;;;;; +13D2;CHEROKEE LETTER SV;Lo;0;L;;;;;N;;;;; +13D3;CHEROKEE LETTER DA;Lo;0;L;;;;;N;;;;; +13D4;CHEROKEE LETTER TA;Lo;0;L;;;;;N;;;;; +13D5;CHEROKEE LETTER DE;Lo;0;L;;;;;N;;;;; +13D6;CHEROKEE LETTER TE;Lo;0;L;;;;;N;;;;; +13D7;CHEROKEE LETTER DI;Lo;0;L;;;;;N;;;;; +13D8;CHEROKEE LETTER TI;Lo;0;L;;;;;N;;;;; +13D9;CHEROKEE LETTER DO;Lo;0;L;;;;;N;;;;; +13DA;CHEROKEE LETTER DU;Lo;0;L;;;;;N;;;;; +13DB;CHEROKEE LETTER DV;Lo;0;L;;;;;N;;;;; +13DC;CHEROKEE LETTER DLA;Lo;0;L;;;;;N;;;;; +13DD;CHEROKEE LETTER TLA;Lo;0;L;;;;;N;;;;; +13DE;CHEROKEE LETTER TLE;Lo;0;L;;;;;N;;;;; +13DF;CHEROKEE LETTER TLI;Lo;0;L;;;;;N;;;;; +13E0;CHEROKEE LETTER TLO;Lo;0;L;;;;;N;;;;; +13E1;CHEROKEE LETTER TLU;Lo;0;L;;;;;N;;;;; +13E2;CHEROKEE LETTER TLV;Lo;0;L;;;;;N;;;;; +13E3;CHEROKEE LETTER TSA;Lo;0;L;;;;;N;;;;; +13E4;CHEROKEE LETTER TSE;Lo;0;L;;;;;N;;;;; +13E5;CHEROKEE LETTER TSI;Lo;0;L;;;;;N;;;;; +13E6;CHEROKEE LETTER TSO;Lo;0;L;;;;;N;;;;; +13E7;CHEROKEE LETTER TSU;Lo;0;L;;;;;N;;;;; +13E8;CHEROKEE LETTER TSV;Lo;0;L;;;;;N;;;;; +13E9;CHEROKEE LETTER WA;Lo;0;L;;;;;N;;;;; +13EA;CHEROKEE LETTER WE;Lo;0;L;;;;;N;;;;; +13EB;CHEROKEE LETTER WI;Lo;0;L;;;;;N;;;;; +13EC;CHEROKEE LETTER WO;Lo;0;L;;;;;N;;;;; +13ED;CHEROKEE LETTER WU;Lo;0;L;;;;;N;;;;; +13EE;CHEROKEE LETTER WV;Lo;0;L;;;;;N;;;;; +13EF;CHEROKEE LETTER YA;Lo;0;L;;;;;N;;;;; +13F0;CHEROKEE LETTER YE;Lo;0;L;;;;;N;;;;; +13F1;CHEROKEE LETTER YI;Lo;0;L;;;;;N;;;;; +13F2;CHEROKEE LETTER YO;Lo;0;L;;;;;N;;;;; +13F3;CHEROKEE LETTER YU;Lo;0;L;;;;;N;;;;; +13F4;CHEROKEE LETTER YV;Lo;0;L;;;;;N;;;;; +1401;CANADIAN SYLLABICS E;Lo;0;L;;;;;N;;;;; +1402;CANADIAN SYLLABICS AAI;Lo;0;L;;;;;N;;;;; +1403;CANADIAN SYLLABICS I;Lo;0;L;;;;;N;;;;; +1404;CANADIAN SYLLABICS II;Lo;0;L;;;;;N;;;;; +1405;CANADIAN SYLLABICS O;Lo;0;L;;;;;N;;;;; +1406;CANADIAN SYLLABICS OO;Lo;0;L;;;;;N;;;;; +1407;CANADIAN SYLLABICS Y-CREE OO;Lo;0;L;;;;;N;;;;; +1408;CANADIAN SYLLABICS CARRIER EE;Lo;0;L;;;;;N;;;;; +1409;CANADIAN SYLLABICS CARRIER I;Lo;0;L;;;;;N;;;;; +140A;CANADIAN SYLLABICS A;Lo;0;L;;;;;N;;;;; +140B;CANADIAN SYLLABICS AA;Lo;0;L;;;;;N;;;;; +140C;CANADIAN SYLLABICS WE;Lo;0;L;;;;;N;;;;; +140D;CANADIAN SYLLABICS WEST-CREE WE;Lo;0;L;;;;;N;;;;; +140E;CANADIAN SYLLABICS WI;Lo;0;L;;;;;N;;;;; +140F;CANADIAN SYLLABICS WEST-CREE WI;Lo;0;L;;;;;N;;;;; +1410;CANADIAN SYLLABICS WII;Lo;0;L;;;;;N;;;;; +1411;CANADIAN SYLLABICS WEST-CREE WII;Lo;0;L;;;;;N;;;;; +1412;CANADIAN SYLLABICS WO;Lo;0;L;;;;;N;;;;; +1413;CANADIAN SYLLABICS WEST-CREE WO;Lo;0;L;;;;;N;;;;; +1414;CANADIAN SYLLABICS WOO;Lo;0;L;;;;;N;;;;; +1415;CANADIAN SYLLABICS WEST-CREE WOO;Lo;0;L;;;;;N;;;;; +1416;CANADIAN SYLLABICS NASKAPI WOO;Lo;0;L;;;;;N;;;;; +1417;CANADIAN SYLLABICS WA;Lo;0;L;;;;;N;;;;; +1418;CANADIAN SYLLABICS WEST-CREE WA;Lo;0;L;;;;;N;;;;; +1419;CANADIAN SYLLABICS WAA;Lo;0;L;;;;;N;;;;; +141A;CANADIAN SYLLABICS WEST-CREE WAA;Lo;0;L;;;;;N;;;;; +141B;CANADIAN SYLLABICS NASKAPI WAA;Lo;0;L;;;;;N;;;;; +141C;CANADIAN SYLLABICS AI;Lo;0;L;;;;;N;;;;; +141D;CANADIAN SYLLABICS Y-CREE W;Lo;0;L;;;;;N;;;;; +141E;CANADIAN SYLLABICS GLOTTAL STOP;Lo;0;L;;;;;N;;;;; +141F;CANADIAN SYLLABICS FINAL ACUTE;Lo;0;L;;;;;N;;;;; +1420;CANADIAN SYLLABICS FINAL GRAVE;Lo;0;L;;;;;N;;;;; +1421;CANADIAN SYLLABICS FINAL BOTTOM HALF RING;Lo;0;L;;;;;N;;;;; +1422;CANADIAN SYLLABICS FINAL TOP HALF RING;Lo;0;L;;;;;N;;;;; +1423;CANADIAN SYLLABICS FINAL RIGHT HALF RING;Lo;0;L;;;;;N;;;;; +1424;CANADIAN SYLLABICS FINAL RING;Lo;0;L;;;;;N;;;;; +1425;CANADIAN SYLLABICS FINAL DOUBLE ACUTE;Lo;0;L;;;;;N;;;;; +1426;CANADIAN SYLLABICS FINAL DOUBLE SHORT VERTICAL STROKES;Lo;0;L;;;;;N;;;;; +1427;CANADIAN SYLLABICS FINAL MIDDLE DOT;Lo;0;L;;;;;N;;;;; +1428;CANADIAN SYLLABICS FINAL SHORT HORIZONTAL STROKE;Lo;0;L;;;;;N;;;;; +1429;CANADIAN SYLLABICS FINAL PLUS;Lo;0;L;;;;;N;;;;; +142A;CANADIAN SYLLABICS FINAL DOWN TACK;Lo;0;L;;;;;N;;;;; +142B;CANADIAN SYLLABICS EN;Lo;0;L;;;;;N;;;;; +142C;CANADIAN SYLLABICS IN;Lo;0;L;;;;;N;;;;; +142D;CANADIAN SYLLABICS ON;Lo;0;L;;;;;N;;;;; +142E;CANADIAN SYLLABICS AN;Lo;0;L;;;;;N;;;;; +142F;CANADIAN SYLLABICS PE;Lo;0;L;;;;;N;;;;; +1430;CANADIAN SYLLABICS PAAI;Lo;0;L;;;;;N;;;;; +1431;CANADIAN SYLLABICS PI;Lo;0;L;;;;;N;;;;; +1432;CANADIAN SYLLABICS PII;Lo;0;L;;;;;N;;;;; +1433;CANADIAN SYLLABICS PO;Lo;0;L;;;;;N;;;;; +1434;CANADIAN SYLLABICS POO;Lo;0;L;;;;;N;;;;; +1435;CANADIAN SYLLABICS Y-CREE POO;Lo;0;L;;;;;N;;;;; +1436;CANADIAN SYLLABICS CARRIER HEE;Lo;0;L;;;;;N;;;;; +1437;CANADIAN SYLLABICS CARRIER HI;Lo;0;L;;;;;N;;;;; +1438;CANADIAN SYLLABICS PA;Lo;0;L;;;;;N;;;;; +1439;CANADIAN SYLLABICS PAA;Lo;0;L;;;;;N;;;;; +143A;CANADIAN SYLLABICS PWE;Lo;0;L;;;;;N;;;;; +143B;CANADIAN SYLLABICS WEST-CREE PWE;Lo;0;L;;;;;N;;;;; +143C;CANADIAN SYLLABICS PWI;Lo;0;L;;;;;N;;;;; +143D;CANADIAN SYLLABICS WEST-CREE PWI;Lo;0;L;;;;;N;;;;; +143E;CANADIAN SYLLABICS PWII;Lo;0;L;;;;;N;;;;; +143F;CANADIAN SYLLABICS WEST-CREE PWII;Lo;0;L;;;;;N;;;;; +1440;CANADIAN SYLLABICS PWO;Lo;0;L;;;;;N;;;;; +1441;CANADIAN SYLLABICS WEST-CREE PWO;Lo;0;L;;;;;N;;;;; +1442;CANADIAN SYLLABICS PWOO;Lo;0;L;;;;;N;;;;; +1443;CANADIAN SYLLABICS WEST-CREE PWOO;Lo;0;L;;;;;N;;;;; +1444;CANADIAN SYLLABICS PWA;Lo;0;L;;;;;N;;;;; +1445;CANADIAN SYLLABICS WEST-CREE PWA;Lo;0;L;;;;;N;;;;; +1446;CANADIAN SYLLABICS PWAA;Lo;0;L;;;;;N;;;;; +1447;CANADIAN SYLLABICS WEST-CREE PWAA;Lo;0;L;;;;;N;;;;; +1448;CANADIAN SYLLABICS Y-CREE PWAA;Lo;0;L;;;;;N;;;;; +1449;CANADIAN SYLLABICS P;Lo;0;L;;;;;N;;;;; +144A;CANADIAN SYLLABICS WEST-CREE P;Lo;0;L;;;;;N;;;;; +144B;CANADIAN SYLLABICS CARRIER H;Lo;0;L;;;;;N;;;;; +144C;CANADIAN SYLLABICS TE;Lo;0;L;;;;;N;;;;; +144D;CANADIAN SYLLABICS TAAI;Lo;0;L;;;;;N;;;;; +144E;CANADIAN SYLLABICS TI;Lo;0;L;;;;;N;;;;; +144F;CANADIAN SYLLABICS TII;Lo;0;L;;;;;N;;;;; +1450;CANADIAN SYLLABICS TO;Lo;0;L;;;;;N;;;;; +1451;CANADIAN SYLLABICS TOO;Lo;0;L;;;;;N;;;;; +1452;CANADIAN SYLLABICS Y-CREE TOO;Lo;0;L;;;;;N;;;;; +1453;CANADIAN SYLLABICS CARRIER DEE;Lo;0;L;;;;;N;;;;; +1454;CANADIAN SYLLABICS CARRIER DI;Lo;0;L;;;;;N;;;;; +1455;CANADIAN SYLLABICS TA;Lo;0;L;;;;;N;;;;; +1456;CANADIAN SYLLABICS TAA;Lo;0;L;;;;;N;;;;; +1457;CANADIAN SYLLABICS TWE;Lo;0;L;;;;;N;;;;; +1458;CANADIAN SYLLABICS WEST-CREE TWE;Lo;0;L;;;;;N;;;;; +1459;CANADIAN SYLLABICS TWI;Lo;0;L;;;;;N;;;;; +145A;CANADIAN SYLLABICS WEST-CREE TWI;Lo;0;L;;;;;N;;;;; +145B;CANADIAN SYLLABICS TWII;Lo;0;L;;;;;N;;;;; +145C;CANADIAN SYLLABICS WEST-CREE TWII;Lo;0;L;;;;;N;;;;; +145D;CANADIAN SYLLABICS TWO;Lo;0;L;;;;;N;;;;; +145E;CANADIAN SYLLABICS WEST-CREE TWO;Lo;0;L;;;;;N;;;;; +145F;CANADIAN SYLLABICS TWOO;Lo;0;L;;;;;N;;;;; +1460;CANADIAN SYLLABICS WEST-CREE TWOO;Lo;0;L;;;;;N;;;;; +1461;CANADIAN SYLLABICS TWA;Lo;0;L;;;;;N;;;;; +1462;CANADIAN SYLLABICS WEST-CREE TWA;Lo;0;L;;;;;N;;;;; +1463;CANADIAN SYLLABICS TWAA;Lo;0;L;;;;;N;;;;; +1464;CANADIAN SYLLABICS WEST-CREE TWAA;Lo;0;L;;;;;N;;;;; +1465;CANADIAN SYLLABICS NASKAPI TWAA;Lo;0;L;;;;;N;;;;; +1466;CANADIAN SYLLABICS T;Lo;0;L;;;;;N;;;;; +1467;CANADIAN SYLLABICS TTE;Lo;0;L;;;;;N;;;;; +1468;CANADIAN SYLLABICS TTI;Lo;0;L;;;;;N;;;;; +1469;CANADIAN SYLLABICS TTO;Lo;0;L;;;;;N;;;;; +146A;CANADIAN SYLLABICS TTA;Lo;0;L;;;;;N;;;;; +146B;CANADIAN SYLLABICS KE;Lo;0;L;;;;;N;;;;; +146C;CANADIAN SYLLABICS KAAI;Lo;0;L;;;;;N;;;;; +146D;CANADIAN SYLLABICS KI;Lo;0;L;;;;;N;;;;; +146E;CANADIAN SYLLABICS KII;Lo;0;L;;;;;N;;;;; +146F;CANADIAN SYLLABICS KO;Lo;0;L;;;;;N;;;;; +1470;CANADIAN SYLLABICS KOO;Lo;0;L;;;;;N;;;;; +1471;CANADIAN SYLLABICS Y-CREE KOO;Lo;0;L;;;;;N;;;;; +1472;CANADIAN SYLLABICS KA;Lo;0;L;;;;;N;;;;; +1473;CANADIAN SYLLABICS KAA;Lo;0;L;;;;;N;;;;; +1474;CANADIAN SYLLABICS KWE;Lo;0;L;;;;;N;;;;; +1475;CANADIAN SYLLABICS WEST-CREE KWE;Lo;0;L;;;;;N;;;;; +1476;CANADIAN SYLLABICS KWI;Lo;0;L;;;;;N;;;;; +1477;CANADIAN SYLLABICS WEST-CREE KWI;Lo;0;L;;;;;N;;;;; +1478;CANADIAN SYLLABICS KWII;Lo;0;L;;;;;N;;;;; +1479;CANADIAN SYLLABICS WEST-CREE KWII;Lo;0;L;;;;;N;;;;; +147A;CANADIAN SYLLABICS KWO;Lo;0;L;;;;;N;;;;; +147B;CANADIAN SYLLABICS WEST-CREE KWO;Lo;0;L;;;;;N;;;;; +147C;CANADIAN SYLLABICS KWOO;Lo;0;L;;;;;N;;;;; +147D;CANADIAN SYLLABICS WEST-CREE KWOO;Lo;0;L;;;;;N;;;;; +147E;CANADIAN SYLLABICS KWA;Lo;0;L;;;;;N;;;;; +147F;CANADIAN SYLLABICS WEST-CREE KWA;Lo;0;L;;;;;N;;;;; +1480;CANADIAN SYLLABICS KWAA;Lo;0;L;;;;;N;;;;; +1481;CANADIAN SYLLABICS WEST-CREE KWAA;Lo;0;L;;;;;N;;;;; +1482;CANADIAN SYLLABICS NASKAPI KWAA;Lo;0;L;;;;;N;;;;; +1483;CANADIAN SYLLABICS K;Lo;0;L;;;;;N;;;;; +1484;CANADIAN SYLLABICS KW;Lo;0;L;;;;;N;;;;; +1485;CANADIAN SYLLABICS SOUTH-SLAVEY KEH;Lo;0;L;;;;;N;;;;; +1486;CANADIAN SYLLABICS SOUTH-SLAVEY KIH;Lo;0;L;;;;;N;;;;; +1487;CANADIAN SYLLABICS SOUTH-SLAVEY KOH;Lo;0;L;;;;;N;;;;; +1488;CANADIAN SYLLABICS SOUTH-SLAVEY KAH;Lo;0;L;;;;;N;;;;; +1489;CANADIAN SYLLABICS CE;Lo;0;L;;;;;N;;;;; +148A;CANADIAN SYLLABICS CAAI;Lo;0;L;;;;;N;;;;; +148B;CANADIAN SYLLABICS CI;Lo;0;L;;;;;N;;;;; +148C;CANADIAN SYLLABICS CII;Lo;0;L;;;;;N;;;;; +148D;CANADIAN SYLLABICS CO;Lo;0;L;;;;;N;;;;; +148E;CANADIAN SYLLABICS COO;Lo;0;L;;;;;N;;;;; +148F;CANADIAN SYLLABICS Y-CREE COO;Lo;0;L;;;;;N;;;;; +1490;CANADIAN SYLLABICS CA;Lo;0;L;;;;;N;;;;; +1491;CANADIAN SYLLABICS CAA;Lo;0;L;;;;;N;;;;; +1492;CANADIAN SYLLABICS CWE;Lo;0;L;;;;;N;;;;; +1493;CANADIAN SYLLABICS WEST-CREE CWE;Lo;0;L;;;;;N;;;;; +1494;CANADIAN SYLLABICS CWI;Lo;0;L;;;;;N;;;;; +1495;CANADIAN SYLLABICS WEST-CREE CWI;Lo;0;L;;;;;N;;;;; +1496;CANADIAN SYLLABICS CWII;Lo;0;L;;;;;N;;;;; +1497;CANADIAN SYLLABICS WEST-CREE CWII;Lo;0;L;;;;;N;;;;; +1498;CANADIAN SYLLABICS CWO;Lo;0;L;;;;;N;;;;; +1499;CANADIAN SYLLABICS WEST-CREE CWO;Lo;0;L;;;;;N;;;;; +149A;CANADIAN SYLLABICS CWOO;Lo;0;L;;;;;N;;;;; +149B;CANADIAN SYLLABICS WEST-CREE CWOO;Lo;0;L;;;;;N;;;;; +149C;CANADIAN SYLLABICS CWA;Lo;0;L;;;;;N;;;;; +149D;CANADIAN SYLLABICS WEST-CREE CWA;Lo;0;L;;;;;N;;;;; +149E;CANADIAN SYLLABICS CWAA;Lo;0;L;;;;;N;;;;; +149F;CANADIAN SYLLABICS WEST-CREE CWAA;Lo;0;L;;;;;N;;;;; +14A0;CANADIAN SYLLABICS NASKAPI CWAA;Lo;0;L;;;;;N;;;;; +14A1;CANADIAN SYLLABICS C;Lo;0;L;;;;;N;;;;; +14A2;CANADIAN SYLLABICS SAYISI TH;Lo;0;L;;;;;N;;;;; +14A3;CANADIAN SYLLABICS ME;Lo;0;L;;;;;N;;;;; +14A4;CANADIAN SYLLABICS MAAI;Lo;0;L;;;;;N;;;;; +14A5;CANADIAN SYLLABICS MI;Lo;0;L;;;;;N;;;;; +14A6;CANADIAN SYLLABICS MII;Lo;0;L;;;;;N;;;;; +14A7;CANADIAN SYLLABICS MO;Lo;0;L;;;;;N;;;;; +14A8;CANADIAN SYLLABICS MOO;Lo;0;L;;;;;N;;;;; +14A9;CANADIAN SYLLABICS Y-CREE MOO;Lo;0;L;;;;;N;;;;; +14AA;CANADIAN SYLLABICS MA;Lo;0;L;;;;;N;;;;; +14AB;CANADIAN SYLLABICS MAA;Lo;0;L;;;;;N;;;;; +14AC;CANADIAN SYLLABICS MWE;Lo;0;L;;;;;N;;;;; +14AD;CANADIAN SYLLABICS WEST-CREE MWE;Lo;0;L;;;;;N;;;;; +14AE;CANADIAN SYLLABICS MWI;Lo;0;L;;;;;N;;;;; +14AF;CANADIAN SYLLABICS WEST-CREE MWI;Lo;0;L;;;;;N;;;;; +14B0;CANADIAN SYLLABICS MWII;Lo;0;L;;;;;N;;;;; +14B1;CANADIAN SYLLABICS WEST-CREE MWII;Lo;0;L;;;;;N;;;;; +14B2;CANADIAN SYLLABICS MWO;Lo;0;L;;;;;N;;;;; +14B3;CANADIAN SYLLABICS WEST-CREE MWO;Lo;0;L;;;;;N;;;;; +14B4;CANADIAN SYLLABICS MWOO;Lo;0;L;;;;;N;;;;; +14B5;CANADIAN SYLLABICS WEST-CREE MWOO;Lo;0;L;;;;;N;;;;; +14B6;CANADIAN SYLLABICS MWA;Lo;0;L;;;;;N;;;;; +14B7;CANADIAN SYLLABICS WEST-CREE MWA;Lo;0;L;;;;;N;;;;; +14B8;CANADIAN SYLLABICS MWAA;Lo;0;L;;;;;N;;;;; +14B9;CANADIAN SYLLABICS WEST-CREE MWAA;Lo;0;L;;;;;N;;;;; +14BA;CANADIAN SYLLABICS NASKAPI MWAA;Lo;0;L;;;;;N;;;;; +14BB;CANADIAN SYLLABICS M;Lo;0;L;;;;;N;;;;; +14BC;CANADIAN SYLLABICS WEST-CREE M;Lo;0;L;;;;;N;;;;; +14BD;CANADIAN SYLLABICS MH;Lo;0;L;;;;;N;;;;; +14BE;CANADIAN SYLLABICS ATHAPASCAN M;Lo;0;L;;;;;N;;;;; +14BF;CANADIAN SYLLABICS SAYISI M;Lo;0;L;;;;;N;;;;; +14C0;CANADIAN SYLLABICS NE;Lo;0;L;;;;;N;;;;; +14C1;CANADIAN SYLLABICS NAAI;Lo;0;L;;;;;N;;;;; +14C2;CANADIAN SYLLABICS NI;Lo;0;L;;;;;N;;;;; +14C3;CANADIAN SYLLABICS NII;Lo;0;L;;;;;N;;;;; +14C4;CANADIAN SYLLABICS NO;Lo;0;L;;;;;N;;;;; +14C5;CANADIAN SYLLABICS NOO;Lo;0;L;;;;;N;;;;; +14C6;CANADIAN SYLLABICS Y-CREE NOO;Lo;0;L;;;;;N;;;;; +14C7;CANADIAN SYLLABICS NA;Lo;0;L;;;;;N;;;;; +14C8;CANADIAN SYLLABICS NAA;Lo;0;L;;;;;N;;;;; +14C9;CANADIAN SYLLABICS NWE;Lo;0;L;;;;;N;;;;; +14CA;CANADIAN SYLLABICS WEST-CREE NWE;Lo;0;L;;;;;N;;;;; +14CB;CANADIAN SYLLABICS NWA;Lo;0;L;;;;;N;;;;; +14CC;CANADIAN SYLLABICS WEST-CREE NWA;Lo;0;L;;;;;N;;;;; +14CD;CANADIAN SYLLABICS NWAA;Lo;0;L;;;;;N;;;;; +14CE;CANADIAN SYLLABICS WEST-CREE NWAA;Lo;0;L;;;;;N;;;;; +14CF;CANADIAN SYLLABICS NASKAPI NWAA;Lo;0;L;;;;;N;;;;; +14D0;CANADIAN SYLLABICS N;Lo;0;L;;;;;N;;;;; +14D1;CANADIAN SYLLABICS CARRIER NG;Lo;0;L;;;;;N;;;;; +14D2;CANADIAN SYLLABICS NH;Lo;0;L;;;;;N;;;;; +14D3;CANADIAN SYLLABICS LE;Lo;0;L;;;;;N;;;;; +14D4;CANADIAN SYLLABICS LAAI;Lo;0;L;;;;;N;;;;; +14D5;CANADIAN SYLLABICS LI;Lo;0;L;;;;;N;;;;; +14D6;CANADIAN SYLLABICS LII;Lo;0;L;;;;;N;;;;; +14D7;CANADIAN SYLLABICS LO;Lo;0;L;;;;;N;;;;; +14D8;CANADIAN SYLLABICS LOO;Lo;0;L;;;;;N;;;;; +14D9;CANADIAN SYLLABICS Y-CREE LOO;Lo;0;L;;;;;N;;;;; +14DA;CANADIAN SYLLABICS LA;Lo;0;L;;;;;N;;;;; +14DB;CANADIAN SYLLABICS LAA;Lo;0;L;;;;;N;;;;; +14DC;CANADIAN SYLLABICS LWE;Lo;0;L;;;;;N;;;;; +14DD;CANADIAN SYLLABICS WEST-CREE LWE;Lo;0;L;;;;;N;;;;; +14DE;CANADIAN SYLLABICS LWI;Lo;0;L;;;;;N;;;;; +14DF;CANADIAN SYLLABICS WEST-CREE LWI;Lo;0;L;;;;;N;;;;; +14E0;CANADIAN SYLLABICS LWII;Lo;0;L;;;;;N;;;;; +14E1;CANADIAN SYLLABICS WEST-CREE LWII;Lo;0;L;;;;;N;;;;; +14E2;CANADIAN SYLLABICS LWO;Lo;0;L;;;;;N;;;;; +14E3;CANADIAN SYLLABICS WEST-CREE LWO;Lo;0;L;;;;;N;;;;; +14E4;CANADIAN SYLLABICS LWOO;Lo;0;L;;;;;N;;;;; +14E5;CANADIAN SYLLABICS WEST-CREE LWOO;Lo;0;L;;;;;N;;;;; +14E6;CANADIAN SYLLABICS LWA;Lo;0;L;;;;;N;;;;; +14E7;CANADIAN SYLLABICS WEST-CREE LWA;Lo;0;L;;;;;N;;;;; +14E8;CANADIAN SYLLABICS LWAA;Lo;0;L;;;;;N;;;;; +14E9;CANADIAN SYLLABICS WEST-CREE LWAA;Lo;0;L;;;;;N;;;;; +14EA;CANADIAN SYLLABICS L;Lo;0;L;;;;;N;;;;; +14EB;CANADIAN SYLLABICS WEST-CREE L;Lo;0;L;;;;;N;;;;; +14EC;CANADIAN SYLLABICS MEDIAL L;Lo;0;L;;;;;N;;;;; +14ED;CANADIAN SYLLABICS SE;Lo;0;L;;;;;N;;;;; +14EE;CANADIAN SYLLABICS SAAI;Lo;0;L;;;;;N;;;;; +14EF;CANADIAN SYLLABICS SI;Lo;0;L;;;;;N;;;;; +14F0;CANADIAN SYLLABICS SII;Lo;0;L;;;;;N;;;;; +14F1;CANADIAN SYLLABICS SO;Lo;0;L;;;;;N;;;;; +14F2;CANADIAN SYLLABICS SOO;Lo;0;L;;;;;N;;;;; +14F3;CANADIAN SYLLABICS Y-CREE SOO;Lo;0;L;;;;;N;;;;; +14F4;CANADIAN SYLLABICS SA;Lo;0;L;;;;;N;;;;; +14F5;CANADIAN SYLLABICS SAA;Lo;0;L;;;;;N;;;;; +14F6;CANADIAN SYLLABICS SWE;Lo;0;L;;;;;N;;;;; +14F7;CANADIAN SYLLABICS WEST-CREE SWE;Lo;0;L;;;;;N;;;;; +14F8;CANADIAN SYLLABICS SWI;Lo;0;L;;;;;N;;;;; +14F9;CANADIAN SYLLABICS WEST-CREE SWI;Lo;0;L;;;;;N;;;;; +14FA;CANADIAN SYLLABICS SWII;Lo;0;L;;;;;N;;;;; +14FB;CANADIAN SYLLABICS WEST-CREE SWII;Lo;0;L;;;;;N;;;;; +14FC;CANADIAN SYLLABICS SWO;Lo;0;L;;;;;N;;;;; +14FD;CANADIAN SYLLABICS WEST-CREE SWO;Lo;0;L;;;;;N;;;;; +14FE;CANADIAN SYLLABICS SWOO;Lo;0;L;;;;;N;;;;; +14FF;CANADIAN SYLLABICS WEST-CREE SWOO;Lo;0;L;;;;;N;;;;; +1500;CANADIAN SYLLABICS SWA;Lo;0;L;;;;;N;;;;; +1501;CANADIAN SYLLABICS WEST-CREE SWA;Lo;0;L;;;;;N;;;;; +1502;CANADIAN SYLLABICS SWAA;Lo;0;L;;;;;N;;;;; +1503;CANADIAN SYLLABICS WEST-CREE SWAA;Lo;0;L;;;;;N;;;;; +1504;CANADIAN SYLLABICS NASKAPI SWAA;Lo;0;L;;;;;N;;;;; +1505;CANADIAN SYLLABICS S;Lo;0;L;;;;;N;;;;; +1506;CANADIAN SYLLABICS ATHAPASCAN S;Lo;0;L;;;;;N;;;;; +1507;CANADIAN SYLLABICS SW;Lo;0;L;;;;;N;;;;; +1508;CANADIAN SYLLABICS BLACKFOOT S;Lo;0;L;;;;;N;;;;; +1509;CANADIAN SYLLABICS MOOSE-CREE SK;Lo;0;L;;;;;N;;;;; +150A;CANADIAN SYLLABICS NASKAPI SKW;Lo;0;L;;;;;N;;;;; +150B;CANADIAN SYLLABICS NASKAPI S-W;Lo;0;L;;;;;N;;;;; +150C;CANADIAN SYLLABICS NASKAPI SPWA;Lo;0;L;;;;;N;;;;; +150D;CANADIAN SYLLABICS NASKAPI STWA;Lo;0;L;;;;;N;;;;; +150E;CANADIAN SYLLABICS NASKAPI SKWA;Lo;0;L;;;;;N;;;;; +150F;CANADIAN SYLLABICS NASKAPI SCWA;Lo;0;L;;;;;N;;;;; +1510;CANADIAN SYLLABICS SHE;Lo;0;L;;;;;N;;;;; +1511;CANADIAN SYLLABICS SHI;Lo;0;L;;;;;N;;;;; +1512;CANADIAN SYLLABICS SHII;Lo;0;L;;;;;N;;;;; +1513;CANADIAN SYLLABICS SHO;Lo;0;L;;;;;N;;;;; +1514;CANADIAN SYLLABICS SHOO;Lo;0;L;;;;;N;;;;; +1515;CANADIAN SYLLABICS SHA;Lo;0;L;;;;;N;;;;; +1516;CANADIAN SYLLABICS SHAA;Lo;0;L;;;;;N;;;;; +1517;CANADIAN SYLLABICS SHWE;Lo;0;L;;;;;N;;;;; +1518;CANADIAN SYLLABICS WEST-CREE SHWE;Lo;0;L;;;;;N;;;;; +1519;CANADIAN SYLLABICS SHWI;Lo;0;L;;;;;N;;;;; +151A;CANADIAN SYLLABICS WEST-CREE SHWI;Lo;0;L;;;;;N;;;;; +151B;CANADIAN SYLLABICS SHWII;Lo;0;L;;;;;N;;;;; +151C;CANADIAN SYLLABICS WEST-CREE SHWII;Lo;0;L;;;;;N;;;;; +151D;CANADIAN SYLLABICS SHWO;Lo;0;L;;;;;N;;;;; +151E;CANADIAN SYLLABICS WEST-CREE SHWO;Lo;0;L;;;;;N;;;;; +151F;CANADIAN SYLLABICS SHWOO;Lo;0;L;;;;;N;;;;; +1520;CANADIAN SYLLABICS WEST-CREE SHWOO;Lo;0;L;;;;;N;;;;; +1521;CANADIAN SYLLABICS SHWA;Lo;0;L;;;;;N;;;;; +1522;CANADIAN SYLLABICS WEST-CREE SHWA;Lo;0;L;;;;;N;;;;; +1523;CANADIAN SYLLABICS SHWAA;Lo;0;L;;;;;N;;;;; +1524;CANADIAN SYLLABICS WEST-CREE SHWAA;Lo;0;L;;;;;N;;;;; +1525;CANADIAN SYLLABICS SH;Lo;0;L;;;;;N;;;;; +1526;CANADIAN SYLLABICS YE;Lo;0;L;;;;;N;;;;; +1527;CANADIAN SYLLABICS YAAI;Lo;0;L;;;;;N;;;;; +1528;CANADIAN SYLLABICS YI;Lo;0;L;;;;;N;;;;; +1529;CANADIAN SYLLABICS YII;Lo;0;L;;;;;N;;;;; +152A;CANADIAN SYLLABICS YO;Lo;0;L;;;;;N;;;;; +152B;CANADIAN SYLLABICS YOO;Lo;0;L;;;;;N;;;;; +152C;CANADIAN SYLLABICS Y-CREE YOO;Lo;0;L;;;;;N;;;;; +152D;CANADIAN SYLLABICS YA;Lo;0;L;;;;;N;;;;; +152E;CANADIAN SYLLABICS YAA;Lo;0;L;;;;;N;;;;; +152F;CANADIAN SYLLABICS YWE;Lo;0;L;;;;;N;;;;; +1530;CANADIAN SYLLABICS WEST-CREE YWE;Lo;0;L;;;;;N;;;;; +1531;CANADIAN SYLLABICS YWI;Lo;0;L;;;;;N;;;;; +1532;CANADIAN SYLLABICS WEST-CREE YWI;Lo;0;L;;;;;N;;;;; +1533;CANADIAN SYLLABICS YWII;Lo;0;L;;;;;N;;;;; +1534;CANADIAN SYLLABICS WEST-CREE YWII;Lo;0;L;;;;;N;;;;; +1535;CANADIAN SYLLABICS YWO;Lo;0;L;;;;;N;;;;; +1536;CANADIAN SYLLABICS WEST-CREE YWO;Lo;0;L;;;;;N;;;;; +1537;CANADIAN SYLLABICS YWOO;Lo;0;L;;;;;N;;;;; +1538;CANADIAN SYLLABICS WEST-CREE YWOO;Lo;0;L;;;;;N;;;;; +1539;CANADIAN SYLLABICS YWA;Lo;0;L;;;;;N;;;;; +153A;CANADIAN SYLLABICS WEST-CREE YWA;Lo;0;L;;;;;N;;;;; +153B;CANADIAN SYLLABICS YWAA;Lo;0;L;;;;;N;;;;; +153C;CANADIAN SYLLABICS WEST-CREE YWAA;Lo;0;L;;;;;N;;;;; +153D;CANADIAN SYLLABICS NASKAPI YWAA;Lo;0;L;;;;;N;;;;; +153E;CANADIAN SYLLABICS Y;Lo;0;L;;;;;N;;;;; +153F;CANADIAN SYLLABICS BIBLE-CREE Y;Lo;0;L;;;;;N;;;;; +1540;CANADIAN SYLLABICS WEST-CREE Y;Lo;0;L;;;;;N;;;;; +1541;CANADIAN SYLLABICS SAYISI YI;Lo;0;L;;;;;N;;;;; +1542;CANADIAN SYLLABICS RE;Lo;0;L;;;;;N;;;;; +1543;CANADIAN SYLLABICS R-CREE RE;Lo;0;L;;;;;N;;;;; +1544;CANADIAN SYLLABICS WEST-CREE LE;Lo;0;L;;;;;N;;;;; +1545;CANADIAN SYLLABICS RAAI;Lo;0;L;;;;;N;;;;; +1546;CANADIAN SYLLABICS RI;Lo;0;L;;;;;N;;;;; +1547;CANADIAN SYLLABICS RII;Lo;0;L;;;;;N;;;;; +1548;CANADIAN SYLLABICS RO;Lo;0;L;;;;;N;;;;; +1549;CANADIAN SYLLABICS ROO;Lo;0;L;;;;;N;;;;; +154A;CANADIAN SYLLABICS WEST-CREE LO;Lo;0;L;;;;;N;;;;; +154B;CANADIAN SYLLABICS RA;Lo;0;L;;;;;N;;;;; +154C;CANADIAN SYLLABICS RAA;Lo;0;L;;;;;N;;;;; +154D;CANADIAN SYLLABICS WEST-CREE LA;Lo;0;L;;;;;N;;;;; +154E;CANADIAN SYLLABICS RWAA;Lo;0;L;;;;;N;;;;; +154F;CANADIAN SYLLABICS WEST-CREE RWAA;Lo;0;L;;;;;N;;;;; +1550;CANADIAN SYLLABICS R;Lo;0;L;;;;;N;;;;; +1551;CANADIAN SYLLABICS WEST-CREE R;Lo;0;L;;;;;N;;;;; +1552;CANADIAN SYLLABICS MEDIAL R;Lo;0;L;;;;;N;;;;; +1553;CANADIAN SYLLABICS FE;Lo;0;L;;;;;N;;;;; +1554;CANADIAN SYLLABICS FAAI;Lo;0;L;;;;;N;;;;; +1555;CANADIAN SYLLABICS FI;Lo;0;L;;;;;N;;;;; +1556;CANADIAN SYLLABICS FII;Lo;0;L;;;;;N;;;;; +1557;CANADIAN SYLLABICS FO;Lo;0;L;;;;;N;;;;; +1558;CANADIAN SYLLABICS FOO;Lo;0;L;;;;;N;;;;; +1559;CANADIAN SYLLABICS FA;Lo;0;L;;;;;N;;;;; +155A;CANADIAN SYLLABICS FAA;Lo;0;L;;;;;N;;;;; +155B;CANADIAN SYLLABICS FWAA;Lo;0;L;;;;;N;;;;; +155C;CANADIAN SYLLABICS WEST-CREE FWAA;Lo;0;L;;;;;N;;;;; +155D;CANADIAN SYLLABICS F;Lo;0;L;;;;;N;;;;; +155E;CANADIAN SYLLABICS THE;Lo;0;L;;;;;N;;;;; +155F;CANADIAN SYLLABICS N-CREE THE;Lo;0;L;;;;;N;;;;; +1560;CANADIAN SYLLABICS THI;Lo;0;L;;;;;N;;;;; +1561;CANADIAN SYLLABICS N-CREE THI;Lo;0;L;;;;;N;;;;; +1562;CANADIAN SYLLABICS THII;Lo;0;L;;;;;N;;;;; +1563;CANADIAN SYLLABICS N-CREE THII;Lo;0;L;;;;;N;;;;; +1564;CANADIAN SYLLABICS THO;Lo;0;L;;;;;N;;;;; +1565;CANADIAN SYLLABICS THOO;Lo;0;L;;;;;N;;;;; +1566;CANADIAN SYLLABICS THA;Lo;0;L;;;;;N;;;;; +1567;CANADIAN SYLLABICS THAA;Lo;0;L;;;;;N;;;;; +1568;CANADIAN SYLLABICS THWAA;Lo;0;L;;;;;N;;;;; +1569;CANADIAN SYLLABICS WEST-CREE THWAA;Lo;0;L;;;;;N;;;;; +156A;CANADIAN SYLLABICS TH;Lo;0;L;;;;;N;;;;; +156B;CANADIAN SYLLABICS TTHE;Lo;0;L;;;;;N;;;;; +156C;CANADIAN SYLLABICS TTHI;Lo;0;L;;;;;N;;;;; +156D;CANADIAN SYLLABICS TTHO;Lo;0;L;;;;;N;;;;; +156E;CANADIAN SYLLABICS TTHA;Lo;0;L;;;;;N;;;;; +156F;CANADIAN SYLLABICS TTH;Lo;0;L;;;;;N;;;;; +1570;CANADIAN SYLLABICS TYE;Lo;0;L;;;;;N;;;;; +1571;CANADIAN SYLLABICS TYI;Lo;0;L;;;;;N;;;;; +1572;CANADIAN SYLLABICS TYO;Lo;0;L;;;;;N;;;;; +1573;CANADIAN SYLLABICS TYA;Lo;0;L;;;;;N;;;;; +1574;CANADIAN SYLLABICS NUNAVIK HE;Lo;0;L;;;;;N;;;;; +1575;CANADIAN SYLLABICS NUNAVIK HI;Lo;0;L;;;;;N;;;;; +1576;CANADIAN SYLLABICS NUNAVIK HII;Lo;0;L;;;;;N;;;;; +1577;CANADIAN SYLLABICS NUNAVIK HO;Lo;0;L;;;;;N;;;;; +1578;CANADIAN SYLLABICS NUNAVIK HOO;Lo;0;L;;;;;N;;;;; +1579;CANADIAN SYLLABICS NUNAVIK HA;Lo;0;L;;;;;N;;;;; +157A;CANADIAN SYLLABICS NUNAVIK HAA;Lo;0;L;;;;;N;;;;; +157B;CANADIAN SYLLABICS NUNAVIK H;Lo;0;L;;;;;N;;;;; +157C;CANADIAN SYLLABICS NUNAVUT H;Lo;0;L;;;;;N;;;;; +157D;CANADIAN SYLLABICS HK;Lo;0;L;;;;;N;;;;; +157E;CANADIAN SYLLABICS QAAI;Lo;0;L;;;;;N;;;;; +157F;CANADIAN SYLLABICS QI;Lo;0;L;;;;;N;;;;; +1580;CANADIAN SYLLABICS QII;Lo;0;L;;;;;N;;;;; +1581;CANADIAN SYLLABICS QO;Lo;0;L;;;;;N;;;;; +1582;CANADIAN SYLLABICS QOO;Lo;0;L;;;;;N;;;;; +1583;CANADIAN SYLLABICS QA;Lo;0;L;;;;;N;;;;; +1584;CANADIAN SYLLABICS QAA;Lo;0;L;;;;;N;;;;; +1585;CANADIAN SYLLABICS Q;Lo;0;L;;;;;N;;;;; +1586;CANADIAN SYLLABICS TLHE;Lo;0;L;;;;;N;;;;; +1587;CANADIAN SYLLABICS TLHI;Lo;0;L;;;;;N;;;;; +1588;CANADIAN SYLLABICS TLHO;Lo;0;L;;;;;N;;;;; +1589;CANADIAN SYLLABICS TLHA;Lo;0;L;;;;;N;;;;; +158A;CANADIAN SYLLABICS WEST-CREE RE;Lo;0;L;;;;;N;;;;; +158B;CANADIAN SYLLABICS WEST-CREE RI;Lo;0;L;;;;;N;;;;; +158C;CANADIAN SYLLABICS WEST-CREE RO;Lo;0;L;;;;;N;;;;; +158D;CANADIAN SYLLABICS WEST-CREE RA;Lo;0;L;;;;;N;;;;; +158E;CANADIAN SYLLABICS NGAAI;Lo;0;L;;;;;N;;;;; +158F;CANADIAN SYLLABICS NGI;Lo;0;L;;;;;N;;;;; +1590;CANADIAN SYLLABICS NGII;Lo;0;L;;;;;N;;;;; +1591;CANADIAN SYLLABICS NGO;Lo;0;L;;;;;N;;;;; +1592;CANADIAN SYLLABICS NGOO;Lo;0;L;;;;;N;;;;; +1593;CANADIAN SYLLABICS NGA;Lo;0;L;;;;;N;;;;; +1594;CANADIAN SYLLABICS NGAA;Lo;0;L;;;;;N;;;;; +1595;CANADIAN SYLLABICS NG;Lo;0;L;;;;;N;;;;; +1596;CANADIAN SYLLABICS NNG;Lo;0;L;;;;;N;;;;; +1597;CANADIAN SYLLABICS SAYISI SHE;Lo;0;L;;;;;N;;;;; +1598;CANADIAN SYLLABICS SAYISI SHI;Lo;0;L;;;;;N;;;;; +1599;CANADIAN SYLLABICS SAYISI SHO;Lo;0;L;;;;;N;;;;; +159A;CANADIAN SYLLABICS SAYISI SHA;Lo;0;L;;;;;N;;;;; +159B;CANADIAN SYLLABICS WOODS-CREE THE;Lo;0;L;;;;;N;;;;; +159C;CANADIAN SYLLABICS WOODS-CREE THI;Lo;0;L;;;;;N;;;;; +159D;CANADIAN SYLLABICS WOODS-CREE THO;Lo;0;L;;;;;N;;;;; +159E;CANADIAN SYLLABICS WOODS-CREE THA;Lo;0;L;;;;;N;;;;; +159F;CANADIAN SYLLABICS WOODS-CREE TH;Lo;0;L;;;;;N;;;;; +15A0;CANADIAN SYLLABICS LHI;Lo;0;L;;;;;N;;;;; +15A1;CANADIAN SYLLABICS LHII;Lo;0;L;;;;;N;;;;; +15A2;CANADIAN SYLLABICS LHO;Lo;0;L;;;;;N;;;;; +15A3;CANADIAN SYLLABICS LHOO;Lo;0;L;;;;;N;;;;; +15A4;CANADIAN SYLLABICS LHA;Lo;0;L;;;;;N;;;;; +15A5;CANADIAN SYLLABICS LHAA;Lo;0;L;;;;;N;;;;; +15A6;CANADIAN SYLLABICS LH;Lo;0;L;;;;;N;;;;; +15A7;CANADIAN SYLLABICS TH-CREE THE;Lo;0;L;;;;;N;;;;; +15A8;CANADIAN SYLLABICS TH-CREE THI;Lo;0;L;;;;;N;;;;; +15A9;CANADIAN SYLLABICS TH-CREE THII;Lo;0;L;;;;;N;;;;; +15AA;CANADIAN SYLLABICS TH-CREE THO;Lo;0;L;;;;;N;;;;; +15AB;CANADIAN SYLLABICS TH-CREE THOO;Lo;0;L;;;;;N;;;;; +15AC;CANADIAN SYLLABICS TH-CREE THA;Lo;0;L;;;;;N;;;;; +15AD;CANADIAN SYLLABICS TH-CREE THAA;Lo;0;L;;;;;N;;;;; +15AE;CANADIAN SYLLABICS TH-CREE TH;Lo;0;L;;;;;N;;;;; +15AF;CANADIAN SYLLABICS AIVILIK B;Lo;0;L;;;;;N;;;;; +15B0;CANADIAN SYLLABICS BLACKFOOT E;Lo;0;L;;;;;N;;;;; +15B1;CANADIAN SYLLABICS BLACKFOOT I;Lo;0;L;;;;;N;;;;; +15B2;CANADIAN SYLLABICS BLACKFOOT O;Lo;0;L;;;;;N;;;;; +15B3;CANADIAN SYLLABICS BLACKFOOT A;Lo;0;L;;;;;N;;;;; +15B4;CANADIAN SYLLABICS BLACKFOOT WE;Lo;0;L;;;;;N;;;;; +15B5;CANADIAN SYLLABICS BLACKFOOT WI;Lo;0;L;;;;;N;;;;; +15B6;CANADIAN SYLLABICS BLACKFOOT WO;Lo;0;L;;;;;N;;;;; +15B7;CANADIAN SYLLABICS BLACKFOOT WA;Lo;0;L;;;;;N;;;;; +15B8;CANADIAN SYLLABICS BLACKFOOT NE;Lo;0;L;;;;;N;;;;; +15B9;CANADIAN SYLLABICS BLACKFOOT NI;Lo;0;L;;;;;N;;;;; +15BA;CANADIAN SYLLABICS BLACKFOOT NO;Lo;0;L;;;;;N;;;;; +15BB;CANADIAN SYLLABICS BLACKFOOT NA;Lo;0;L;;;;;N;;;;; +15BC;CANADIAN SYLLABICS BLACKFOOT KE;Lo;0;L;;;;;N;;;;; +15BD;CANADIAN SYLLABICS BLACKFOOT KI;Lo;0;L;;;;;N;;;;; +15BE;CANADIAN SYLLABICS BLACKFOOT KO;Lo;0;L;;;;;N;;;;; +15BF;CANADIAN SYLLABICS BLACKFOOT KA;Lo;0;L;;;;;N;;;;; +15C0;CANADIAN SYLLABICS SAYISI HE;Lo;0;L;;;;;N;;;;; +15C1;CANADIAN SYLLABICS SAYISI HI;Lo;0;L;;;;;N;;;;; +15C2;CANADIAN SYLLABICS SAYISI HO;Lo;0;L;;;;;N;;;;; +15C3;CANADIAN SYLLABICS SAYISI HA;Lo;0;L;;;;;N;;;;; +15C4;CANADIAN SYLLABICS CARRIER GHU;Lo;0;L;;;;;N;;;;; +15C5;CANADIAN SYLLABICS CARRIER GHO;Lo;0;L;;;;;N;;;;; +15C6;CANADIAN SYLLABICS CARRIER GHE;Lo;0;L;;;;;N;;;;; +15C7;CANADIAN SYLLABICS CARRIER GHEE;Lo;0;L;;;;;N;;;;; +15C8;CANADIAN SYLLABICS CARRIER GHI;Lo;0;L;;;;;N;;;;; +15C9;CANADIAN SYLLABICS CARRIER GHA;Lo;0;L;;;;;N;;;;; +15CA;CANADIAN SYLLABICS CARRIER RU;Lo;0;L;;;;;N;;;;; +15CB;CANADIAN SYLLABICS CARRIER RO;Lo;0;L;;;;;N;;;;; +15CC;CANADIAN SYLLABICS CARRIER RE;Lo;0;L;;;;;N;;;;; +15CD;CANADIAN SYLLABICS CARRIER REE;Lo;0;L;;;;;N;;;;; +15CE;CANADIAN SYLLABICS CARRIER RI;Lo;0;L;;;;;N;;;;; +15CF;CANADIAN SYLLABICS CARRIER RA;Lo;0;L;;;;;N;;;;; +15D0;CANADIAN SYLLABICS CARRIER WU;Lo;0;L;;;;;N;;;;; +15D1;CANADIAN SYLLABICS CARRIER WO;Lo;0;L;;;;;N;;;;; +15D2;CANADIAN SYLLABICS CARRIER WE;Lo;0;L;;;;;N;;;;; +15D3;CANADIAN SYLLABICS CARRIER WEE;Lo;0;L;;;;;N;;;;; +15D4;CANADIAN SYLLABICS CARRIER WI;Lo;0;L;;;;;N;;;;; +15D5;CANADIAN SYLLABICS CARRIER WA;Lo;0;L;;;;;N;;;;; +15D6;CANADIAN SYLLABICS CARRIER HWU;Lo;0;L;;;;;N;;;;; +15D7;CANADIAN SYLLABICS CARRIER HWO;Lo;0;L;;;;;N;;;;; +15D8;CANADIAN SYLLABICS CARRIER HWE;Lo;0;L;;;;;N;;;;; +15D9;CANADIAN SYLLABICS CARRIER HWEE;Lo;0;L;;;;;N;;;;; +15DA;CANADIAN SYLLABICS CARRIER HWI;Lo;0;L;;;;;N;;;;; +15DB;CANADIAN SYLLABICS CARRIER HWA;Lo;0;L;;;;;N;;;;; +15DC;CANADIAN SYLLABICS CARRIER THU;Lo;0;L;;;;;N;;;;; +15DD;CANADIAN SYLLABICS CARRIER THO;Lo;0;L;;;;;N;;;;; +15DE;CANADIAN SYLLABICS CARRIER THE;Lo;0;L;;;;;N;;;;; +15DF;CANADIAN SYLLABICS CARRIER THEE;Lo;0;L;;;;;N;;;;; +15E0;CANADIAN SYLLABICS CARRIER THI;Lo;0;L;;;;;N;;;;; +15E1;CANADIAN SYLLABICS CARRIER THA;Lo;0;L;;;;;N;;;;; +15E2;CANADIAN SYLLABICS CARRIER TTU;Lo;0;L;;;;;N;;;;; +15E3;CANADIAN SYLLABICS CARRIER TTO;Lo;0;L;;;;;N;;;;; +15E4;CANADIAN SYLLABICS CARRIER TTE;Lo;0;L;;;;;N;;;;; +15E5;CANADIAN SYLLABICS CARRIER TTEE;Lo;0;L;;;;;N;;;;; +15E6;CANADIAN SYLLABICS CARRIER TTI;Lo;0;L;;;;;N;;;;; +15E7;CANADIAN SYLLABICS CARRIER TTA;Lo;0;L;;;;;N;;;;; +15E8;CANADIAN SYLLABICS CARRIER PU;Lo;0;L;;;;;N;;;;; +15E9;CANADIAN SYLLABICS CARRIER PO;Lo;0;L;;;;;N;;;;; +15EA;CANADIAN SYLLABICS CARRIER PE;Lo;0;L;;;;;N;;;;; +15EB;CANADIAN SYLLABICS CARRIER PEE;Lo;0;L;;;;;N;;;;; +15EC;CANADIAN SYLLABICS CARRIER PI;Lo;0;L;;;;;N;;;;; +15ED;CANADIAN SYLLABICS CARRIER PA;Lo;0;L;;;;;N;;;;; +15EE;CANADIAN SYLLABICS CARRIER P;Lo;0;L;;;;;N;;;;; +15EF;CANADIAN SYLLABICS CARRIER GU;Lo;0;L;;;;;N;;;;; +15F0;CANADIAN SYLLABICS CARRIER GO;Lo;0;L;;;;;N;;;;; +15F1;CANADIAN SYLLABICS CARRIER GE;Lo;0;L;;;;;N;;;;; +15F2;CANADIAN SYLLABICS CARRIER GEE;Lo;0;L;;;;;N;;;;; +15F3;CANADIAN SYLLABICS CARRIER GI;Lo;0;L;;;;;N;;;;; +15F4;CANADIAN SYLLABICS CARRIER GA;Lo;0;L;;;;;N;;;;; +15F5;CANADIAN SYLLABICS CARRIER KHU;Lo;0;L;;;;;N;;;;; +15F6;CANADIAN SYLLABICS CARRIER KHO;Lo;0;L;;;;;N;;;;; +15F7;CANADIAN SYLLABICS CARRIER KHE;Lo;0;L;;;;;N;;;;; +15F8;CANADIAN SYLLABICS CARRIER KHEE;Lo;0;L;;;;;N;;;;; +15F9;CANADIAN SYLLABICS CARRIER KHI;Lo;0;L;;;;;N;;;;; +15FA;CANADIAN SYLLABICS CARRIER KHA;Lo;0;L;;;;;N;;;;; +15FB;CANADIAN SYLLABICS CARRIER KKU;Lo;0;L;;;;;N;;;;; +15FC;CANADIAN SYLLABICS CARRIER KKO;Lo;0;L;;;;;N;;;;; +15FD;CANADIAN SYLLABICS CARRIER KKE;Lo;0;L;;;;;N;;;;; +15FE;CANADIAN SYLLABICS CARRIER KKEE;Lo;0;L;;;;;N;;;;; +15FF;CANADIAN SYLLABICS CARRIER KKI;Lo;0;L;;;;;N;;;;; +1600;CANADIAN SYLLABICS CARRIER KKA;Lo;0;L;;;;;N;;;;; +1601;CANADIAN SYLLABICS CARRIER KK;Lo;0;L;;;;;N;;;;; +1602;CANADIAN SYLLABICS CARRIER NU;Lo;0;L;;;;;N;;;;; +1603;CANADIAN SYLLABICS CARRIER NO;Lo;0;L;;;;;N;;;;; +1604;CANADIAN SYLLABICS CARRIER NE;Lo;0;L;;;;;N;;;;; +1605;CANADIAN SYLLABICS CARRIER NEE;Lo;0;L;;;;;N;;;;; +1606;CANADIAN SYLLABICS CARRIER NI;Lo;0;L;;;;;N;;;;; +1607;CANADIAN SYLLABICS CARRIER NA;Lo;0;L;;;;;N;;;;; +1608;CANADIAN SYLLABICS CARRIER MU;Lo;0;L;;;;;N;;;;; +1609;CANADIAN SYLLABICS CARRIER MO;Lo;0;L;;;;;N;;;;; +160A;CANADIAN SYLLABICS CARRIER ME;Lo;0;L;;;;;N;;;;; +160B;CANADIAN SYLLABICS CARRIER MEE;Lo;0;L;;;;;N;;;;; +160C;CANADIAN SYLLABICS CARRIER MI;Lo;0;L;;;;;N;;;;; +160D;CANADIAN SYLLABICS CARRIER MA;Lo;0;L;;;;;N;;;;; +160E;CANADIAN SYLLABICS CARRIER YU;Lo;0;L;;;;;N;;;;; +160F;CANADIAN SYLLABICS CARRIER YO;Lo;0;L;;;;;N;;;;; +1610;CANADIAN SYLLABICS CARRIER YE;Lo;0;L;;;;;N;;;;; +1611;CANADIAN SYLLABICS CARRIER YEE;Lo;0;L;;;;;N;;;;; +1612;CANADIAN SYLLABICS CARRIER YI;Lo;0;L;;;;;N;;;;; +1613;CANADIAN SYLLABICS CARRIER YA;Lo;0;L;;;;;N;;;;; +1614;CANADIAN SYLLABICS CARRIER JU;Lo;0;L;;;;;N;;;;; +1615;CANADIAN SYLLABICS SAYISI JU;Lo;0;L;;;;;N;;;;; +1616;CANADIAN SYLLABICS CARRIER JO;Lo;0;L;;;;;N;;;;; +1617;CANADIAN SYLLABICS CARRIER JE;Lo;0;L;;;;;N;;;;; +1618;CANADIAN SYLLABICS CARRIER JEE;Lo;0;L;;;;;N;;;;; +1619;CANADIAN SYLLABICS CARRIER JI;Lo;0;L;;;;;N;;;;; +161A;CANADIAN SYLLABICS SAYISI JI;Lo;0;L;;;;;N;;;;; +161B;CANADIAN SYLLABICS CARRIER JA;Lo;0;L;;;;;N;;;;; +161C;CANADIAN SYLLABICS CARRIER JJU;Lo;0;L;;;;;N;;;;; +161D;CANADIAN SYLLABICS CARRIER JJO;Lo;0;L;;;;;N;;;;; +161E;CANADIAN SYLLABICS CARRIER JJE;Lo;0;L;;;;;N;;;;; +161F;CANADIAN SYLLABICS CARRIER JJEE;Lo;0;L;;;;;N;;;;; +1620;CANADIAN SYLLABICS CARRIER JJI;Lo;0;L;;;;;N;;;;; +1621;CANADIAN SYLLABICS CARRIER JJA;Lo;0;L;;;;;N;;;;; +1622;CANADIAN SYLLABICS CARRIER LU;Lo;0;L;;;;;N;;;;; +1623;CANADIAN SYLLABICS CARRIER LO;Lo;0;L;;;;;N;;;;; +1624;CANADIAN SYLLABICS CARRIER LE;Lo;0;L;;;;;N;;;;; +1625;CANADIAN SYLLABICS CARRIER LEE;Lo;0;L;;;;;N;;;;; +1626;CANADIAN SYLLABICS CARRIER LI;Lo;0;L;;;;;N;;;;; +1627;CANADIAN SYLLABICS CARRIER LA;Lo;0;L;;;;;N;;;;; +1628;CANADIAN SYLLABICS CARRIER DLU;Lo;0;L;;;;;N;;;;; +1629;CANADIAN SYLLABICS CARRIER DLO;Lo;0;L;;;;;N;;;;; +162A;CANADIAN SYLLABICS CARRIER DLE;Lo;0;L;;;;;N;;;;; +162B;CANADIAN SYLLABICS CARRIER DLEE;Lo;0;L;;;;;N;;;;; +162C;CANADIAN SYLLABICS CARRIER DLI;Lo;0;L;;;;;N;;;;; +162D;CANADIAN SYLLABICS CARRIER DLA;Lo;0;L;;;;;N;;;;; +162E;CANADIAN SYLLABICS CARRIER LHU;Lo;0;L;;;;;N;;;;; +162F;CANADIAN SYLLABICS CARRIER LHO;Lo;0;L;;;;;N;;;;; +1630;CANADIAN SYLLABICS CARRIER LHE;Lo;0;L;;;;;N;;;;; +1631;CANADIAN SYLLABICS CARRIER LHEE;Lo;0;L;;;;;N;;;;; +1632;CANADIAN SYLLABICS CARRIER LHI;Lo;0;L;;;;;N;;;;; +1633;CANADIAN SYLLABICS CARRIER LHA;Lo;0;L;;;;;N;;;;; +1634;CANADIAN SYLLABICS CARRIER TLHU;Lo;0;L;;;;;N;;;;; +1635;CANADIAN SYLLABICS CARRIER TLHO;Lo;0;L;;;;;N;;;;; +1636;CANADIAN SYLLABICS CARRIER TLHE;Lo;0;L;;;;;N;;;;; +1637;CANADIAN SYLLABICS CARRIER TLHEE;Lo;0;L;;;;;N;;;;; +1638;CANADIAN SYLLABICS CARRIER TLHI;Lo;0;L;;;;;N;;;;; +1639;CANADIAN SYLLABICS CARRIER TLHA;Lo;0;L;;;;;N;;;;; +163A;CANADIAN SYLLABICS CARRIER TLU;Lo;0;L;;;;;N;;;;; +163B;CANADIAN SYLLABICS CARRIER TLO;Lo;0;L;;;;;N;;;;; +163C;CANADIAN SYLLABICS CARRIER TLE;Lo;0;L;;;;;N;;;;; +163D;CANADIAN SYLLABICS CARRIER TLEE;Lo;0;L;;;;;N;;;;; +163E;CANADIAN SYLLABICS CARRIER TLI;Lo;0;L;;;;;N;;;;; +163F;CANADIAN SYLLABICS CARRIER TLA;Lo;0;L;;;;;N;;;;; +1640;CANADIAN SYLLABICS CARRIER ZU;Lo;0;L;;;;;N;;;;; +1641;CANADIAN SYLLABICS CARRIER ZO;Lo;0;L;;;;;N;;;;; +1642;CANADIAN SYLLABICS CARRIER ZE;Lo;0;L;;;;;N;;;;; +1643;CANADIAN SYLLABICS CARRIER ZEE;Lo;0;L;;;;;N;;;;; +1644;CANADIAN SYLLABICS CARRIER ZI;Lo;0;L;;;;;N;;;;; +1645;CANADIAN SYLLABICS CARRIER ZA;Lo;0;L;;;;;N;;;;; +1646;CANADIAN SYLLABICS CARRIER Z;Lo;0;L;;;;;N;;;;; +1647;CANADIAN SYLLABICS CARRIER INITIAL Z;Lo;0;L;;;;;N;;;;; +1648;CANADIAN SYLLABICS CARRIER DZU;Lo;0;L;;;;;N;;;;; +1649;CANADIAN SYLLABICS CARRIER DZO;Lo;0;L;;;;;N;;;;; +164A;CANADIAN SYLLABICS CARRIER DZE;Lo;0;L;;;;;N;;;;; +164B;CANADIAN SYLLABICS CARRIER DZEE;Lo;0;L;;;;;N;;;;; +164C;CANADIAN SYLLABICS CARRIER DZI;Lo;0;L;;;;;N;;;;; +164D;CANADIAN SYLLABICS CARRIER DZA;Lo;0;L;;;;;N;;;;; +164E;CANADIAN SYLLABICS CARRIER SU;Lo;0;L;;;;;N;;;;; +164F;CANADIAN SYLLABICS CARRIER SO;Lo;0;L;;;;;N;;;;; +1650;CANADIAN SYLLABICS CARRIER SE;Lo;0;L;;;;;N;;;;; +1651;CANADIAN SYLLABICS CARRIER SEE;Lo;0;L;;;;;N;;;;; +1652;CANADIAN SYLLABICS CARRIER SI;Lo;0;L;;;;;N;;;;; +1653;CANADIAN SYLLABICS CARRIER SA;Lo;0;L;;;;;N;;;;; +1654;CANADIAN SYLLABICS CARRIER SHU;Lo;0;L;;;;;N;;;;; +1655;CANADIAN SYLLABICS CARRIER SHO;Lo;0;L;;;;;N;;;;; +1656;CANADIAN SYLLABICS CARRIER SHE;Lo;0;L;;;;;N;;;;; +1657;CANADIAN SYLLABICS CARRIER SHEE;Lo;0;L;;;;;N;;;;; +1658;CANADIAN SYLLABICS CARRIER SHI;Lo;0;L;;;;;N;;;;; +1659;CANADIAN SYLLABICS CARRIER SHA;Lo;0;L;;;;;N;;;;; +165A;CANADIAN SYLLABICS CARRIER SH;Lo;0;L;;;;;N;;;;; +165B;CANADIAN SYLLABICS CARRIER TSU;Lo;0;L;;;;;N;;;;; +165C;CANADIAN SYLLABICS CARRIER TSO;Lo;0;L;;;;;N;;;;; +165D;CANADIAN SYLLABICS CARRIER TSE;Lo;0;L;;;;;N;;;;; +165E;CANADIAN SYLLABICS CARRIER TSEE;Lo;0;L;;;;;N;;;;; +165F;CANADIAN SYLLABICS CARRIER TSI;Lo;0;L;;;;;N;;;;; +1660;CANADIAN SYLLABICS CARRIER TSA;Lo;0;L;;;;;N;;;;; +1661;CANADIAN SYLLABICS CARRIER CHU;Lo;0;L;;;;;N;;;;; +1662;CANADIAN SYLLABICS CARRIER CHO;Lo;0;L;;;;;N;;;;; +1663;CANADIAN SYLLABICS CARRIER CHE;Lo;0;L;;;;;N;;;;; +1664;CANADIAN SYLLABICS CARRIER CHEE;Lo;0;L;;;;;N;;;;; +1665;CANADIAN SYLLABICS CARRIER CHI;Lo;0;L;;;;;N;;;;; +1666;CANADIAN SYLLABICS CARRIER CHA;Lo;0;L;;;;;N;;;;; +1667;CANADIAN SYLLABICS CARRIER TTSU;Lo;0;L;;;;;N;;;;; +1668;CANADIAN SYLLABICS CARRIER TTSO;Lo;0;L;;;;;N;;;;; +1669;CANADIAN SYLLABICS CARRIER TTSE;Lo;0;L;;;;;N;;;;; +166A;CANADIAN SYLLABICS CARRIER TTSEE;Lo;0;L;;;;;N;;;;; +166B;CANADIAN SYLLABICS CARRIER TTSI;Lo;0;L;;;;;N;;;;; +166C;CANADIAN SYLLABICS CARRIER TTSA;Lo;0;L;;;;;N;;;;; +166D;CANADIAN SYLLABICS CHI SIGN;Po;0;L;;;;;N;;;;; +166E;CANADIAN SYLLABICS FULL STOP;Po;0;L;;;;;N;;;;; +166F;CANADIAN SYLLABICS QAI;Lo;0;L;;;;;N;;;;; +1670;CANADIAN SYLLABICS NGAI;Lo;0;L;;;;;N;;;;; +1671;CANADIAN SYLLABICS NNGI;Lo;0;L;;;;;N;;;;; +1672;CANADIAN SYLLABICS NNGII;Lo;0;L;;;;;N;;;;; +1673;CANADIAN SYLLABICS NNGO;Lo;0;L;;;;;N;;;;; +1674;CANADIAN SYLLABICS NNGOO;Lo;0;L;;;;;N;;;;; +1675;CANADIAN SYLLABICS NNGA;Lo;0;L;;;;;N;;;;; +1676;CANADIAN SYLLABICS NNGAA;Lo;0;L;;;;;N;;;;; +1680;OGHAM SPACE MARK;Zs;0;WS;;;;;N;;;;; +1681;OGHAM LETTER BEITH;Lo;0;L;;;;;N;;;;; +1682;OGHAM LETTER LUIS;Lo;0;L;;;;;N;;;;; +1683;OGHAM LETTER FEARN;Lo;0;L;;;;;N;;;;; +1684;OGHAM LETTER SAIL;Lo;0;L;;;;;N;;;;; +1685;OGHAM LETTER NION;Lo;0;L;;;;;N;;;;; +1686;OGHAM LETTER UATH;Lo;0;L;;;;;N;;;;; +1687;OGHAM LETTER DAIR;Lo;0;L;;;;;N;;;;; +1688;OGHAM LETTER TINNE;Lo;0;L;;;;;N;;;;; +1689;OGHAM LETTER COLL;Lo;0;L;;;;;N;;;;; +168A;OGHAM LETTER CEIRT;Lo;0;L;;;;;N;;;;; +168B;OGHAM LETTER MUIN;Lo;0;L;;;;;N;;;;; +168C;OGHAM LETTER GORT;Lo;0;L;;;;;N;;;;; +168D;OGHAM LETTER NGEADAL;Lo;0;L;;;;;N;;;;; +168E;OGHAM LETTER STRAIF;Lo;0;L;;;;;N;;;;; +168F;OGHAM LETTER RUIS;Lo;0;L;;;;;N;;;;; +1690;OGHAM LETTER AILM;Lo;0;L;;;;;N;;;;; +1691;OGHAM LETTER ONN;Lo;0;L;;;;;N;;;;; +1692;OGHAM LETTER UR;Lo;0;L;;;;;N;;;;; +1693;OGHAM LETTER EADHADH;Lo;0;L;;;;;N;;;;; +1694;OGHAM LETTER IODHADH;Lo;0;L;;;;;N;;;;; +1695;OGHAM LETTER EABHADH;Lo;0;L;;;;;N;;;;; +1696;OGHAM LETTER OR;Lo;0;L;;;;;N;;;;; +1697;OGHAM LETTER UILLEANN;Lo;0;L;;;;;N;;;;; +1698;OGHAM LETTER IFIN;Lo;0;L;;;;;N;;;;; +1699;OGHAM LETTER EAMHANCHOLL;Lo;0;L;;;;;N;;;;; +169A;OGHAM LETTER PEITH;Lo;0;L;;;;;N;;;;; +169B;OGHAM FEATHER MARK;Ps;0;ON;;;;;N;;;;; +169C;OGHAM REVERSED FEATHER MARK;Pe;0;ON;;;;;N;;;;; +16A0;RUNIC LETTER FEHU FEOH FE F;Lo;0;L;;;;;N;;;;; +16A1;RUNIC LETTER V;Lo;0;L;;;;;N;;;;; +16A2;RUNIC LETTER URUZ UR U;Lo;0;L;;;;;N;;;;; +16A3;RUNIC LETTER YR;Lo;0;L;;;;;N;;;;; +16A4;RUNIC LETTER Y;Lo;0;L;;;;;N;;;;; +16A5;RUNIC LETTER W;Lo;0;L;;;;;N;;;;; +16A6;RUNIC LETTER THURISAZ THURS THORN;Lo;0;L;;;;;N;;;;; +16A7;RUNIC LETTER ETH;Lo;0;L;;;;;N;;;;; +16A8;RUNIC LETTER ANSUZ A;Lo;0;L;;;;;N;;;;; +16A9;RUNIC LETTER OS O;Lo;0;L;;;;;N;;;;; +16AA;RUNIC LETTER AC A;Lo;0;L;;;;;N;;;;; +16AB;RUNIC LETTER AESC;Lo;0;L;;;;;N;;;;; +16AC;RUNIC LETTER LONG-BRANCH-OSS O;Lo;0;L;;;;;N;;;;; +16AD;RUNIC LETTER SHORT-TWIG-OSS O;Lo;0;L;;;;;N;;;;; +16AE;RUNIC LETTER O;Lo;0;L;;;;;N;;;;; +16AF;RUNIC LETTER OE;Lo;0;L;;;;;N;;;;; +16B0;RUNIC LETTER ON;Lo;0;L;;;;;N;;;;; +16B1;RUNIC LETTER RAIDO RAD REID R;Lo;0;L;;;;;N;;;;; +16B2;RUNIC LETTER KAUNA;Lo;0;L;;;;;N;;;;; +16B3;RUNIC LETTER CEN;Lo;0;L;;;;;N;;;;; +16B4;RUNIC LETTER KAUN K;Lo;0;L;;;;;N;;;;; +16B5;RUNIC LETTER G;Lo;0;L;;;;;N;;;;; +16B6;RUNIC LETTER ENG;Lo;0;L;;;;;N;;;;; +16B7;RUNIC LETTER GEBO GYFU G;Lo;0;L;;;;;N;;;;; +16B8;RUNIC LETTER GAR;Lo;0;L;;;;;N;;;;; +16B9;RUNIC LETTER WUNJO WYNN W;Lo;0;L;;;;;N;;;;; +16BA;RUNIC LETTER HAGLAZ H;Lo;0;L;;;;;N;;;;; +16BB;RUNIC LETTER HAEGL H;Lo;0;L;;;;;N;;;;; +16BC;RUNIC LETTER LONG-BRANCH-HAGALL H;Lo;0;L;;;;;N;;;;; +16BD;RUNIC LETTER SHORT-TWIG-HAGALL H;Lo;0;L;;;;;N;;;;; +16BE;RUNIC LETTER NAUDIZ NYD NAUD N;Lo;0;L;;;;;N;;;;; +16BF;RUNIC LETTER SHORT-TWIG-NAUD N;Lo;0;L;;;;;N;;;;; +16C0;RUNIC LETTER DOTTED-N;Lo;0;L;;;;;N;;;;; +16C1;RUNIC LETTER ISAZ IS ISS I;Lo;0;L;;;;;N;;;;; +16C2;RUNIC LETTER E;Lo;0;L;;;;;N;;;;; +16C3;RUNIC LETTER JERAN J;Lo;0;L;;;;;N;;;;; +16C4;RUNIC LETTER GER;Lo;0;L;;;;;N;;;;; +16C5;RUNIC LETTER LONG-BRANCH-AR AE;Lo;0;L;;;;;N;;;;; +16C6;RUNIC LETTER SHORT-TWIG-AR A;Lo;0;L;;;;;N;;;;; +16C7;RUNIC LETTER IWAZ EOH;Lo;0;L;;;;;N;;;;; +16C8;RUNIC LETTER PERTHO PEORTH P;Lo;0;L;;;;;N;;;;; +16C9;RUNIC LETTER ALGIZ EOLHX;Lo;0;L;;;;;N;;;;; +16CA;RUNIC LETTER SOWILO S;Lo;0;L;;;;;N;;;;; +16CB;RUNIC LETTER SIGEL LONG-BRANCH-SOL S;Lo;0;L;;;;;N;;;;; +16CC;RUNIC LETTER SHORT-TWIG-SOL S;Lo;0;L;;;;;N;;;;; +16CD;RUNIC LETTER C;Lo;0;L;;;;;N;;;;; +16CE;RUNIC LETTER Z;Lo;0;L;;;;;N;;;;; +16CF;RUNIC LETTER TIWAZ TIR TYR T;Lo;0;L;;;;;N;;;;; +16D0;RUNIC LETTER SHORT-TWIG-TYR T;Lo;0;L;;;;;N;;;;; +16D1;RUNIC LETTER D;Lo;0;L;;;;;N;;;;; +16D2;RUNIC LETTER BERKANAN BEORC BJARKAN B;Lo;0;L;;;;;N;;;;; +16D3;RUNIC LETTER SHORT-TWIG-BJARKAN B;Lo;0;L;;;;;N;;;;; +16D4;RUNIC LETTER DOTTED-P;Lo;0;L;;;;;N;;;;; +16D5;RUNIC LETTER OPEN-P;Lo;0;L;;;;;N;;;;; +16D6;RUNIC LETTER EHWAZ EH E;Lo;0;L;;;;;N;;;;; +16D7;RUNIC LETTER MANNAZ MAN M;Lo;0;L;;;;;N;;;;; +16D8;RUNIC LETTER LONG-BRANCH-MADR M;Lo;0;L;;;;;N;;;;; +16D9;RUNIC LETTER SHORT-TWIG-MADR M;Lo;0;L;;;;;N;;;;; +16DA;RUNIC LETTER LAUKAZ LAGU LOGR L;Lo;0;L;;;;;N;;;;; +16DB;RUNIC LETTER DOTTED-L;Lo;0;L;;;;;N;;;;; +16DC;RUNIC LETTER INGWAZ;Lo;0;L;;;;;N;;;;; +16DD;RUNIC LETTER ING;Lo;0;L;;;;;N;;;;; +16DE;RUNIC LETTER DAGAZ DAEG D;Lo;0;L;;;;;N;;;;; +16DF;RUNIC LETTER OTHALAN ETHEL O;Lo;0;L;;;;;N;;;;; +16E0;RUNIC LETTER EAR;Lo;0;L;;;;;N;;;;; +16E1;RUNIC LETTER IOR;Lo;0;L;;;;;N;;;;; +16E2;RUNIC LETTER CWEORTH;Lo;0;L;;;;;N;;;;; +16E3;RUNIC LETTER CALC;Lo;0;L;;;;;N;;;;; +16E4;RUNIC LETTER CEALC;Lo;0;L;;;;;N;;;;; +16E5;RUNIC LETTER STAN;Lo;0;L;;;;;N;;;;; +16E6;RUNIC LETTER LONG-BRANCH-YR;Lo;0;L;;;;;N;;;;; +16E7;RUNIC LETTER SHORT-TWIG-YR;Lo;0;L;;;;;N;;;;; +16E8;RUNIC LETTER ICELANDIC-YR;Lo;0;L;;;;;N;;;;; +16E9;RUNIC LETTER Q;Lo;0;L;;;;;N;;;;; +16EA;RUNIC LETTER X;Lo;0;L;;;;;N;;;;; +16EB;RUNIC SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;; +16EC;RUNIC MULTIPLE PUNCTUATION;Po;0;L;;;;;N;;;;; +16ED;RUNIC CROSS PUNCTUATION;Po;0;L;;;;;N;;;;; +16EE;RUNIC ARLAUG SYMBOL;Nl;0;L;;;;17;N;;golden number 17;;; +16EF;RUNIC TVIMADUR SYMBOL;Nl;0;L;;;;18;N;;golden number 18;;; +16F0;RUNIC BELGTHOR SYMBOL;Nl;0;L;;;;19;N;;golden number 19;;; +1700;TAGALOG LETTER A;Lo;0;L;;;;;N;;;;; +1701;TAGALOG LETTER I;Lo;0;L;;;;;N;;;;; +1702;TAGALOG LETTER U;Lo;0;L;;;;;N;;;;; +1703;TAGALOG LETTER KA;Lo;0;L;;;;;N;;;;; +1704;TAGALOG LETTER GA;Lo;0;L;;;;;N;;;;; +1705;TAGALOG LETTER NGA;Lo;0;L;;;;;N;;;;; +1706;TAGALOG LETTER TA;Lo;0;L;;;;;N;;;;; +1707;TAGALOG LETTER DA;Lo;0;L;;;;;N;;;;; +1708;TAGALOG LETTER NA;Lo;0;L;;;;;N;;;;; +1709;TAGALOG LETTER PA;Lo;0;L;;;;;N;;;;; +170A;TAGALOG LETTER BA;Lo;0;L;;;;;N;;;;; +170B;TAGALOG LETTER MA;Lo;0;L;;;;;N;;;;; +170C;TAGALOG LETTER YA;Lo;0;L;;;;;N;;;;; +170E;TAGALOG LETTER LA;Lo;0;L;;;;;N;;;;; +170F;TAGALOG LETTER WA;Lo;0;L;;;;;N;;;;; +1710;TAGALOG LETTER SA;Lo;0;L;;;;;N;;;;; +1711;TAGALOG LETTER HA;Lo;0;L;;;;;N;;;;; +1712;TAGALOG VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1713;TAGALOG VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1714;TAGALOG SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +1720;HANUNOO LETTER A;Lo;0;L;;;;;N;;;;; +1721;HANUNOO LETTER I;Lo;0;L;;;;;N;;;;; +1722;HANUNOO LETTER U;Lo;0;L;;;;;N;;;;; +1723;HANUNOO LETTER KA;Lo;0;L;;;;;N;;;;; +1724;HANUNOO LETTER GA;Lo;0;L;;;;;N;;;;; +1725;HANUNOO LETTER NGA;Lo;0;L;;;;;N;;;;; +1726;HANUNOO LETTER TA;Lo;0;L;;;;;N;;;;; +1727;HANUNOO LETTER DA;Lo;0;L;;;;;N;;;;; +1728;HANUNOO LETTER NA;Lo;0;L;;;;;N;;;;; +1729;HANUNOO LETTER PA;Lo;0;L;;;;;N;;;;; +172A;HANUNOO LETTER BA;Lo;0;L;;;;;N;;;;; +172B;HANUNOO LETTER MA;Lo;0;L;;;;;N;;;;; +172C;HANUNOO LETTER YA;Lo;0;L;;;;;N;;;;; +172D;HANUNOO LETTER RA;Lo;0;L;;;;;N;;;;; +172E;HANUNOO LETTER LA;Lo;0;L;;;;;N;;;;; +172F;HANUNOO LETTER WA;Lo;0;L;;;;;N;;;;; +1730;HANUNOO LETTER SA;Lo;0;L;;;;;N;;;;; +1731;HANUNOO LETTER HA;Lo;0;L;;;;;N;;;;; +1732;HANUNOO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1733;HANUNOO VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1734;HANUNOO SIGN PAMUDPOD;Mn;9;NSM;;;;;N;;;;; +1735;PHILIPPINE SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;; +1736;PHILIPPINE DOUBLE PUNCTUATION;Po;0;L;;;;;N;;;;; +1740;BUHID LETTER A;Lo;0;L;;;;;N;;;;; +1741;BUHID LETTER I;Lo;0;L;;;;;N;;;;; +1742;BUHID LETTER U;Lo;0;L;;;;;N;;;;; +1743;BUHID LETTER KA;Lo;0;L;;;;;N;;;;; +1744;BUHID LETTER GA;Lo;0;L;;;;;N;;;;; +1745;BUHID LETTER NGA;Lo;0;L;;;;;N;;;;; +1746;BUHID LETTER TA;Lo;0;L;;;;;N;;;;; +1747;BUHID LETTER DA;Lo;0;L;;;;;N;;;;; +1748;BUHID LETTER NA;Lo;0;L;;;;;N;;;;; +1749;BUHID LETTER PA;Lo;0;L;;;;;N;;;;; +174A;BUHID LETTER BA;Lo;0;L;;;;;N;;;;; +174B;BUHID LETTER MA;Lo;0;L;;;;;N;;;;; +174C;BUHID LETTER YA;Lo;0;L;;;;;N;;;;; +174D;BUHID LETTER RA;Lo;0;L;;;;;N;;;;; +174E;BUHID LETTER LA;Lo;0;L;;;;;N;;;;; +174F;BUHID LETTER WA;Lo;0;L;;;;;N;;;;; +1750;BUHID LETTER SA;Lo;0;L;;;;;N;;;;; +1751;BUHID LETTER HA;Lo;0;L;;;;;N;;;;; +1752;BUHID VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1753;BUHID VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1760;TAGBANWA LETTER A;Lo;0;L;;;;;N;;;;; +1761;TAGBANWA LETTER I;Lo;0;L;;;;;N;;;;; +1762;TAGBANWA LETTER U;Lo;0;L;;;;;N;;;;; +1763;TAGBANWA LETTER KA;Lo;0;L;;;;;N;;;;; +1764;TAGBANWA LETTER GA;Lo;0;L;;;;;N;;;;; +1765;TAGBANWA LETTER NGA;Lo;0;L;;;;;N;;;;; +1766;TAGBANWA LETTER TA;Lo;0;L;;;;;N;;;;; +1767;TAGBANWA LETTER DA;Lo;0;L;;;;;N;;;;; +1768;TAGBANWA LETTER NA;Lo;0;L;;;;;N;;;;; +1769;TAGBANWA LETTER PA;Lo;0;L;;;;;N;;;;; +176A;TAGBANWA LETTER BA;Lo;0;L;;;;;N;;;;; +176B;TAGBANWA LETTER MA;Lo;0;L;;;;;N;;;;; +176C;TAGBANWA LETTER YA;Lo;0;L;;;;;N;;;;; +176E;TAGBANWA LETTER LA;Lo;0;L;;;;;N;;;;; +176F;TAGBANWA LETTER WA;Lo;0;L;;;;;N;;;;; +1770;TAGBANWA LETTER SA;Lo;0;L;;;;;N;;;;; +1772;TAGBANWA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1773;TAGBANWA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1780;KHMER LETTER KA;Lo;0;L;;;;;N;;;;; +1781;KHMER LETTER KHA;Lo;0;L;;;;;N;;;;; +1782;KHMER LETTER KO;Lo;0;L;;;;;N;;;;; +1783;KHMER LETTER KHO;Lo;0;L;;;;;N;;;;; +1784;KHMER LETTER NGO;Lo;0;L;;;;;N;;;;; +1785;KHMER LETTER CA;Lo;0;L;;;;;N;;;;; +1786;KHMER LETTER CHA;Lo;0;L;;;;;N;;;;; +1787;KHMER LETTER CO;Lo;0;L;;;;;N;;;;; +1788;KHMER LETTER CHO;Lo;0;L;;;;;N;;;;; +1789;KHMER LETTER NYO;Lo;0;L;;;;;N;;;;; +178A;KHMER LETTER DA;Lo;0;L;;;;;N;;;;; +178B;KHMER LETTER TTHA;Lo;0;L;;;;;N;;;;; +178C;KHMER LETTER DO;Lo;0;L;;;;;N;;;;; +178D;KHMER LETTER TTHO;Lo;0;L;;;;;N;;;;; +178E;KHMER LETTER NNO;Lo;0;L;;;;;N;;;;; +178F;KHMER LETTER TA;Lo;0;L;;;;;N;;;;; +1790;KHMER LETTER THA;Lo;0;L;;;;;N;;;;; +1791;KHMER LETTER TO;Lo;0;L;;;;;N;;;;; +1792;KHMER LETTER THO;Lo;0;L;;;;;N;;;;; +1793;KHMER LETTER NO;Lo;0;L;;;;;N;;;;; +1794;KHMER LETTER BA;Lo;0;L;;;;;N;;;;; +1795;KHMER LETTER PHA;Lo;0;L;;;;;N;;;;; +1796;KHMER LETTER PO;Lo;0;L;;;;;N;;;;; +1797;KHMER LETTER PHO;Lo;0;L;;;;;N;;;;; +1798;KHMER LETTER MO;Lo;0;L;;;;;N;;;;; +1799;KHMER LETTER YO;Lo;0;L;;;;;N;;;;; +179A;KHMER LETTER RO;Lo;0;L;;;;;N;;;;; +179B;KHMER LETTER LO;Lo;0;L;;;;;N;;;;; +179C;KHMER LETTER VO;Lo;0;L;;;;;N;;;;; +179D;KHMER LETTER SHA;Lo;0;L;;;;;N;;;;; +179E;KHMER LETTER SSO;Lo;0;L;;;;;N;;;;; +179F;KHMER LETTER SA;Lo;0;L;;;;;N;;;;; +17A0;KHMER LETTER HA;Lo;0;L;;;;;N;;;;; +17A1;KHMER LETTER LA;Lo;0;L;;;;;N;;;;; +17A2;KHMER LETTER QA;Lo;0;L;;;;;N;;;;; +17A3;KHMER INDEPENDENT VOWEL QAQ;Lo;0;L;;;;;N;;;;; +17A4;KHMER INDEPENDENT VOWEL QAA;Lo;0;L;;;;;N;;;;; +17A5;KHMER INDEPENDENT VOWEL QI;Lo;0;L;;;;;N;;;;; +17A6;KHMER INDEPENDENT VOWEL QII;Lo;0;L;;;;;N;;;;; +17A7;KHMER INDEPENDENT VOWEL QU;Lo;0;L;;;;;N;;;;; +17A8;KHMER INDEPENDENT VOWEL QUK;Lo;0;L;;;;;N;;;;; +17A9;KHMER INDEPENDENT VOWEL QUU;Lo;0;L;;;;;N;;;;; +17AA;KHMER INDEPENDENT VOWEL QUUV;Lo;0;L;;;;;N;;;;; +17AB;KHMER INDEPENDENT VOWEL RY;Lo;0;L;;;;;N;;;;; +17AC;KHMER INDEPENDENT VOWEL RYY;Lo;0;L;;;;;N;;;;; +17AD;KHMER INDEPENDENT VOWEL LY;Lo;0;L;;;;;N;;;;; +17AE;KHMER INDEPENDENT VOWEL LYY;Lo;0;L;;;;;N;;;;; +17AF;KHMER INDEPENDENT VOWEL QE;Lo;0;L;;;;;N;;;;; +17B0;KHMER INDEPENDENT VOWEL QAI;Lo;0;L;;;;;N;;;;; +17B1;KHMER INDEPENDENT VOWEL QOO TYPE ONE;Lo;0;L;;;;;N;;;;; +17B2;KHMER INDEPENDENT VOWEL QOO TYPE TWO;Lo;0;L;;;;;N;;;;; +17B3;KHMER INDEPENDENT VOWEL QAU;Lo;0;L;;;;;N;;;;; +17B4;KHMER VOWEL INHERENT AQ;Mc;0;L;;;;;N;;;;; +17B5;KHMER VOWEL INHERENT AA;Mc;0;L;;;;;N;;;;; +17B6;KHMER VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +17B7;KHMER VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +17B8;KHMER VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +17B9;KHMER VOWEL SIGN Y;Mn;0;NSM;;;;;N;;;;; +17BA;KHMER VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;; +17BB;KHMER VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +17BC;KHMER VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +17BD;KHMER VOWEL SIGN UA;Mn;0;NSM;;;;;N;;;;; +17BE;KHMER VOWEL SIGN OE;Mc;0;L;;;;;N;;;;; +17BF;KHMER VOWEL SIGN YA;Mc;0;L;;;;;N;;;;; +17C0;KHMER VOWEL SIGN IE;Mc;0;L;;;;;N;;;;; +17C1;KHMER VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +17C2;KHMER VOWEL SIGN AE;Mc;0;L;;;;;N;;;;; +17C3;KHMER VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +17C4;KHMER VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +17C5;KHMER VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +17C6;KHMER SIGN NIKAHIT;Mn;0;NSM;;;;;N;;;;; +17C7;KHMER SIGN REAHMUK;Mc;0;L;;;;;N;;;;; +17C8;KHMER SIGN YUUKALEAPINTU;Mc;0;L;;;;;N;;;;; +17C9;KHMER SIGN MUUSIKATOAN;Mn;0;NSM;;;;;N;;;;; +17CA;KHMER SIGN TRIISAP;Mn;0;NSM;;;;;N;;;;; +17CB;KHMER SIGN BANTOC;Mn;0;NSM;;;;;N;;;;; +17CC;KHMER SIGN ROBAT;Mn;0;NSM;;;;;N;;;;; +17CD;KHMER SIGN TOANDAKHIAT;Mn;0;NSM;;;;;N;;;;; +17CE;KHMER SIGN KAKABAT;Mn;0;NSM;;;;;N;;;;; +17CF;KHMER SIGN AHSDA;Mn;0;NSM;;;;;N;;;;; +17D0;KHMER SIGN SAMYOK SANNYA;Mn;0;NSM;;;;;N;;;;; +17D1;KHMER SIGN VIRIAM;Mn;0;NSM;;;;;N;;;;; +17D2;KHMER SIGN COENG;Mn;9;NSM;;;;;N;;;;; +17D3;KHMER SIGN BATHAMASAT;Mn;0;NSM;;;;;N;;;;; +17D4;KHMER SIGN KHAN;Po;0;L;;;;;N;;;;; +17D5;KHMER SIGN BARIYOOSAN;Po;0;L;;;;;N;;;;; +17D6;KHMER SIGN CAMNUC PII KUUH;Po;0;L;;;;;N;;;;; +17D7;KHMER SIGN LEK TOO;Lm;0;L;;;;;N;;;;; +17D8;KHMER SIGN BEYYAL;Po;0;L;;;;;N;;;;; +17D9;KHMER SIGN PHNAEK MUAN;Po;0;L;;;;;N;;;;; +17DA;KHMER SIGN KOOMUUT;Po;0;L;;;;;N;;;;; +17DB;KHMER CURRENCY SYMBOL RIEL;Sc;0;ET;;;;;N;;;;; +17DC;KHMER SIGN AVAKRAHASANYA;Lo;0;L;;;;;N;;;;; +17E0;KHMER DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +17E1;KHMER DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +17E2;KHMER DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +17E3;KHMER DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +17E4;KHMER DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +17E5;KHMER DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +17E6;KHMER DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +17E7;KHMER DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +17E8;KHMER DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +17E9;KHMER DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1800;MONGOLIAN BIRGA;Po;0;ON;;;;;N;;;;; +1801;MONGOLIAN ELLIPSIS;Po;0;ON;;;;;N;;;;; +1802;MONGOLIAN COMMA;Po;0;ON;;;;;N;;;;; +1803;MONGOLIAN FULL STOP;Po;0;ON;;;;;N;;;;; +1804;MONGOLIAN COLON;Po;0;ON;;;;;N;;;;; +1805;MONGOLIAN FOUR DOTS;Po;0;ON;;;;;N;;;;; +1806;MONGOLIAN TODO SOFT HYPHEN;Pd;0;ON;;;;;N;;;;; +1807;MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER;Po;0;ON;;;;;N;;;;; +1808;MONGOLIAN MANCHU COMMA;Po;0;ON;;;;;N;;;;; +1809;MONGOLIAN MANCHU FULL STOP;Po;0;ON;;;;;N;;;;; +180A;MONGOLIAN NIRUGU;Po;0;ON;;;;;N;;;;; +180B;MONGOLIAN FREE VARIATION SELECTOR ONE;Mn;0;NSM;;;;;N;;;;; +180C;MONGOLIAN FREE VARIATION SELECTOR TWO;Mn;0;NSM;;;;;N;;;;; +180D;MONGOLIAN FREE VARIATION SELECTOR THREE;Mn;0;NSM;;;;;N;;;;; +180E;MONGOLIAN VOWEL SEPARATOR;Cf;0;BN;;;;;N;;;;; +1810;MONGOLIAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1811;MONGOLIAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1812;MONGOLIAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1813;MONGOLIAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1814;MONGOLIAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1815;MONGOLIAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1816;MONGOLIAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1817;MONGOLIAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1818;MONGOLIAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1819;MONGOLIAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1820;MONGOLIAN LETTER A;Lo;0;L;;;;;N;;;;; +1821;MONGOLIAN LETTER E;Lo;0;L;;;;;N;;;;; +1822;MONGOLIAN LETTER I;Lo;0;L;;;;;N;;;;; +1823;MONGOLIAN LETTER O;Lo;0;L;;;;;N;;;;; +1824;MONGOLIAN LETTER U;Lo;0;L;;;;;N;;;;; +1825;MONGOLIAN LETTER OE;Lo;0;L;;;;;N;;;;; +1826;MONGOLIAN LETTER UE;Lo;0;L;;;;;N;;;;; +1827;MONGOLIAN LETTER EE;Lo;0;L;;;;;N;;;;; +1828;MONGOLIAN LETTER NA;Lo;0;L;;;;;N;;;;; +1829;MONGOLIAN LETTER ANG;Lo;0;L;;;;;N;;;;; +182A;MONGOLIAN LETTER BA;Lo;0;L;;;;;N;;;;; +182B;MONGOLIAN LETTER PA;Lo;0;L;;;;;N;;;;; +182C;MONGOLIAN LETTER QA;Lo;0;L;;;;;N;;;;; +182D;MONGOLIAN LETTER GA;Lo;0;L;;;;;N;;;;; +182E;MONGOLIAN LETTER MA;Lo;0;L;;;;;N;;;;; +182F;MONGOLIAN LETTER LA;Lo;0;L;;;;;N;;;;; +1830;MONGOLIAN LETTER SA;Lo;0;L;;;;;N;;;;; +1831;MONGOLIAN LETTER SHA;Lo;0;L;;;;;N;;;;; +1832;MONGOLIAN LETTER TA;Lo;0;L;;;;;N;;;;; +1833;MONGOLIAN LETTER DA;Lo;0;L;;;;;N;;;;; +1834;MONGOLIAN LETTER CHA;Lo;0;L;;;;;N;;;;; +1835;MONGOLIAN LETTER JA;Lo;0;L;;;;;N;;;;; +1836;MONGOLIAN LETTER YA;Lo;0;L;;;;;N;;;;; +1837;MONGOLIAN LETTER RA;Lo;0;L;;;;;N;;;;; +1838;MONGOLIAN LETTER WA;Lo;0;L;;;;;N;;;;; +1839;MONGOLIAN LETTER FA;Lo;0;L;;;;;N;;;;; +183A;MONGOLIAN LETTER KA;Lo;0;L;;;;;N;;;;; +183B;MONGOLIAN LETTER KHA;Lo;0;L;;;;;N;;;;; +183C;MONGOLIAN LETTER TSA;Lo;0;L;;;;;N;;;;; +183D;MONGOLIAN LETTER ZA;Lo;0;L;;;;;N;;;;; +183E;MONGOLIAN LETTER HAA;Lo;0;L;;;;;N;;;;; +183F;MONGOLIAN LETTER ZRA;Lo;0;L;;;;;N;;;;; +1840;MONGOLIAN LETTER LHA;Lo;0;L;;;;;N;;;;; +1841;MONGOLIAN LETTER ZHI;Lo;0;L;;;;;N;;;;; +1842;MONGOLIAN LETTER CHI;Lo;0;L;;;;;N;;;;; +1843;MONGOLIAN LETTER TODO LONG VOWEL SIGN;Lm;0;L;;;;;N;;;;; +1844;MONGOLIAN LETTER TODO E;Lo;0;L;;;;;N;;;;; +1845;MONGOLIAN LETTER TODO I;Lo;0;L;;;;;N;;;;; +1846;MONGOLIAN LETTER TODO O;Lo;0;L;;;;;N;;;;; +1847;MONGOLIAN LETTER TODO U;Lo;0;L;;;;;N;;;;; +1848;MONGOLIAN LETTER TODO OE;Lo;0;L;;;;;N;;;;; +1849;MONGOLIAN LETTER TODO UE;Lo;0;L;;;;;N;;;;; +184A;MONGOLIAN LETTER TODO ANG;Lo;0;L;;;;;N;;;;; +184B;MONGOLIAN LETTER TODO BA;Lo;0;L;;;;;N;;;;; +184C;MONGOLIAN LETTER TODO PA;Lo;0;L;;;;;N;;;;; +184D;MONGOLIAN LETTER TODO QA;Lo;0;L;;;;;N;;;;; +184E;MONGOLIAN LETTER TODO GA;Lo;0;L;;;;;N;;;;; +184F;MONGOLIAN LETTER TODO MA;Lo;0;L;;;;;N;;;;; +1850;MONGOLIAN LETTER TODO TA;Lo;0;L;;;;;N;;;;; +1851;MONGOLIAN LETTER TODO DA;Lo;0;L;;;;;N;;;;; +1852;MONGOLIAN LETTER TODO CHA;Lo;0;L;;;;;N;;;;; +1853;MONGOLIAN LETTER TODO JA;Lo;0;L;;;;;N;;;;; +1854;MONGOLIAN LETTER TODO TSA;Lo;0;L;;;;;N;;;;; +1855;MONGOLIAN LETTER TODO YA;Lo;0;L;;;;;N;;;;; +1856;MONGOLIAN LETTER TODO WA;Lo;0;L;;;;;N;;;;; +1857;MONGOLIAN LETTER TODO KA;Lo;0;L;;;;;N;;;;; +1858;MONGOLIAN LETTER TODO GAA;Lo;0;L;;;;;N;;;;; +1859;MONGOLIAN LETTER TODO HAA;Lo;0;L;;;;;N;;;;; +185A;MONGOLIAN LETTER TODO JIA;Lo;0;L;;;;;N;;;;; +185B;MONGOLIAN LETTER TODO NIA;Lo;0;L;;;;;N;;;;; +185C;MONGOLIAN LETTER TODO DZA;Lo;0;L;;;;;N;;;;; +185D;MONGOLIAN LETTER SIBE E;Lo;0;L;;;;;N;;;;; +185E;MONGOLIAN LETTER SIBE I;Lo;0;L;;;;;N;;;;; +185F;MONGOLIAN LETTER SIBE IY;Lo;0;L;;;;;N;;;;; +1860;MONGOLIAN LETTER SIBE UE;Lo;0;L;;;;;N;;;;; +1861;MONGOLIAN LETTER SIBE U;Lo;0;L;;;;;N;;;;; +1862;MONGOLIAN LETTER SIBE ANG;Lo;0;L;;;;;N;;;;; +1863;MONGOLIAN LETTER SIBE KA;Lo;0;L;;;;;N;;;;; +1864;MONGOLIAN LETTER SIBE GA;Lo;0;L;;;;;N;;;;; +1865;MONGOLIAN LETTER SIBE HA;Lo;0;L;;;;;N;;;;; +1866;MONGOLIAN LETTER SIBE PA;Lo;0;L;;;;;N;;;;; +1867;MONGOLIAN LETTER SIBE SHA;Lo;0;L;;;;;N;;;;; +1868;MONGOLIAN LETTER SIBE TA;Lo;0;L;;;;;N;;;;; +1869;MONGOLIAN LETTER SIBE DA;Lo;0;L;;;;;N;;;;; +186A;MONGOLIAN LETTER SIBE JA;Lo;0;L;;;;;N;;;;; +186B;MONGOLIAN LETTER SIBE FA;Lo;0;L;;;;;N;;;;; +186C;MONGOLIAN LETTER SIBE GAA;Lo;0;L;;;;;N;;;;; +186D;MONGOLIAN LETTER SIBE HAA;Lo;0;L;;;;;N;;;;; +186E;MONGOLIAN LETTER SIBE TSA;Lo;0;L;;;;;N;;;;; +186F;MONGOLIAN LETTER SIBE ZA;Lo;0;L;;;;;N;;;;; +1870;MONGOLIAN LETTER SIBE RAA;Lo;0;L;;;;;N;;;;; +1871;MONGOLIAN LETTER SIBE CHA;Lo;0;L;;;;;N;;;;; +1872;MONGOLIAN LETTER SIBE ZHA;Lo;0;L;;;;;N;;;;; +1873;MONGOLIAN LETTER MANCHU I;Lo;0;L;;;;;N;;;;; +1874;MONGOLIAN LETTER MANCHU KA;Lo;0;L;;;;;N;;;;; +1875;MONGOLIAN LETTER MANCHU RA;Lo;0;L;;;;;N;;;;; +1876;MONGOLIAN LETTER MANCHU FA;Lo;0;L;;;;;N;;;;; +1877;MONGOLIAN LETTER MANCHU ZHA;Lo;0;L;;;;;N;;;;; +1880;MONGOLIAN LETTER ALI GALI ANUSVARA ONE;Lo;0;L;;;;;N;;;;; +1881;MONGOLIAN LETTER ALI GALI VISARGA ONE;Lo;0;L;;;;;N;;;;; +1882;MONGOLIAN LETTER ALI GALI DAMARU;Lo;0;L;;;;;N;;;;; +1883;MONGOLIAN LETTER ALI GALI UBADAMA;Lo;0;L;;;;;N;;;;; +1884;MONGOLIAN LETTER ALI GALI INVERTED UBADAMA;Lo;0;L;;;;;N;;;;; +1885;MONGOLIAN LETTER ALI GALI BALUDA;Lo;0;L;;;;;N;;;;; +1886;MONGOLIAN LETTER ALI GALI THREE BALUDA;Lo;0;L;;;;;N;;;;; +1887;MONGOLIAN LETTER ALI GALI A;Lo;0;L;;;;;N;;;;; +1888;MONGOLIAN LETTER ALI GALI I;Lo;0;L;;;;;N;;;;; +1889;MONGOLIAN LETTER ALI GALI KA;Lo;0;L;;;;;N;;;;; +188A;MONGOLIAN LETTER ALI GALI NGA;Lo;0;L;;;;;N;;;;; +188B;MONGOLIAN LETTER ALI GALI CA;Lo;0;L;;;;;N;;;;; +188C;MONGOLIAN LETTER ALI GALI TTA;Lo;0;L;;;;;N;;;;; +188D;MONGOLIAN LETTER ALI GALI TTHA;Lo;0;L;;;;;N;;;;; +188E;MONGOLIAN LETTER ALI GALI DDA;Lo;0;L;;;;;N;;;;; +188F;MONGOLIAN LETTER ALI GALI NNA;Lo;0;L;;;;;N;;;;; +1890;MONGOLIAN LETTER ALI GALI TA;Lo;0;L;;;;;N;;;;; +1891;MONGOLIAN LETTER ALI GALI DA;Lo;0;L;;;;;N;;;;; +1892;MONGOLIAN LETTER ALI GALI PA;Lo;0;L;;;;;N;;;;; +1893;MONGOLIAN LETTER ALI GALI PHA;Lo;0;L;;;;;N;;;;; +1894;MONGOLIAN LETTER ALI GALI SSA;Lo;0;L;;;;;N;;;;; +1895;MONGOLIAN LETTER ALI GALI ZHA;Lo;0;L;;;;;N;;;;; +1896;MONGOLIAN LETTER ALI GALI ZA;Lo;0;L;;;;;N;;;;; +1897;MONGOLIAN LETTER ALI GALI AH;Lo;0;L;;;;;N;;;;; +1898;MONGOLIAN LETTER TODO ALI GALI TA;Lo;0;L;;;;;N;;;;; +1899;MONGOLIAN LETTER TODO ALI GALI ZHA;Lo;0;L;;;;;N;;;;; +189A;MONGOLIAN LETTER MANCHU ALI GALI GHA;Lo;0;L;;;;;N;;;;; +189B;MONGOLIAN LETTER MANCHU ALI GALI NGA;Lo;0;L;;;;;N;;;;; +189C;MONGOLIAN LETTER MANCHU ALI GALI CA;Lo;0;L;;;;;N;;;;; +189D;MONGOLIAN LETTER MANCHU ALI GALI JHA;Lo;0;L;;;;;N;;;;; +189E;MONGOLIAN LETTER MANCHU ALI GALI TTA;Lo;0;L;;;;;N;;;;; +189F;MONGOLIAN LETTER MANCHU ALI GALI DDHA;Lo;0;L;;;;;N;;;;; +18A0;MONGOLIAN LETTER MANCHU ALI GALI TA;Lo;0;L;;;;;N;;;;; +18A1;MONGOLIAN LETTER MANCHU ALI GALI DHA;Lo;0;L;;;;;N;;;;; +18A2;MONGOLIAN LETTER MANCHU ALI GALI SSA;Lo;0;L;;;;;N;;;;; +18A3;MONGOLIAN LETTER MANCHU ALI GALI CYA;Lo;0;L;;;;;N;;;;; +18A4;MONGOLIAN LETTER MANCHU ALI GALI ZHA;Lo;0;L;;;;;N;;;;; +18A5;MONGOLIAN LETTER MANCHU ALI GALI ZA;Lo;0;L;;;;;N;;;;; +18A6;MONGOLIAN LETTER ALI GALI HALF U;Lo;0;L;;;;;N;;;;; +18A7;MONGOLIAN LETTER ALI GALI HALF YA;Lo;0;L;;;;;N;;;;; +18A8;MONGOLIAN LETTER MANCHU ALI GALI BHA;Lo;0;L;;;;;N;;;;; +18A9;MONGOLIAN LETTER ALI GALI DAGALGA;Mn;228;NSM;;;;;N;;;;; +1E00;LATIN CAPITAL LETTER A WITH RING BELOW;Lu;0;L;0041 0325;;;;N;;;;1E01; +1E01;LATIN SMALL LETTER A WITH RING BELOW;Ll;0;L;0061 0325;;;;N;;;1E00;;1E00 +1E02;LATIN CAPITAL LETTER B WITH DOT ABOVE;Lu;0;L;0042 0307;;;;N;;;;1E03; +1E03;LATIN SMALL LETTER B WITH DOT ABOVE;Ll;0;L;0062 0307;;;;N;;;1E02;;1E02 +1E04;LATIN CAPITAL LETTER B WITH DOT BELOW;Lu;0;L;0042 0323;;;;N;;;;1E05; +1E05;LATIN SMALL LETTER B WITH DOT BELOW;Ll;0;L;0062 0323;;;;N;;;1E04;;1E04 +1E06;LATIN CAPITAL LETTER B WITH LINE BELOW;Lu;0;L;0042 0331;;;;N;;;;1E07; +1E07;LATIN SMALL LETTER B WITH LINE BELOW;Ll;0;L;0062 0331;;;;N;;;1E06;;1E06 +1E08;LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE;Lu;0;L;00C7 0301;;;;N;;;;1E09; +1E09;LATIN SMALL LETTER C WITH CEDILLA AND ACUTE;Ll;0;L;00E7 0301;;;;N;;;1E08;;1E08 +1E0A;LATIN CAPITAL LETTER D WITH DOT ABOVE;Lu;0;L;0044 0307;;;;N;;;;1E0B; +1E0B;LATIN SMALL LETTER D WITH DOT ABOVE;Ll;0;L;0064 0307;;;;N;;;1E0A;;1E0A +1E0C;LATIN CAPITAL LETTER D WITH DOT BELOW;Lu;0;L;0044 0323;;;;N;;;;1E0D; +1E0D;LATIN SMALL LETTER D WITH DOT BELOW;Ll;0;L;0064 0323;;;;N;;;1E0C;;1E0C +1E0E;LATIN CAPITAL LETTER D WITH LINE BELOW;Lu;0;L;0044 0331;;;;N;;;;1E0F; +1E0F;LATIN SMALL LETTER D WITH LINE BELOW;Ll;0;L;0064 0331;;;;N;;;1E0E;;1E0E +1E10;LATIN CAPITAL LETTER D WITH CEDILLA;Lu;0;L;0044 0327;;;;N;;;;1E11; +1E11;LATIN SMALL LETTER D WITH CEDILLA;Ll;0;L;0064 0327;;;;N;;;1E10;;1E10 +1E12;LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW;Lu;0;L;0044 032D;;;;N;;;;1E13; +1E13;LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW;Ll;0;L;0064 032D;;;;N;;;1E12;;1E12 +1E14;LATIN CAPITAL LETTER E WITH MACRON AND GRAVE;Lu;0;L;0112 0300;;;;N;;;;1E15; +1E15;LATIN SMALL LETTER E WITH MACRON AND GRAVE;Ll;0;L;0113 0300;;;;N;;;1E14;;1E14 +1E16;LATIN CAPITAL LETTER E WITH MACRON AND ACUTE;Lu;0;L;0112 0301;;;;N;;;;1E17; +1E17;LATIN SMALL LETTER E WITH MACRON AND ACUTE;Ll;0;L;0113 0301;;;;N;;;1E16;;1E16 +1E18;LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW;Lu;0;L;0045 032D;;;;N;;;;1E19; +1E19;LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW;Ll;0;L;0065 032D;;;;N;;;1E18;;1E18 +1E1A;LATIN CAPITAL LETTER E WITH TILDE BELOW;Lu;0;L;0045 0330;;;;N;;;;1E1B; +1E1B;LATIN SMALL LETTER E WITH TILDE BELOW;Ll;0;L;0065 0330;;;;N;;;1E1A;;1E1A +1E1C;LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE;Lu;0;L;0228 0306;;;;N;;;;1E1D; +1E1D;LATIN SMALL LETTER E WITH CEDILLA AND BREVE;Ll;0;L;0229 0306;;;;N;;;1E1C;;1E1C +1E1E;LATIN CAPITAL LETTER F WITH DOT ABOVE;Lu;0;L;0046 0307;;;;N;;;;1E1F; +1E1F;LATIN SMALL LETTER F WITH DOT ABOVE;Ll;0;L;0066 0307;;;;N;;;1E1E;;1E1E +1E20;LATIN CAPITAL LETTER G WITH MACRON;Lu;0;L;0047 0304;;;;N;;;;1E21; +1E21;LATIN SMALL LETTER G WITH MACRON;Ll;0;L;0067 0304;;;;N;;;1E20;;1E20 +1E22;LATIN CAPITAL LETTER H WITH DOT ABOVE;Lu;0;L;0048 0307;;;;N;;;;1E23; +1E23;LATIN SMALL LETTER H WITH DOT ABOVE;Ll;0;L;0068 0307;;;;N;;;1E22;;1E22 +1E24;LATIN CAPITAL LETTER H WITH DOT BELOW;Lu;0;L;0048 0323;;;;N;;;;1E25; +1E25;LATIN SMALL LETTER H WITH DOT BELOW;Ll;0;L;0068 0323;;;;N;;;1E24;;1E24 +1E26;LATIN CAPITAL LETTER H WITH DIAERESIS;Lu;0;L;0048 0308;;;;N;;;;1E27; +1E27;LATIN SMALL LETTER H WITH DIAERESIS;Ll;0;L;0068 0308;;;;N;;;1E26;;1E26 +1E28;LATIN CAPITAL LETTER H WITH CEDILLA;Lu;0;L;0048 0327;;;;N;;;;1E29; +1E29;LATIN SMALL LETTER H WITH CEDILLA;Ll;0;L;0068 0327;;;;N;;;1E28;;1E28 +1E2A;LATIN CAPITAL LETTER H WITH BREVE BELOW;Lu;0;L;0048 032E;;;;N;;;;1E2B; +1E2B;LATIN SMALL LETTER H WITH BREVE BELOW;Ll;0;L;0068 032E;;;;N;;;1E2A;;1E2A +1E2C;LATIN CAPITAL LETTER I WITH TILDE BELOW;Lu;0;L;0049 0330;;;;N;;;;1E2D; +1E2D;LATIN SMALL LETTER I WITH TILDE BELOW;Ll;0;L;0069 0330;;;;N;;;1E2C;;1E2C +1E2E;LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE;Lu;0;L;00CF 0301;;;;N;;;;1E2F; +1E2F;LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE;Ll;0;L;00EF 0301;;;;N;;;1E2E;;1E2E +1E30;LATIN CAPITAL LETTER K WITH ACUTE;Lu;0;L;004B 0301;;;;N;;;;1E31; +1E31;LATIN SMALL LETTER K WITH ACUTE;Ll;0;L;006B 0301;;;;N;;;1E30;;1E30 +1E32;LATIN CAPITAL LETTER K WITH DOT BELOW;Lu;0;L;004B 0323;;;;N;;;;1E33; +1E33;LATIN SMALL LETTER K WITH DOT BELOW;Ll;0;L;006B 0323;;;;N;;;1E32;;1E32 +1E34;LATIN CAPITAL LETTER K WITH LINE BELOW;Lu;0;L;004B 0331;;;;N;;;;1E35; +1E35;LATIN SMALL LETTER K WITH LINE BELOW;Ll;0;L;006B 0331;;;;N;;;1E34;;1E34 +1E36;LATIN CAPITAL LETTER L WITH DOT BELOW;Lu;0;L;004C 0323;;;;N;;;;1E37; +1E37;LATIN SMALL LETTER L WITH DOT BELOW;Ll;0;L;006C 0323;;;;N;;;1E36;;1E36 +1E38;LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON;Lu;0;L;1E36 0304;;;;N;;;;1E39; +1E39;LATIN SMALL LETTER L WITH DOT BELOW AND MACRON;Ll;0;L;1E37 0304;;;;N;;;1E38;;1E38 +1E3A;LATIN CAPITAL LETTER L WITH LINE BELOW;Lu;0;L;004C 0331;;;;N;;;;1E3B; +1E3B;LATIN SMALL LETTER L WITH LINE BELOW;Ll;0;L;006C 0331;;;;N;;;1E3A;;1E3A +1E3C;LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW;Lu;0;L;004C 032D;;;;N;;;;1E3D; +1E3D;LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW;Ll;0;L;006C 032D;;;;N;;;1E3C;;1E3C +1E3E;LATIN CAPITAL LETTER M WITH ACUTE;Lu;0;L;004D 0301;;;;N;;;;1E3F; +1E3F;LATIN SMALL LETTER M WITH ACUTE;Ll;0;L;006D 0301;;;;N;;;1E3E;;1E3E +1E40;LATIN CAPITAL LETTER M WITH DOT ABOVE;Lu;0;L;004D 0307;;;;N;;;;1E41; +1E41;LATIN SMALL LETTER M WITH DOT ABOVE;Ll;0;L;006D 0307;;;;N;;;1E40;;1E40 +1E42;LATIN CAPITAL LETTER M WITH DOT BELOW;Lu;0;L;004D 0323;;;;N;;;;1E43; +1E43;LATIN SMALL LETTER M WITH DOT BELOW;Ll;0;L;006D 0323;;;;N;;;1E42;;1E42 +1E44;LATIN CAPITAL LETTER N WITH DOT ABOVE;Lu;0;L;004E 0307;;;;N;;;;1E45; +1E45;LATIN SMALL LETTER N WITH DOT ABOVE;Ll;0;L;006E 0307;;;;N;;;1E44;;1E44 +1E46;LATIN CAPITAL LETTER N WITH DOT BELOW;Lu;0;L;004E 0323;;;;N;;;;1E47; +1E47;LATIN SMALL LETTER N WITH DOT BELOW;Ll;0;L;006E 0323;;;;N;;;1E46;;1E46 +1E48;LATIN CAPITAL LETTER N WITH LINE BELOW;Lu;0;L;004E 0331;;;;N;;;;1E49; +1E49;LATIN SMALL LETTER N WITH LINE BELOW;Ll;0;L;006E 0331;;;;N;;;1E48;;1E48 +1E4A;LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW;Lu;0;L;004E 032D;;;;N;;;;1E4B; +1E4B;LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW;Ll;0;L;006E 032D;;;;N;;;1E4A;;1E4A +1E4C;LATIN CAPITAL LETTER O WITH TILDE AND ACUTE;Lu;0;L;00D5 0301;;;;N;;;;1E4D; +1E4D;LATIN SMALL LETTER O WITH TILDE AND ACUTE;Ll;0;L;00F5 0301;;;;N;;;1E4C;;1E4C +1E4E;LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS;Lu;0;L;00D5 0308;;;;N;;;;1E4F; +1E4F;LATIN SMALL LETTER O WITH TILDE AND DIAERESIS;Ll;0;L;00F5 0308;;;;N;;;1E4E;;1E4E +1E50;LATIN CAPITAL LETTER O WITH MACRON AND GRAVE;Lu;0;L;014C 0300;;;;N;;;;1E51; +1E51;LATIN SMALL LETTER O WITH MACRON AND GRAVE;Ll;0;L;014D 0300;;;;N;;;1E50;;1E50 +1E52;LATIN CAPITAL LETTER O WITH MACRON AND ACUTE;Lu;0;L;014C 0301;;;;N;;;;1E53; +1E53;LATIN SMALL LETTER O WITH MACRON AND ACUTE;Ll;0;L;014D 0301;;;;N;;;1E52;;1E52 +1E54;LATIN CAPITAL LETTER P WITH ACUTE;Lu;0;L;0050 0301;;;;N;;;;1E55; +1E55;LATIN SMALL LETTER P WITH ACUTE;Ll;0;L;0070 0301;;;;N;;;1E54;;1E54 +1E56;LATIN CAPITAL LETTER P WITH DOT ABOVE;Lu;0;L;0050 0307;;;;N;;;;1E57; +1E57;LATIN SMALL LETTER P WITH DOT ABOVE;Ll;0;L;0070 0307;;;;N;;;1E56;;1E56 +1E58;LATIN CAPITAL LETTER R WITH DOT ABOVE;Lu;0;L;0052 0307;;;;N;;;;1E59; +1E59;LATIN SMALL LETTER R WITH DOT ABOVE;Ll;0;L;0072 0307;;;;N;;;1E58;;1E58 +1E5A;LATIN CAPITAL LETTER R WITH DOT BELOW;Lu;0;L;0052 0323;;;;N;;;;1E5B; +1E5B;LATIN SMALL LETTER R WITH DOT BELOW;Ll;0;L;0072 0323;;;;N;;;1E5A;;1E5A +1E5C;LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON;Lu;0;L;1E5A 0304;;;;N;;;;1E5D; +1E5D;LATIN SMALL LETTER R WITH DOT BELOW AND MACRON;Ll;0;L;1E5B 0304;;;;N;;;1E5C;;1E5C +1E5E;LATIN CAPITAL LETTER R WITH LINE BELOW;Lu;0;L;0052 0331;;;;N;;;;1E5F; +1E5F;LATIN SMALL LETTER R WITH LINE BELOW;Ll;0;L;0072 0331;;;;N;;;1E5E;;1E5E +1E60;LATIN CAPITAL LETTER S WITH DOT ABOVE;Lu;0;L;0053 0307;;;;N;;;;1E61; +1E61;LATIN SMALL LETTER S WITH DOT ABOVE;Ll;0;L;0073 0307;;;;N;;;1E60;;1E60 +1E62;LATIN CAPITAL LETTER S WITH DOT BELOW;Lu;0;L;0053 0323;;;;N;;;;1E63; +1E63;LATIN SMALL LETTER S WITH DOT BELOW;Ll;0;L;0073 0323;;;;N;;;1E62;;1E62 +1E64;LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE;Lu;0;L;015A 0307;;;;N;;;;1E65; +1E65;LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE;Ll;0;L;015B 0307;;;;N;;;1E64;;1E64 +1E66;LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE;Lu;0;L;0160 0307;;;;N;;;;1E67; +1E67;LATIN SMALL LETTER S WITH CARON AND DOT ABOVE;Ll;0;L;0161 0307;;;;N;;;1E66;;1E66 +1E68;LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE;Lu;0;L;1E62 0307;;;;N;;;;1E69; +1E69;LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE;Ll;0;L;1E63 0307;;;;N;;;1E68;;1E68 +1E6A;LATIN CAPITAL LETTER T WITH DOT ABOVE;Lu;0;L;0054 0307;;;;N;;;;1E6B; +1E6B;LATIN SMALL LETTER T WITH DOT ABOVE;Ll;0;L;0074 0307;;;;N;;;1E6A;;1E6A +1E6C;LATIN CAPITAL LETTER T WITH DOT BELOW;Lu;0;L;0054 0323;;;;N;;;;1E6D; +1E6D;LATIN SMALL LETTER T WITH DOT BELOW;Ll;0;L;0074 0323;;;;N;;;1E6C;;1E6C +1E6E;LATIN CAPITAL LETTER T WITH LINE BELOW;Lu;0;L;0054 0331;;;;N;;;;1E6F; +1E6F;LATIN SMALL LETTER T WITH LINE BELOW;Ll;0;L;0074 0331;;;;N;;;1E6E;;1E6E +1E70;LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW;Lu;0;L;0054 032D;;;;N;;;;1E71; +1E71;LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW;Ll;0;L;0074 032D;;;;N;;;1E70;;1E70 +1E72;LATIN CAPITAL LETTER U WITH DIAERESIS BELOW;Lu;0;L;0055 0324;;;;N;;;;1E73; +1E73;LATIN SMALL LETTER U WITH DIAERESIS BELOW;Ll;0;L;0075 0324;;;;N;;;1E72;;1E72 +1E74;LATIN CAPITAL LETTER U WITH TILDE BELOW;Lu;0;L;0055 0330;;;;N;;;;1E75; +1E75;LATIN SMALL LETTER U WITH TILDE BELOW;Ll;0;L;0075 0330;;;;N;;;1E74;;1E74 +1E76;LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW;Lu;0;L;0055 032D;;;;N;;;;1E77; +1E77;LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW;Ll;0;L;0075 032D;;;;N;;;1E76;;1E76 +1E78;LATIN CAPITAL LETTER U WITH TILDE AND ACUTE;Lu;0;L;0168 0301;;;;N;;;;1E79; +1E79;LATIN SMALL LETTER U WITH TILDE AND ACUTE;Ll;0;L;0169 0301;;;;N;;;1E78;;1E78 +1E7A;LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS;Lu;0;L;016A 0308;;;;N;;;;1E7B; +1E7B;LATIN SMALL LETTER U WITH MACRON AND DIAERESIS;Ll;0;L;016B 0308;;;;N;;;1E7A;;1E7A +1E7C;LATIN CAPITAL LETTER V WITH TILDE;Lu;0;L;0056 0303;;;;N;;;;1E7D; +1E7D;LATIN SMALL LETTER V WITH TILDE;Ll;0;L;0076 0303;;;;N;;;1E7C;;1E7C +1E7E;LATIN CAPITAL LETTER V WITH DOT BELOW;Lu;0;L;0056 0323;;;;N;;;;1E7F; +1E7F;LATIN SMALL LETTER V WITH DOT BELOW;Ll;0;L;0076 0323;;;;N;;;1E7E;;1E7E +1E80;LATIN CAPITAL LETTER W WITH GRAVE;Lu;0;L;0057 0300;;;;N;;;;1E81; +1E81;LATIN SMALL LETTER W WITH GRAVE;Ll;0;L;0077 0300;;;;N;;;1E80;;1E80 +1E82;LATIN CAPITAL LETTER W WITH ACUTE;Lu;0;L;0057 0301;;;;N;;;;1E83; +1E83;LATIN SMALL LETTER W WITH ACUTE;Ll;0;L;0077 0301;;;;N;;;1E82;;1E82 +1E84;LATIN CAPITAL LETTER W WITH DIAERESIS;Lu;0;L;0057 0308;;;;N;;;;1E85; +1E85;LATIN SMALL LETTER W WITH DIAERESIS;Ll;0;L;0077 0308;;;;N;;;1E84;;1E84 +1E86;LATIN CAPITAL LETTER W WITH DOT ABOVE;Lu;0;L;0057 0307;;;;N;;;;1E87; +1E87;LATIN SMALL LETTER W WITH DOT ABOVE;Ll;0;L;0077 0307;;;;N;;;1E86;;1E86 +1E88;LATIN CAPITAL LETTER W WITH DOT BELOW;Lu;0;L;0057 0323;;;;N;;;;1E89; +1E89;LATIN SMALL LETTER W WITH DOT BELOW;Ll;0;L;0077 0323;;;;N;;;1E88;;1E88 +1E8A;LATIN CAPITAL LETTER X WITH DOT ABOVE;Lu;0;L;0058 0307;;;;N;;;;1E8B; +1E8B;LATIN SMALL LETTER X WITH DOT ABOVE;Ll;0;L;0078 0307;;;;N;;;1E8A;;1E8A +1E8C;LATIN CAPITAL LETTER X WITH DIAERESIS;Lu;0;L;0058 0308;;;;N;;;;1E8D; +1E8D;LATIN SMALL LETTER X WITH DIAERESIS;Ll;0;L;0078 0308;;;;N;;;1E8C;;1E8C +1E8E;LATIN CAPITAL LETTER Y WITH DOT ABOVE;Lu;0;L;0059 0307;;;;N;;;;1E8F; +1E8F;LATIN SMALL LETTER Y WITH DOT ABOVE;Ll;0;L;0079 0307;;;;N;;;1E8E;;1E8E +1E90;LATIN CAPITAL LETTER Z WITH CIRCUMFLEX;Lu;0;L;005A 0302;;;;N;;;;1E91; +1E91;LATIN SMALL LETTER Z WITH CIRCUMFLEX;Ll;0;L;007A 0302;;;;N;;;1E90;;1E90 +1E92;LATIN CAPITAL LETTER Z WITH DOT BELOW;Lu;0;L;005A 0323;;;;N;;;;1E93; +1E93;LATIN SMALL LETTER Z WITH DOT BELOW;Ll;0;L;007A 0323;;;;N;;;1E92;;1E92 +1E94;LATIN CAPITAL LETTER Z WITH LINE BELOW;Lu;0;L;005A 0331;;;;N;;;;1E95; +1E95;LATIN SMALL LETTER Z WITH LINE BELOW;Ll;0;L;007A 0331;;;;N;;;1E94;;1E94 +1E96;LATIN SMALL LETTER H WITH LINE BELOW;Ll;0;L;0068 0331;;;;N;;;;; +1E97;LATIN SMALL LETTER T WITH DIAERESIS;Ll;0;L;0074 0308;;;;N;;;;; +1E98;LATIN SMALL LETTER W WITH RING ABOVE;Ll;0;L;0077 030A;;;;N;;;;; +1E99;LATIN SMALL LETTER Y WITH RING ABOVE;Ll;0;L;0079 030A;;;;N;;;;; +1E9A;LATIN SMALL LETTER A WITH RIGHT HALF RING;Ll;0;L; 0061 02BE;;;;N;;;;; +1E9B;LATIN SMALL LETTER LONG S WITH DOT ABOVE;Ll;0;L;017F 0307;;;;N;;;1E60;;1E60 +1EA0;LATIN CAPITAL LETTER A WITH DOT BELOW;Lu;0;L;0041 0323;;;;N;;;;1EA1; +1EA1;LATIN SMALL LETTER A WITH DOT BELOW;Ll;0;L;0061 0323;;;;N;;;1EA0;;1EA0 +1EA2;LATIN CAPITAL LETTER A WITH HOOK ABOVE;Lu;0;L;0041 0309;;;;N;;;;1EA3; +1EA3;LATIN SMALL LETTER A WITH HOOK ABOVE;Ll;0;L;0061 0309;;;;N;;;1EA2;;1EA2 +1EA4;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00C2 0301;;;;N;;;;1EA5; +1EA5;LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00E2 0301;;;;N;;;1EA4;;1EA4 +1EA6;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00C2 0300;;;;N;;;;1EA7; +1EA7;LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00E2 0300;;;;N;;;1EA6;;1EA6 +1EA8;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00C2 0309;;;;N;;;;1EA9; +1EA9;LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00E2 0309;;;;N;;;1EA8;;1EA8 +1EAA;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE;Lu;0;L;00C2 0303;;;;N;;;;1EAB; +1EAB;LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE;Ll;0;L;00E2 0303;;;;N;;;1EAA;;1EAA +1EAC;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1EA0 0302;;;;N;;;;1EAD; +1EAD;LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1EA1 0302;;;;N;;;1EAC;;1EAC +1EAE;LATIN CAPITAL LETTER A WITH BREVE AND ACUTE;Lu;0;L;0102 0301;;;;N;;;;1EAF; +1EAF;LATIN SMALL LETTER A WITH BREVE AND ACUTE;Ll;0;L;0103 0301;;;;N;;;1EAE;;1EAE +1EB0;LATIN CAPITAL LETTER A WITH BREVE AND GRAVE;Lu;0;L;0102 0300;;;;N;;;;1EB1; +1EB1;LATIN SMALL LETTER A WITH BREVE AND GRAVE;Ll;0;L;0103 0300;;;;N;;;1EB0;;1EB0 +1EB2;LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE;Lu;0;L;0102 0309;;;;N;;;;1EB3; +1EB3;LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE;Ll;0;L;0103 0309;;;;N;;;1EB2;;1EB2 +1EB4;LATIN CAPITAL LETTER A WITH BREVE AND TILDE;Lu;0;L;0102 0303;;;;N;;;;1EB5; +1EB5;LATIN SMALL LETTER A WITH BREVE AND TILDE;Ll;0;L;0103 0303;;;;N;;;1EB4;;1EB4 +1EB6;LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW;Lu;0;L;1EA0 0306;;;;N;;;;1EB7; +1EB7;LATIN SMALL LETTER A WITH BREVE AND DOT BELOW;Ll;0;L;1EA1 0306;;;;N;;;1EB6;;1EB6 +1EB8;LATIN CAPITAL LETTER E WITH DOT BELOW;Lu;0;L;0045 0323;;;;N;;;;1EB9; +1EB9;LATIN SMALL LETTER E WITH DOT BELOW;Ll;0;L;0065 0323;;;;N;;;1EB8;;1EB8 +1EBA;LATIN CAPITAL LETTER E WITH HOOK ABOVE;Lu;0;L;0045 0309;;;;N;;;;1EBB; +1EBB;LATIN SMALL LETTER E WITH HOOK ABOVE;Ll;0;L;0065 0309;;;;N;;;1EBA;;1EBA +1EBC;LATIN CAPITAL LETTER E WITH TILDE;Lu;0;L;0045 0303;;;;N;;;;1EBD; +1EBD;LATIN SMALL LETTER E WITH TILDE;Ll;0;L;0065 0303;;;;N;;;1EBC;;1EBC +1EBE;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00CA 0301;;;;N;;;;1EBF; +1EBF;LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00EA 0301;;;;N;;;1EBE;;1EBE +1EC0;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00CA 0300;;;;N;;;;1EC1; +1EC1;LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00EA 0300;;;;N;;;1EC0;;1EC0 +1EC2;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00CA 0309;;;;N;;;;1EC3; +1EC3;LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00EA 0309;;;;N;;;1EC2;;1EC2 +1EC4;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE;Lu;0;L;00CA 0303;;;;N;;;;1EC5; +1EC5;LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE;Ll;0;L;00EA 0303;;;;N;;;1EC4;;1EC4 +1EC6;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1EB8 0302;;;;N;;;;1EC7; +1EC7;LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1EB9 0302;;;;N;;;1EC6;;1EC6 +1EC8;LATIN CAPITAL LETTER I WITH HOOK ABOVE;Lu;0;L;0049 0309;;;;N;;;;1EC9; +1EC9;LATIN SMALL LETTER I WITH HOOK ABOVE;Ll;0;L;0069 0309;;;;N;;;1EC8;;1EC8 +1ECA;LATIN CAPITAL LETTER I WITH DOT BELOW;Lu;0;L;0049 0323;;;;N;;;;1ECB; +1ECB;LATIN SMALL LETTER I WITH DOT BELOW;Ll;0;L;0069 0323;;;;N;;;1ECA;;1ECA +1ECC;LATIN CAPITAL LETTER O WITH DOT BELOW;Lu;0;L;004F 0323;;;;N;;;;1ECD; +1ECD;LATIN SMALL LETTER O WITH DOT BELOW;Ll;0;L;006F 0323;;;;N;;;1ECC;;1ECC +1ECE;LATIN CAPITAL LETTER O WITH HOOK ABOVE;Lu;0;L;004F 0309;;;;N;;;;1ECF; +1ECF;LATIN SMALL LETTER O WITH HOOK ABOVE;Ll;0;L;006F 0309;;;;N;;;1ECE;;1ECE +1ED0;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00D4 0301;;;;N;;;;1ED1; +1ED1;LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00F4 0301;;;;N;;;1ED0;;1ED0 +1ED2;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00D4 0300;;;;N;;;;1ED3; +1ED3;LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00F4 0300;;;;N;;;1ED2;;1ED2 +1ED4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00D4 0309;;;;N;;;;1ED5; +1ED5;LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00F4 0309;;;;N;;;1ED4;;1ED4 +1ED6;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE;Lu;0;L;00D4 0303;;;;N;;;;1ED7; +1ED7;LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE;Ll;0;L;00F4 0303;;;;N;;;1ED6;;1ED6 +1ED8;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1ECC 0302;;;;N;;;;1ED9; +1ED9;LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1ECD 0302;;;;N;;;1ED8;;1ED8 +1EDA;LATIN CAPITAL LETTER O WITH HORN AND ACUTE;Lu;0;L;01A0 0301;;;;N;;;;1EDB; +1EDB;LATIN SMALL LETTER O WITH HORN AND ACUTE;Ll;0;L;01A1 0301;;;;N;;;1EDA;;1EDA +1EDC;LATIN CAPITAL LETTER O WITH HORN AND GRAVE;Lu;0;L;01A0 0300;;;;N;;;;1EDD; +1EDD;LATIN SMALL LETTER O WITH HORN AND GRAVE;Ll;0;L;01A1 0300;;;;N;;;1EDC;;1EDC +1EDE;LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE;Lu;0;L;01A0 0309;;;;N;;;;1EDF; +1EDF;LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE;Ll;0;L;01A1 0309;;;;N;;;1EDE;;1EDE +1EE0;LATIN CAPITAL LETTER O WITH HORN AND TILDE;Lu;0;L;01A0 0303;;;;N;;;;1EE1; +1EE1;LATIN SMALL LETTER O WITH HORN AND TILDE;Ll;0;L;01A1 0303;;;;N;;;1EE0;;1EE0 +1EE2;LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW;Lu;0;L;01A0 0323;;;;N;;;;1EE3; +1EE3;LATIN SMALL LETTER O WITH HORN AND DOT BELOW;Ll;0;L;01A1 0323;;;;N;;;1EE2;;1EE2 +1EE4;LATIN CAPITAL LETTER U WITH DOT BELOW;Lu;0;L;0055 0323;;;;N;;;;1EE5; +1EE5;LATIN SMALL LETTER U WITH DOT BELOW;Ll;0;L;0075 0323;;;;N;;;1EE4;;1EE4 +1EE6;LATIN CAPITAL LETTER U WITH HOOK ABOVE;Lu;0;L;0055 0309;;;;N;;;;1EE7; +1EE7;LATIN SMALL LETTER U WITH HOOK ABOVE;Ll;0;L;0075 0309;;;;N;;;1EE6;;1EE6 +1EE8;LATIN CAPITAL LETTER U WITH HORN AND ACUTE;Lu;0;L;01AF 0301;;;;N;;;;1EE9; +1EE9;LATIN SMALL LETTER U WITH HORN AND ACUTE;Ll;0;L;01B0 0301;;;;N;;;1EE8;;1EE8 +1EEA;LATIN CAPITAL LETTER U WITH HORN AND GRAVE;Lu;0;L;01AF 0300;;;;N;;;;1EEB; +1EEB;LATIN SMALL LETTER U WITH HORN AND GRAVE;Ll;0;L;01B0 0300;;;;N;;;1EEA;;1EEA +1EEC;LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE;Lu;0;L;01AF 0309;;;;N;;;;1EED; +1EED;LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE;Ll;0;L;01B0 0309;;;;N;;;1EEC;;1EEC +1EEE;LATIN CAPITAL LETTER U WITH HORN AND TILDE;Lu;0;L;01AF 0303;;;;N;;;;1EEF; +1EEF;LATIN SMALL LETTER U WITH HORN AND TILDE;Ll;0;L;01B0 0303;;;;N;;;1EEE;;1EEE +1EF0;LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW;Lu;0;L;01AF 0323;;;;N;;;;1EF1; +1EF1;LATIN SMALL LETTER U WITH HORN AND DOT BELOW;Ll;0;L;01B0 0323;;;;N;;;1EF0;;1EF0 +1EF2;LATIN CAPITAL LETTER Y WITH GRAVE;Lu;0;L;0059 0300;;;;N;;;;1EF3; +1EF3;LATIN SMALL LETTER Y WITH GRAVE;Ll;0;L;0079 0300;;;;N;;;1EF2;;1EF2 +1EF4;LATIN CAPITAL LETTER Y WITH DOT BELOW;Lu;0;L;0059 0323;;;;N;;;;1EF5; +1EF5;LATIN SMALL LETTER Y WITH DOT BELOW;Ll;0;L;0079 0323;;;;N;;;1EF4;;1EF4 +1EF6;LATIN CAPITAL LETTER Y WITH HOOK ABOVE;Lu;0;L;0059 0309;;;;N;;;;1EF7; +1EF7;LATIN SMALL LETTER Y WITH HOOK ABOVE;Ll;0;L;0079 0309;;;;N;;;1EF6;;1EF6 +1EF8;LATIN CAPITAL LETTER Y WITH TILDE;Lu;0;L;0059 0303;;;;N;;;;1EF9; +1EF9;LATIN SMALL LETTER Y WITH TILDE;Ll;0;L;0079 0303;;;;N;;;1EF8;;1EF8 +1F00;GREEK SMALL LETTER ALPHA WITH PSILI;Ll;0;L;03B1 0313;;;;N;;;1F08;;1F08 +1F01;GREEK SMALL LETTER ALPHA WITH DASIA;Ll;0;L;03B1 0314;;;;N;;;1F09;;1F09 +1F02;GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA;Ll;0;L;1F00 0300;;;;N;;;1F0A;;1F0A +1F03;GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA;Ll;0;L;1F01 0300;;;;N;;;1F0B;;1F0B +1F04;GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA;Ll;0;L;1F00 0301;;;;N;;;1F0C;;1F0C +1F05;GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA;Ll;0;L;1F01 0301;;;;N;;;1F0D;;1F0D +1F06;GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI;Ll;0;L;1F00 0342;;;;N;;;1F0E;;1F0E +1F07;GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI;Ll;0;L;1F01 0342;;;;N;;;1F0F;;1F0F +1F08;GREEK CAPITAL LETTER ALPHA WITH PSILI;Lu;0;L;0391 0313;;;;N;;;;1F00; +1F09;GREEK CAPITAL LETTER ALPHA WITH DASIA;Lu;0;L;0391 0314;;;;N;;;;1F01; +1F0A;GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA;Lu;0;L;1F08 0300;;;;N;;;;1F02; +1F0B;GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA;Lu;0;L;1F09 0300;;;;N;;;;1F03; +1F0C;GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA;Lu;0;L;1F08 0301;;;;N;;;;1F04; +1F0D;GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA;Lu;0;L;1F09 0301;;;;N;;;;1F05; +1F0E;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI;Lu;0;L;1F08 0342;;;;N;;;;1F06; +1F0F;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI;Lu;0;L;1F09 0342;;;;N;;;;1F07; +1F10;GREEK SMALL LETTER EPSILON WITH PSILI;Ll;0;L;03B5 0313;;;;N;;;1F18;;1F18 +1F11;GREEK SMALL LETTER EPSILON WITH DASIA;Ll;0;L;03B5 0314;;;;N;;;1F19;;1F19 +1F12;GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA;Ll;0;L;1F10 0300;;;;N;;;1F1A;;1F1A +1F13;GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA;Ll;0;L;1F11 0300;;;;N;;;1F1B;;1F1B +1F14;GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA;Ll;0;L;1F10 0301;;;;N;;;1F1C;;1F1C +1F15;GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA;Ll;0;L;1F11 0301;;;;N;;;1F1D;;1F1D +1F18;GREEK CAPITAL LETTER EPSILON WITH PSILI;Lu;0;L;0395 0313;;;;N;;;;1F10; +1F19;GREEK CAPITAL LETTER EPSILON WITH DASIA;Lu;0;L;0395 0314;;;;N;;;;1F11; +1F1A;GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA;Lu;0;L;1F18 0300;;;;N;;;;1F12; +1F1B;GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA;Lu;0;L;1F19 0300;;;;N;;;;1F13; +1F1C;GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA;Lu;0;L;1F18 0301;;;;N;;;;1F14; +1F1D;GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA;Lu;0;L;1F19 0301;;;;N;;;;1F15; +1F20;GREEK SMALL LETTER ETA WITH PSILI;Ll;0;L;03B7 0313;;;;N;;;1F28;;1F28 +1F21;GREEK SMALL LETTER ETA WITH DASIA;Ll;0;L;03B7 0314;;;;N;;;1F29;;1F29 +1F22;GREEK SMALL LETTER ETA WITH PSILI AND VARIA;Ll;0;L;1F20 0300;;;;N;;;1F2A;;1F2A +1F23;GREEK SMALL LETTER ETA WITH DASIA AND VARIA;Ll;0;L;1F21 0300;;;;N;;;1F2B;;1F2B +1F24;GREEK SMALL LETTER ETA WITH PSILI AND OXIA;Ll;0;L;1F20 0301;;;;N;;;1F2C;;1F2C +1F25;GREEK SMALL LETTER ETA WITH DASIA AND OXIA;Ll;0;L;1F21 0301;;;;N;;;1F2D;;1F2D +1F26;GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI;Ll;0;L;1F20 0342;;;;N;;;1F2E;;1F2E +1F27;GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI;Ll;0;L;1F21 0342;;;;N;;;1F2F;;1F2F +1F28;GREEK CAPITAL LETTER ETA WITH PSILI;Lu;0;L;0397 0313;;;;N;;;;1F20; +1F29;GREEK CAPITAL LETTER ETA WITH DASIA;Lu;0;L;0397 0314;;;;N;;;;1F21; +1F2A;GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA;Lu;0;L;1F28 0300;;;;N;;;;1F22; +1F2B;GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA;Lu;0;L;1F29 0300;;;;N;;;;1F23; +1F2C;GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA;Lu;0;L;1F28 0301;;;;N;;;;1F24; +1F2D;GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA;Lu;0;L;1F29 0301;;;;N;;;;1F25; +1F2E;GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI;Lu;0;L;1F28 0342;;;;N;;;;1F26; +1F2F;GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI;Lu;0;L;1F29 0342;;;;N;;;;1F27; +1F30;GREEK SMALL LETTER IOTA WITH PSILI;Ll;0;L;03B9 0313;;;;N;;;1F38;;1F38 +1F31;GREEK SMALL LETTER IOTA WITH DASIA;Ll;0;L;03B9 0314;;;;N;;;1F39;;1F39 +1F32;GREEK SMALL LETTER IOTA WITH PSILI AND VARIA;Ll;0;L;1F30 0300;;;;N;;;1F3A;;1F3A +1F33;GREEK SMALL LETTER IOTA WITH DASIA AND VARIA;Ll;0;L;1F31 0300;;;;N;;;1F3B;;1F3B +1F34;GREEK SMALL LETTER IOTA WITH PSILI AND OXIA;Ll;0;L;1F30 0301;;;;N;;;1F3C;;1F3C +1F35;GREEK SMALL LETTER IOTA WITH DASIA AND OXIA;Ll;0;L;1F31 0301;;;;N;;;1F3D;;1F3D +1F36;GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI;Ll;0;L;1F30 0342;;;;N;;;1F3E;;1F3E +1F37;GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI;Ll;0;L;1F31 0342;;;;N;;;1F3F;;1F3F +1F38;GREEK CAPITAL LETTER IOTA WITH PSILI;Lu;0;L;0399 0313;;;;N;;;;1F30; +1F39;GREEK CAPITAL LETTER IOTA WITH DASIA;Lu;0;L;0399 0314;;;;N;;;;1F31; +1F3A;GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA;Lu;0;L;1F38 0300;;;;N;;;;1F32; +1F3B;GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA;Lu;0;L;1F39 0300;;;;N;;;;1F33; +1F3C;GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA;Lu;0;L;1F38 0301;;;;N;;;;1F34; +1F3D;GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA;Lu;0;L;1F39 0301;;;;N;;;;1F35; +1F3E;GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI;Lu;0;L;1F38 0342;;;;N;;;;1F36; +1F3F;GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI;Lu;0;L;1F39 0342;;;;N;;;;1F37; +1F40;GREEK SMALL LETTER OMICRON WITH PSILI;Ll;0;L;03BF 0313;;;;N;;;1F48;;1F48 +1F41;GREEK SMALL LETTER OMICRON WITH DASIA;Ll;0;L;03BF 0314;;;;N;;;1F49;;1F49 +1F42;GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA;Ll;0;L;1F40 0300;;;;N;;;1F4A;;1F4A +1F43;GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA;Ll;0;L;1F41 0300;;;;N;;;1F4B;;1F4B +1F44;GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA;Ll;0;L;1F40 0301;;;;N;;;1F4C;;1F4C +1F45;GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA;Ll;0;L;1F41 0301;;;;N;;;1F4D;;1F4D +1F48;GREEK CAPITAL LETTER OMICRON WITH PSILI;Lu;0;L;039F 0313;;;;N;;;;1F40; +1F49;GREEK CAPITAL LETTER OMICRON WITH DASIA;Lu;0;L;039F 0314;;;;N;;;;1F41; +1F4A;GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA;Lu;0;L;1F48 0300;;;;N;;;;1F42; +1F4B;GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA;Lu;0;L;1F49 0300;;;;N;;;;1F43; +1F4C;GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA;Lu;0;L;1F48 0301;;;;N;;;;1F44; +1F4D;GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA;Lu;0;L;1F49 0301;;;;N;;;;1F45; +1F50;GREEK SMALL LETTER UPSILON WITH PSILI;Ll;0;L;03C5 0313;;;;N;;;;; +1F51;GREEK SMALL LETTER UPSILON WITH DASIA;Ll;0;L;03C5 0314;;;;N;;;1F59;;1F59 +1F52;GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA;Ll;0;L;1F50 0300;;;;N;;;;; +1F53;GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA;Ll;0;L;1F51 0300;;;;N;;;1F5B;;1F5B +1F54;GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA;Ll;0;L;1F50 0301;;;;N;;;;; +1F55;GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA;Ll;0;L;1F51 0301;;;;N;;;1F5D;;1F5D +1F56;GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI;Ll;0;L;1F50 0342;;;;N;;;;; +1F57;GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI;Ll;0;L;1F51 0342;;;;N;;;1F5F;;1F5F +1F59;GREEK CAPITAL LETTER UPSILON WITH DASIA;Lu;0;L;03A5 0314;;;;N;;;;1F51; +1F5B;GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA;Lu;0;L;1F59 0300;;;;N;;;;1F53; +1F5D;GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA;Lu;0;L;1F59 0301;;;;N;;;;1F55; +1F5F;GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI;Lu;0;L;1F59 0342;;;;N;;;;1F57; +1F60;GREEK SMALL LETTER OMEGA WITH PSILI;Ll;0;L;03C9 0313;;;;N;;;1F68;;1F68 +1F61;GREEK SMALL LETTER OMEGA WITH DASIA;Ll;0;L;03C9 0314;;;;N;;;1F69;;1F69 +1F62;GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA;Ll;0;L;1F60 0300;;;;N;;;1F6A;;1F6A +1F63;GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA;Ll;0;L;1F61 0300;;;;N;;;1F6B;;1F6B +1F64;GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA;Ll;0;L;1F60 0301;;;;N;;;1F6C;;1F6C +1F65;GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA;Ll;0;L;1F61 0301;;;;N;;;1F6D;;1F6D +1F66;GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI;Ll;0;L;1F60 0342;;;;N;;;1F6E;;1F6E +1F67;GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI;Ll;0;L;1F61 0342;;;;N;;;1F6F;;1F6F +1F68;GREEK CAPITAL LETTER OMEGA WITH PSILI;Lu;0;L;03A9 0313;;;;N;;;;1F60; +1F69;GREEK CAPITAL LETTER OMEGA WITH DASIA;Lu;0;L;03A9 0314;;;;N;;;;1F61; +1F6A;GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA;Lu;0;L;1F68 0300;;;;N;;;;1F62; +1F6B;GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA;Lu;0;L;1F69 0300;;;;N;;;;1F63; +1F6C;GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA;Lu;0;L;1F68 0301;;;;N;;;;1F64; +1F6D;GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA;Lu;0;L;1F69 0301;;;;N;;;;1F65; +1F6E;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI;Lu;0;L;1F68 0342;;;;N;;;;1F66; +1F6F;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI;Lu;0;L;1F69 0342;;;;N;;;;1F67; +1F70;GREEK SMALL LETTER ALPHA WITH VARIA;Ll;0;L;03B1 0300;;;;N;;;1FBA;;1FBA +1F71;GREEK SMALL LETTER ALPHA WITH OXIA;Ll;0;L;03AC;;;;N;;;1FBB;;1FBB +1F72;GREEK SMALL LETTER EPSILON WITH VARIA;Ll;0;L;03B5 0300;;;;N;;;1FC8;;1FC8 +1F73;GREEK SMALL LETTER EPSILON WITH OXIA;Ll;0;L;03AD;;;;N;;;1FC9;;1FC9 +1F74;GREEK SMALL LETTER ETA WITH VARIA;Ll;0;L;03B7 0300;;;;N;;;1FCA;;1FCA +1F75;GREEK SMALL LETTER ETA WITH OXIA;Ll;0;L;03AE;;;;N;;;1FCB;;1FCB +1F76;GREEK SMALL LETTER IOTA WITH VARIA;Ll;0;L;03B9 0300;;;;N;;;1FDA;;1FDA +1F77;GREEK SMALL LETTER IOTA WITH OXIA;Ll;0;L;03AF;;;;N;;;1FDB;;1FDB +1F78;GREEK SMALL LETTER OMICRON WITH VARIA;Ll;0;L;03BF 0300;;;;N;;;1FF8;;1FF8 +1F79;GREEK SMALL LETTER OMICRON WITH OXIA;Ll;0;L;03CC;;;;N;;;1FF9;;1FF9 +1F7A;GREEK SMALL LETTER UPSILON WITH VARIA;Ll;0;L;03C5 0300;;;;N;;;1FEA;;1FEA +1F7B;GREEK SMALL LETTER UPSILON WITH OXIA;Ll;0;L;03CD;;;;N;;;1FEB;;1FEB +1F7C;GREEK SMALL LETTER OMEGA WITH VARIA;Ll;0;L;03C9 0300;;;;N;;;1FFA;;1FFA +1F7D;GREEK SMALL LETTER OMEGA WITH OXIA;Ll;0;L;03CE;;;;N;;;1FFB;;1FFB +1F80;GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F00 0345;;;;N;;;1F88;;1F88 +1F81;GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F01 0345;;;;N;;;1F89;;1F89 +1F82;GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F02 0345;;;;N;;;1F8A;;1F8A +1F83;GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F03 0345;;;;N;;;1F8B;;1F8B +1F84;GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F04 0345;;;;N;;;1F8C;;1F8C +1F85;GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F05 0345;;;;N;;;1F8D;;1F8D +1F86;GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F06 0345;;;;N;;;1F8E;;1F8E +1F87;GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F07 0345;;;;N;;;1F8F;;1F8F +1F88;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F08 0345;;;;N;;;;1F80; +1F89;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F09 0345;;;;N;;;;1F81; +1F8A;GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F0A 0345;;;;N;;;;1F82; +1F8B;GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F0B 0345;;;;N;;;;1F83; +1F8C;GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F0C 0345;;;;N;;;;1F84; +1F8D;GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F0D 0345;;;;N;;;;1F85; +1F8E;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F0E 0345;;;;N;;;;1F86; +1F8F;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F0F 0345;;;;N;;;;1F87; +1F90;GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F20 0345;;;;N;;;1F98;;1F98 +1F91;GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F21 0345;;;;N;;;1F99;;1F99 +1F92;GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F22 0345;;;;N;;;1F9A;;1F9A +1F93;GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F23 0345;;;;N;;;1F9B;;1F9B +1F94;GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F24 0345;;;;N;;;1F9C;;1F9C +1F95;GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F25 0345;;;;N;;;1F9D;;1F9D +1F96;GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F26 0345;;;;N;;;1F9E;;1F9E +1F97;GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F27 0345;;;;N;;;1F9F;;1F9F +1F98;GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F28 0345;;;;N;;;;1F90; +1F99;GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F29 0345;;;;N;;;;1F91; +1F9A;GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F2A 0345;;;;N;;;;1F92; +1F9B;GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F2B 0345;;;;N;;;;1F93; +1F9C;GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F2C 0345;;;;N;;;;1F94; +1F9D;GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F2D 0345;;;;N;;;;1F95; +1F9E;GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F2E 0345;;;;N;;;;1F96; +1F9F;GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F2F 0345;;;;N;;;;1F97; +1FA0;GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F60 0345;;;;N;;;1FA8;;1FA8 +1FA1;GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F61 0345;;;;N;;;1FA9;;1FA9 +1FA2;GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F62 0345;;;;N;;;1FAA;;1FAA +1FA3;GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F63 0345;;;;N;;;1FAB;;1FAB +1FA4;GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F64 0345;;;;N;;;1FAC;;1FAC +1FA5;GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F65 0345;;;;N;;;1FAD;;1FAD +1FA6;GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F66 0345;;;;N;;;1FAE;;1FAE +1FA7;GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F67 0345;;;;N;;;1FAF;;1FAF +1FA8;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F68 0345;;;;N;;;;1FA0; +1FA9;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F69 0345;;;;N;;;;1FA1; +1FAA;GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F6A 0345;;;;N;;;;1FA2; +1FAB;GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F6B 0345;;;;N;;;;1FA3; +1FAC;GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F6C 0345;;;;N;;;;1FA4; +1FAD;GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F6D 0345;;;;N;;;;1FA5; +1FAE;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F6E 0345;;;;N;;;;1FA6; +1FAF;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F6F 0345;;;;N;;;;1FA7; +1FB0;GREEK SMALL LETTER ALPHA WITH VRACHY;Ll;0;L;03B1 0306;;;;N;;;1FB8;;1FB8 +1FB1;GREEK SMALL LETTER ALPHA WITH MACRON;Ll;0;L;03B1 0304;;;;N;;;1FB9;;1FB9 +1FB2;GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F70 0345;;;;N;;;;; +1FB3;GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI;Ll;0;L;03B1 0345;;;;N;;;1FBC;;1FBC +1FB4;GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03AC 0345;;;;N;;;;; +1FB6;GREEK SMALL LETTER ALPHA WITH PERISPOMENI;Ll;0;L;03B1 0342;;;;N;;;;; +1FB7;GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FB6 0345;;;;N;;;;; +1FB8;GREEK CAPITAL LETTER ALPHA WITH VRACHY;Lu;0;L;0391 0306;;;;N;;;;1FB0; +1FB9;GREEK CAPITAL LETTER ALPHA WITH MACRON;Lu;0;L;0391 0304;;;;N;;;;1FB1; +1FBA;GREEK CAPITAL LETTER ALPHA WITH VARIA;Lu;0;L;0391 0300;;;;N;;;;1F70; +1FBB;GREEK CAPITAL LETTER ALPHA WITH OXIA;Lu;0;L;0386;;;;N;;;;1F71; +1FBC;GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI;Lt;0;L;0391 0345;;;;N;;;;1FB3; +1FBD;GREEK KORONIS;Sk;0;ON; 0020 0313;;;;N;;;;; +1FBE;GREEK PROSGEGRAMMENI;Ll;0;L;03B9;;;;N;;;0399;;0399 +1FBF;GREEK PSILI;Sk;0;ON; 0020 0313;;;;N;;;;; +1FC0;GREEK PERISPOMENI;Sk;0;ON; 0020 0342;;;;N;;;;; +1FC1;GREEK DIALYTIKA AND PERISPOMENI;Sk;0;ON;00A8 0342;;;;N;;;;; +1FC2;GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F74 0345;;;;N;;;;; +1FC3;GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI;Ll;0;L;03B7 0345;;;;N;;;1FCC;;1FCC +1FC4;GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03AE 0345;;;;N;;;;; +1FC6;GREEK SMALL LETTER ETA WITH PERISPOMENI;Ll;0;L;03B7 0342;;;;N;;;;; +1FC7;GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FC6 0345;;;;N;;;;; +1FC8;GREEK CAPITAL LETTER EPSILON WITH VARIA;Lu;0;L;0395 0300;;;;N;;;;1F72; +1FC9;GREEK CAPITAL LETTER EPSILON WITH OXIA;Lu;0;L;0388;;;;N;;;;1F73; +1FCA;GREEK CAPITAL LETTER ETA WITH VARIA;Lu;0;L;0397 0300;;;;N;;;;1F74; +1FCB;GREEK CAPITAL LETTER ETA WITH OXIA;Lu;0;L;0389;;;;N;;;;1F75; +1FCC;GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI;Lt;0;L;0397 0345;;;;N;;;;1FC3; +1FCD;GREEK PSILI AND VARIA;Sk;0;ON;1FBF 0300;;;;N;;;;; +1FCE;GREEK PSILI AND OXIA;Sk;0;ON;1FBF 0301;;;;N;;;;; +1FCF;GREEK PSILI AND PERISPOMENI;Sk;0;ON;1FBF 0342;;;;N;;;;; +1FD0;GREEK SMALL LETTER IOTA WITH VRACHY;Ll;0;L;03B9 0306;;;;N;;;1FD8;;1FD8 +1FD1;GREEK SMALL LETTER IOTA WITH MACRON;Ll;0;L;03B9 0304;;;;N;;;1FD9;;1FD9 +1FD2;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA;Ll;0;L;03CA 0300;;;;N;;;;; +1FD3;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA;Ll;0;L;0390;;;;N;;;;; +1FD6;GREEK SMALL LETTER IOTA WITH PERISPOMENI;Ll;0;L;03B9 0342;;;;N;;;;; +1FD7;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI;Ll;0;L;03CA 0342;;;;N;;;;; +1FD8;GREEK CAPITAL LETTER IOTA WITH VRACHY;Lu;0;L;0399 0306;;;;N;;;;1FD0; +1FD9;GREEK CAPITAL LETTER IOTA WITH MACRON;Lu;0;L;0399 0304;;;;N;;;;1FD1; +1FDA;GREEK CAPITAL LETTER IOTA WITH VARIA;Lu;0;L;0399 0300;;;;N;;;;1F76; +1FDB;GREEK CAPITAL LETTER IOTA WITH OXIA;Lu;0;L;038A;;;;N;;;;1F77; +1FDD;GREEK DASIA AND VARIA;Sk;0;ON;1FFE 0300;;;;N;;;;; +1FDE;GREEK DASIA AND OXIA;Sk;0;ON;1FFE 0301;;;;N;;;;; +1FDF;GREEK DASIA AND PERISPOMENI;Sk;0;ON;1FFE 0342;;;;N;;;;; +1FE0;GREEK SMALL LETTER UPSILON WITH VRACHY;Ll;0;L;03C5 0306;;;;N;;;1FE8;;1FE8 +1FE1;GREEK SMALL LETTER UPSILON WITH MACRON;Ll;0;L;03C5 0304;;;;N;;;1FE9;;1FE9 +1FE2;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA;Ll;0;L;03CB 0300;;;;N;;;;; +1FE3;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA;Ll;0;L;03B0;;;;N;;;;; +1FE4;GREEK SMALL LETTER RHO WITH PSILI;Ll;0;L;03C1 0313;;;;N;;;;; +1FE5;GREEK SMALL LETTER RHO WITH DASIA;Ll;0;L;03C1 0314;;;;N;;;1FEC;;1FEC +1FE6;GREEK SMALL LETTER UPSILON WITH PERISPOMENI;Ll;0;L;03C5 0342;;;;N;;;;; +1FE7;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI;Ll;0;L;03CB 0342;;;;N;;;;; +1FE8;GREEK CAPITAL LETTER UPSILON WITH VRACHY;Lu;0;L;03A5 0306;;;;N;;;;1FE0; +1FE9;GREEK CAPITAL LETTER UPSILON WITH MACRON;Lu;0;L;03A5 0304;;;;N;;;;1FE1; +1FEA;GREEK CAPITAL LETTER UPSILON WITH VARIA;Lu;0;L;03A5 0300;;;;N;;;;1F7A; +1FEB;GREEK CAPITAL LETTER UPSILON WITH OXIA;Lu;0;L;038E;;;;N;;;;1F7B; +1FEC;GREEK CAPITAL LETTER RHO WITH DASIA;Lu;0;L;03A1 0314;;;;N;;;;1FE5; +1FED;GREEK DIALYTIKA AND VARIA;Sk;0;ON;00A8 0300;;;;N;;;;; +1FEE;GREEK DIALYTIKA AND OXIA;Sk;0;ON;0385;;;;N;;;;; +1FEF;GREEK VARIA;Sk;0;ON;0060;;;;N;;;;; +1FF2;GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F7C 0345;;;;N;;;;; +1FF3;GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI;Ll;0;L;03C9 0345;;;;N;;;1FFC;;1FFC +1FF4;GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03CE 0345;;;;N;;;;; +1FF6;GREEK SMALL LETTER OMEGA WITH PERISPOMENI;Ll;0;L;03C9 0342;;;;N;;;;; +1FF7;GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FF6 0345;;;;N;;;;; +1FF8;GREEK CAPITAL LETTER OMICRON WITH VARIA;Lu;0;L;039F 0300;;;;N;;;;1F78; +1FF9;GREEK CAPITAL LETTER OMICRON WITH OXIA;Lu;0;L;038C;;;;N;;;;1F79; +1FFA;GREEK CAPITAL LETTER OMEGA WITH VARIA;Lu;0;L;03A9 0300;;;;N;;;;1F7C; +1FFB;GREEK CAPITAL LETTER OMEGA WITH OXIA;Lu;0;L;038F;;;;N;;;;1F7D; +1FFC;GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI;Lt;0;L;03A9 0345;;;;N;;;;1FF3; +1FFD;GREEK OXIA;Sk;0;ON;00B4;;;;N;;;;; +1FFE;GREEK DASIA;Sk;0;ON; 0020 0314;;;;N;;;;; +2000;EN QUAD;Zs;0;WS;2002;;;;N;;;;; +2001;EM QUAD;Zs;0;WS;2003;;;;N;;;;; +2002;EN SPACE;Zs;0;WS; 0020;;;;N;;;;; +2003;EM SPACE;Zs;0;WS; 0020;;;;N;;;;; +2004;THREE-PER-EM SPACE;Zs;0;WS; 0020;;;;N;;;;; +2005;FOUR-PER-EM SPACE;Zs;0;WS; 0020;;;;N;;;;; +2006;SIX-PER-EM SPACE;Zs;0;WS; 0020;;;;N;;;;; +2007;FIGURE SPACE;Zs;0;WS; 0020;;;;N;;;;; +2008;PUNCTUATION SPACE;Zs;0;WS; 0020;;;;N;;;;; +2009;THIN SPACE;Zs;0;WS; 0020;;;;N;;;;; +200A;HAIR SPACE;Zs;0;WS; 0020;;;;N;;;;; +200B;ZERO WIDTH SPACE;Zs;0;BN;;;;;N;;;;; +200C;ZERO WIDTH NON-JOINER;Cf;0;BN;;;;;N;;;;; +200D;ZERO WIDTH JOINER;Cf;0;BN;;;;;N;;;;; +200E;LEFT-TO-RIGHT MARK;Cf;0;L;;;;;N;;;;; +200F;RIGHT-TO-LEFT MARK;Cf;0;R;;;;;N;;;;; +2010;HYPHEN;Pd;0;ON;;;;;N;;;;; +2011;NON-BREAKING HYPHEN;Pd;0;ON; 2010;;;;N;;;;; +2012;FIGURE DASH;Pd;0;ON;;;;;N;;;;; +2013;EN DASH;Pd;0;ON;;;;;N;;;;; +2014;EM DASH;Pd;0;ON;;;;;N;;;;; +2015;HORIZONTAL BAR;Pd;0;ON;;;;;N;QUOTATION DASH;;;; +2016;DOUBLE VERTICAL LINE;Po;0;ON;;;;;N;DOUBLE VERTICAL BAR;;;; +2017;DOUBLE LOW LINE;Po;0;ON; 0020 0333;;;;N;SPACING DOUBLE UNDERSCORE;;;; +2018;LEFT SINGLE QUOTATION MARK;Pi;0;ON;;;;;N;SINGLE TURNED COMMA QUOTATION MARK;;;; +2019;RIGHT SINGLE QUOTATION MARK;Pf;0;ON;;;;;N;SINGLE COMMA QUOTATION MARK;;;; +201A;SINGLE LOW-9 QUOTATION MARK;Ps;0;ON;;;;;N;LOW SINGLE COMMA QUOTATION MARK;;;; +201B;SINGLE HIGH-REVERSED-9 QUOTATION MARK;Pi;0;ON;;;;;N;SINGLE REVERSED COMMA QUOTATION MARK;;;; +201C;LEFT DOUBLE QUOTATION MARK;Pi;0;ON;;;;;N;DOUBLE TURNED COMMA QUOTATION MARK;;;; +201D;RIGHT DOUBLE QUOTATION MARK;Pf;0;ON;;;;;N;DOUBLE COMMA QUOTATION MARK;;;; +201E;DOUBLE LOW-9 QUOTATION MARK;Ps;0;ON;;;;;N;LOW DOUBLE COMMA QUOTATION MARK;;;; +201F;DOUBLE HIGH-REVERSED-9 QUOTATION MARK;Pi;0;ON;;;;;N;DOUBLE REVERSED COMMA QUOTATION MARK;;;; +2020;DAGGER;Po;0;ON;;;;;N;;;;; +2021;DOUBLE DAGGER;Po;0;ON;;;;;N;;;;; +2022;BULLET;Po;0;ON;;;;;N;;;;; +2023;TRIANGULAR BULLET;Po;0;ON;;;;;N;;;;; +2024;ONE DOT LEADER;Po;0;ON; 002E;;;;N;;;;; +2025;TWO DOT LEADER;Po;0;ON; 002E 002E;;;;N;;;;; +2026;HORIZONTAL ELLIPSIS;Po;0;ON; 002E 002E 002E;;;;N;;;;; +2027;HYPHENATION POINT;Po;0;ON;;;;;N;;;;; +2028;LINE SEPARATOR;Zl;0;WS;;;;;N;;;;; +2029;PARAGRAPH SEPARATOR;Zp;0;B;;;;;N;;;;; +202A;LEFT-TO-RIGHT EMBEDDING;Cf;0;LRE;;;;;N;;;;; +202B;RIGHT-TO-LEFT EMBEDDING;Cf;0;RLE;;;;;N;;;;; +202C;POP DIRECTIONAL FORMATTING;Cf;0;PDF;;;;;N;;;;; +202D;LEFT-TO-RIGHT OVERRIDE;Cf;0;LRO;;;;;N;;;;; +202E;RIGHT-TO-LEFT OVERRIDE;Cf;0;RLO;;;;;N;;;;; +202F;NARROW NO-BREAK SPACE;Zs;0;WS; 0020;;;;N;;;;; +2030;PER MILLE SIGN;Po;0;ET;;;;;N;;;;; +2031;PER TEN THOUSAND SIGN;Po;0;ET;;;;;N;;;;; +2032;PRIME;Po;0;ET;;;;;N;;;;; +2033;DOUBLE PRIME;Po;0;ET; 2032 2032;;;;N;;;;; +2034;TRIPLE PRIME;Po;0;ET; 2032 2032 2032;;;;N;;;;; +2035;REVERSED PRIME;Po;0;ON;;;;;N;;;;; +2036;REVERSED DOUBLE PRIME;Po;0;ON; 2035 2035;;;;N;;;;; +2037;REVERSED TRIPLE PRIME;Po;0;ON; 2035 2035 2035;;;;N;;;;; +2038;CARET;Po;0;ON;;;;;N;;;;; +2039;SINGLE LEFT-POINTING ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING SINGLE GUILLEMET;;;; +203A;SINGLE RIGHT-POINTING ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING SINGLE GUILLEMET;;;; +203B;REFERENCE MARK;Po;0;ON;;;;;N;;;;; +203C;DOUBLE EXCLAMATION MARK;Po;0;ON; 0021 0021;;;;N;;;;; +203D;INTERROBANG;Po;0;ON;;;;;N;;;;; +203E;OVERLINE;Po;0;ON; 0020 0305;;;;N;SPACING OVERSCORE;;;; +203F;UNDERTIE;Pc;0;ON;;;;;N;;Enotikon;;; +2040;CHARACTER TIE;Pc;0;ON;;;;;N;;;;; +2041;CARET INSERTION POINT;Po;0;ON;;;;;N;;;;; +2042;ASTERISM;Po;0;ON;;;;;N;;;;; +2043;HYPHEN BULLET;Po;0;ON;;;;;N;;;;; +2044;FRACTION SLASH;Sm;0;ON;;;;;N;;;;; +2045;LEFT SQUARE BRACKET WITH QUILL;Ps;0;ON;;;;;Y;;;;; +2046;RIGHT SQUARE BRACKET WITH QUILL;Pe;0;ON;;;;;Y;;;;; +2047;DOUBLE QUESTION MARK;Po;0;ON; 003F 003F;;;;N;;;;; +2048;QUESTION EXCLAMATION MARK;Po;0;ON; 003F 0021;;;;N;;;;; +2049;EXCLAMATION QUESTION MARK;Po;0;ON; 0021 003F;;;;N;;;;; +204A;TIRONIAN SIGN ET;Po;0;ON;;;;;N;;;;; +204B;REVERSED PILCROW SIGN;Po;0;ON;;;;;N;;;;; +204C;BLACK LEFTWARDS BULLET;Po;0;ON;;;;;N;;;;; +204D;BLACK RIGHTWARDS BULLET;Po;0;ON;;;;;N;;;;; +204E;LOW ASTERISK;Po;0;ON;;;;;N;;;;; +204F;REVERSED SEMICOLON;Po;0;ON;;;;;N;;;;; +2050;CLOSE UP;Po;0;ON;;;;;N;;;;; +2051;TWO ASTERISKS ALIGNED VERTICALLY;Po;0;ON;;;;;N;;;;; +2052;COMMERCIAL MINUS SIGN;Sm;0;ON;;;;;N;;;;; +2057;QUADRUPLE PRIME;Po;0;ON; 2032 2032 2032 2032;;;;N;;;;; +205F;MEDIUM MATHEMATICAL SPACE;Zs;0;WS; 0020;;;;N;;;;; +2060;WORD JOINER;Cf;0;BN;;;;;N;;;;; +2061;FUNCTION APPLICATION;Cf;0;BN;;;;;N;;;;; +2062;INVISIBLE TIMES;Cf;0;BN;;;;;N;;;;; +2063;INVISIBLE SEPARATOR;Cf;0;BN;;;;;N;;;;; +206A;INHIBIT SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;; +206B;ACTIVATE SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;; +206C;INHIBIT ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;; +206D;ACTIVATE ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;; +206E;NATIONAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;; +206F;NOMINAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;; +2070;SUPERSCRIPT ZERO;No;0;EN; 0030;0;0;0;N;SUPERSCRIPT DIGIT ZERO;;;; +2071;SUPERSCRIPT LATIN SMALL LETTER I;Ll;0;L; 0069;;;;N;;;;; +2074;SUPERSCRIPT FOUR;No;0;EN; 0034;4;4;4;N;SUPERSCRIPT DIGIT FOUR;;;; +2075;SUPERSCRIPT FIVE;No;0;EN; 0035;5;5;5;N;SUPERSCRIPT DIGIT FIVE;;;; +2076;SUPERSCRIPT SIX;No;0;EN; 0036;6;6;6;N;SUPERSCRIPT DIGIT SIX;;;; +2077;SUPERSCRIPT SEVEN;No;0;EN; 0037;7;7;7;N;SUPERSCRIPT DIGIT SEVEN;;;; +2078;SUPERSCRIPT EIGHT;No;0;EN; 0038;8;8;8;N;SUPERSCRIPT DIGIT EIGHT;;;; +2079;SUPERSCRIPT NINE;No;0;EN; 0039;9;9;9;N;SUPERSCRIPT DIGIT NINE;;;; +207A;SUPERSCRIPT PLUS SIGN;Sm;0;ET; 002B;;;;N;;;;; +207B;SUPERSCRIPT MINUS;Sm;0;ET; 2212;;;;N;SUPERSCRIPT HYPHEN-MINUS;;;; +207C;SUPERSCRIPT EQUALS SIGN;Sm;0;ON; 003D;;;;N;;;;; +207D;SUPERSCRIPT LEFT PARENTHESIS;Ps;0;ON; 0028;;;;Y;SUPERSCRIPT OPENING PARENTHESIS;;;; +207E;SUPERSCRIPT RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;Y;SUPERSCRIPT CLOSING PARENTHESIS;;;; +207F;SUPERSCRIPT LATIN SMALL LETTER N;Ll;0;L; 006E;;;;N;;;;; +2080;SUBSCRIPT ZERO;No;0;EN; 0030;0;0;0;N;SUBSCRIPT DIGIT ZERO;;;; +2081;SUBSCRIPT ONE;No;0;EN; 0031;1;1;1;N;SUBSCRIPT DIGIT ONE;;;; +2082;SUBSCRIPT TWO;No;0;EN; 0032;2;2;2;N;SUBSCRIPT DIGIT TWO;;;; +2083;SUBSCRIPT THREE;No;0;EN; 0033;3;3;3;N;SUBSCRIPT DIGIT THREE;;;; +2084;SUBSCRIPT FOUR;No;0;EN; 0034;4;4;4;N;SUBSCRIPT DIGIT FOUR;;;; +2085;SUBSCRIPT FIVE;No;0;EN; 0035;5;5;5;N;SUBSCRIPT DIGIT FIVE;;;; +2086;SUBSCRIPT SIX;No;0;EN; 0036;6;6;6;N;SUBSCRIPT DIGIT SIX;;;; +2087;SUBSCRIPT SEVEN;No;0;EN; 0037;7;7;7;N;SUBSCRIPT DIGIT SEVEN;;;; +2088;SUBSCRIPT EIGHT;No;0;EN; 0038;8;8;8;N;SUBSCRIPT DIGIT EIGHT;;;; +2089;SUBSCRIPT NINE;No;0;EN; 0039;9;9;9;N;SUBSCRIPT DIGIT NINE;;;; +208A;SUBSCRIPT PLUS SIGN;Sm;0;ET; 002B;;;;N;;;;; +208B;SUBSCRIPT MINUS;Sm;0;ET; 2212;;;;N;SUBSCRIPT HYPHEN-MINUS;;;; +208C;SUBSCRIPT EQUALS SIGN;Sm;0;ON; 003D;;;;N;;;;; +208D;SUBSCRIPT LEFT PARENTHESIS;Ps;0;ON; 0028;;;;Y;SUBSCRIPT OPENING PARENTHESIS;;;; +208E;SUBSCRIPT RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;Y;SUBSCRIPT CLOSING PARENTHESIS;;;; +20A0;EURO-CURRENCY SIGN;Sc;0;ET;;;;;N;;;;; +20A1;COLON SIGN;Sc;0;ET;;;;;N;;;;; +20A2;CRUZEIRO SIGN;Sc;0;ET;;;;;N;;;;; +20A3;FRENCH FRANC SIGN;Sc;0;ET;;;;;N;;;;; +20A4;LIRA SIGN;Sc;0;ET;;;;;N;;;;; +20A5;MILL SIGN;Sc;0;ET;;;;;N;;;;; +20A6;NAIRA SIGN;Sc;0;ET;;;;;N;;;;; +20A7;PESETA SIGN;Sc;0;ET;;;;;N;;;;; +20A8;RUPEE SIGN;Sc;0;ET; 0052 0073;;;;N;;;;; +20A9;WON SIGN;Sc;0;ET;;;;;N;;;;; +20AA;NEW SHEQEL SIGN;Sc;0;ET;;;;;N;;;;; +20AB;DONG SIGN;Sc;0;ET;;;;;N;;;;; +20AC;EURO SIGN;Sc;0;ET;;;;;N;;;;; +20AD;KIP SIGN;Sc;0;ET;;;;;N;;;;; +20AE;TUGRIK SIGN;Sc;0;ET;;;;;N;;;;; +20AF;DRACHMA SIGN;Sc;0;ET;;;;;N;;;;; +20B0;GERMAN PENNY SIGN;Sc;0;ET;;;;;N;;;;; +20B1;PESO SIGN;Sc;0;ET;;;;;N;;;;; +20D0;COMBINING LEFT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT HARPOON ABOVE;;;; +20D1;COMBINING RIGHT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT HARPOON ABOVE;;;; +20D2;COMBINING LONG VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG VERTICAL BAR OVERLAY;;;; +20D3;COMBINING SHORT VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT VERTICAL BAR OVERLAY;;;; +20D4;COMBINING ANTICLOCKWISE ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING ANTICLOCKWISE ARROW ABOVE;;;; +20D5;COMBINING CLOCKWISE ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING CLOCKWISE ARROW ABOVE;;;; +20D6;COMBINING LEFT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT ARROW ABOVE;;;; +20D7;COMBINING RIGHT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT ARROW ABOVE;;;; +20D8;COMBINING RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING RING OVERLAY;;;; +20D9;COMBINING CLOCKWISE RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING CLOCKWISE RING OVERLAY;;;; +20DA;COMBINING ANTICLOCKWISE RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING ANTICLOCKWISE RING OVERLAY;;;; +20DB;COMBINING THREE DOTS ABOVE;Mn;230;NSM;;;;;N;NON-SPACING THREE DOTS ABOVE;;;; +20DC;COMBINING FOUR DOTS ABOVE;Mn;230;NSM;;;;;N;NON-SPACING FOUR DOTS ABOVE;;;; +20DD;COMBINING ENCLOSING CIRCLE;Me;0;NSM;;;;;N;ENCLOSING CIRCLE;;;; +20DE;COMBINING ENCLOSING SQUARE;Me;0;NSM;;;;;N;ENCLOSING SQUARE;;;; +20DF;COMBINING ENCLOSING DIAMOND;Me;0;NSM;;;;;N;ENCLOSING DIAMOND;;;; +20E0;COMBINING ENCLOSING CIRCLE BACKSLASH;Me;0;NSM;;;;;N;ENCLOSING CIRCLE SLASH;;;; +20E1;COMBINING LEFT RIGHT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT RIGHT ARROW ABOVE;;;; +20E2;COMBINING ENCLOSING SCREEN;Me;0;NSM;;;;;N;;;;; +20E3;COMBINING ENCLOSING KEYCAP;Me;0;NSM;;;;;N;;;;; +20E4;COMBINING ENCLOSING UPWARD POINTING TRIANGLE;Me;0;NSM;;;;;N;;;;; +20E5;COMBINING REVERSE SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;;;;; +20E6;COMBINING DOUBLE VERTICAL STROKE OVERLAY;Mn;1;NSM;;;;;N;;;;; +20E7;COMBINING ANNUITY SYMBOL;Mn;230;NSM;;;;;N;;;;; +20E8;COMBINING TRIPLE UNDERDOT;Mn;220;NSM;;;;;N;;;;; +20E9;COMBINING WIDE BRIDGE ABOVE;Mn;230;NSM;;;;;N;;;;; +20EA;COMBINING LEFTWARDS ARROW OVERLAY;Mn;1;NSM;;;;;N;;;;; +2100;ACCOUNT OF;So;0;ON; 0061 002F 0063;;;;N;;;;; +2101;ADDRESSED TO THE SUBJECT;So;0;ON; 0061 002F 0073;;;;N;;;;; +2102;DOUBLE-STRUCK CAPITAL C;Lu;0;L; 0043;;;;N;DOUBLE-STRUCK C;;;; +2103;DEGREE CELSIUS;So;0;ON; 00B0 0043;;;;N;DEGREES CENTIGRADE;;;; +2104;CENTRE LINE SYMBOL;So;0;ON;;;;;N;C L SYMBOL;;;; +2105;CARE OF;So;0;ON; 0063 002F 006F;;;;N;;;;; +2106;CADA UNA;So;0;ON; 0063 002F 0075;;;;N;;;;; +2107;EULER CONSTANT;Lu;0;L; 0190;;;;N;EULERS;;;; +2108;SCRUPLE;So;0;ON;;;;;N;;;;; +2109;DEGREE FAHRENHEIT;So;0;ON; 00B0 0046;;;;N;DEGREES FAHRENHEIT;;;; +210A;SCRIPT SMALL G;Ll;0;L; 0067;;;;N;;;;; +210B;SCRIPT CAPITAL H;Lu;0;L; 0048;;;;N;SCRIPT H;;;; +210C;BLACK-LETTER CAPITAL H;Lu;0;L; 0048;;;;N;BLACK-LETTER H;;;; +210D;DOUBLE-STRUCK CAPITAL H;Lu;0;L; 0048;;;;N;DOUBLE-STRUCK H;;;; +210E;PLANCK CONSTANT;Ll;0;L; 0068;;;;N;;;;; +210F;PLANCK CONSTANT OVER TWO PI;Ll;0;L; 0127;;;;N;PLANCK CONSTANT OVER 2 PI;;;; +2110;SCRIPT CAPITAL I;Lu;0;L; 0049;;;;N;SCRIPT I;;;; +2111;BLACK-LETTER CAPITAL I;Lu;0;L; 0049;;;;N;BLACK-LETTER I;;;; +2112;SCRIPT CAPITAL L;Lu;0;L; 004C;;;;N;SCRIPT L;;;; +2113;SCRIPT SMALL L;Ll;0;L; 006C;;;;N;;;;; +2114;L B BAR SYMBOL;So;0;ON;;;;;N;;;;; +2115;DOUBLE-STRUCK CAPITAL N;Lu;0;L; 004E;;;;N;DOUBLE-STRUCK N;;;; +2116;NUMERO SIGN;So;0;ON; 004E 006F;;;;N;NUMERO;;;; +2117;SOUND RECORDING COPYRIGHT;So;0;ON;;;;;N;;;;; +2118;SCRIPT CAPITAL P;So;0;ON;;;;;N;SCRIPT P;;;; +2119;DOUBLE-STRUCK CAPITAL P;Lu;0;L; 0050;;;;N;DOUBLE-STRUCK P;;;; +211A;DOUBLE-STRUCK CAPITAL Q;Lu;0;L; 0051;;;;N;DOUBLE-STRUCK Q;;;; +211B;SCRIPT CAPITAL R;Lu;0;L; 0052;;;;N;SCRIPT R;;;; +211C;BLACK-LETTER CAPITAL R;Lu;0;L; 0052;;;;N;BLACK-LETTER R;;;; +211D;DOUBLE-STRUCK CAPITAL R;Lu;0;L; 0052;;;;N;DOUBLE-STRUCK R;;;; +211E;PRESCRIPTION TAKE;So;0;ON;;;;;N;;;;; +211F;RESPONSE;So;0;ON;;;;;N;;;;; +2120;SERVICE MARK;So;0;ON; 0053 004D;;;;N;;;;; +2121;TELEPHONE SIGN;So;0;ON; 0054 0045 004C;;;;N;T E L SYMBOL;;;; +2122;TRADE MARK SIGN;So;0;ON; 0054 004D;;;;N;TRADEMARK;;;; +2123;VERSICLE;So;0;ON;;;;;N;;;;; +2124;DOUBLE-STRUCK CAPITAL Z;Lu;0;L; 005A;;;;N;DOUBLE-STRUCK Z;;;; +2125;OUNCE SIGN;So;0;ON;;;;;N;OUNCE;;;; +2126;OHM SIGN;Lu;0;L;03A9;;;;N;OHM;;;03C9; +2127;INVERTED OHM SIGN;So;0;ON;;;;;N;MHO;;;; +2128;BLACK-LETTER CAPITAL Z;Lu;0;L; 005A;;;;N;BLACK-LETTER Z;;;; +2129;TURNED GREEK SMALL LETTER IOTA;So;0;ON;;;;;N;;;;; +212A;KELVIN SIGN;Lu;0;L;004B;;;;N;DEGREES KELVIN;;;006B; +212B;ANGSTROM SIGN;Lu;0;L;00C5;;;;N;ANGSTROM UNIT;;;00E5; +212C;SCRIPT CAPITAL B;Lu;0;L; 0042;;;;N;SCRIPT B;;;; +212D;BLACK-LETTER CAPITAL C;Lu;0;L; 0043;;;;N;BLACK-LETTER C;;;; +212E;ESTIMATED SYMBOL;So;0;ET;;;;;N;;;;; +212F;SCRIPT SMALL E;Ll;0;L; 0065;;;;N;;;;; +2130;SCRIPT CAPITAL E;Lu;0;L; 0045;;;;N;SCRIPT E;;;; +2131;SCRIPT CAPITAL F;Lu;0;L; 0046;;;;N;SCRIPT F;;;; +2132;TURNED CAPITAL F;So;0;ON;;;;;N;TURNED F;;;; +2133;SCRIPT CAPITAL M;Lu;0;L; 004D;;;;N;SCRIPT M;;;; +2134;SCRIPT SMALL O;Ll;0;L; 006F;;;;N;;;;; +2135;ALEF SYMBOL;Lo;0;L; 05D0;;;;N;FIRST TRANSFINITE CARDINAL;;;; +2136;BET SYMBOL;Lo;0;L; 05D1;;;;N;SECOND TRANSFINITE CARDINAL;;;; +2137;GIMEL SYMBOL;Lo;0;L; 05D2;;;;N;THIRD TRANSFINITE CARDINAL;;;; +2138;DALET SYMBOL;Lo;0;L; 05D3;;;;N;FOURTH TRANSFINITE CARDINAL;;;; +2139;INFORMATION SOURCE;Ll;0;L; 0069;;;;N;;;;; +213A;ROTATED CAPITAL Q;So;0;ON;;;;;N;;;;; +213D;DOUBLE-STRUCK SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +213E;DOUBLE-STRUCK CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +213F;DOUBLE-STRUCK CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +2140;DOUBLE-STRUCK N-ARY SUMMATION;Sm;0;ON; 2211;;;;Y;;;;; +2141;TURNED SANS-SERIF CAPITAL G;Sm;0;ON;;;;;N;;;;; +2142;TURNED SANS-SERIF CAPITAL L;Sm;0;ON;;;;;N;;;;; +2143;REVERSED SANS-SERIF CAPITAL L;Sm;0;ON;;;;;N;;;;; +2144;TURNED SANS-SERIF CAPITAL Y;Sm;0;ON;;;;;N;;;;; +2145;DOUBLE-STRUCK ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +2146;DOUBLE-STRUCK ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; +2147;DOUBLE-STRUCK ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; +2148;DOUBLE-STRUCK ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; +2149;DOUBLE-STRUCK ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; +214A;PROPERTY LINE;So;0;ON;;;;;N;;;;; +214B;TURNED AMPERSAND;Sm;0;ON;;;;;N;;;;; +2153;VULGAR FRACTION ONE THIRD;No;0;ON; 0031 2044 0033;;;1/3;N;FRACTION ONE THIRD;;;; +2154;VULGAR FRACTION TWO THIRDS;No;0;ON; 0032 2044 0033;;;2/3;N;FRACTION TWO THIRDS;;;; +2155;VULGAR FRACTION ONE FIFTH;No;0;ON; 0031 2044 0035;;;1/5;N;FRACTION ONE FIFTH;;;; +2156;VULGAR FRACTION TWO FIFTHS;No;0;ON; 0032 2044 0035;;;2/5;N;FRACTION TWO FIFTHS;;;; +2157;VULGAR FRACTION THREE FIFTHS;No;0;ON; 0033 2044 0035;;;3/5;N;FRACTION THREE FIFTHS;;;; +2158;VULGAR FRACTION FOUR FIFTHS;No;0;ON; 0034 2044 0035;;;4/5;N;FRACTION FOUR FIFTHS;;;; +2159;VULGAR FRACTION ONE SIXTH;No;0;ON; 0031 2044 0036;;;1/6;N;FRACTION ONE SIXTH;;;; +215A;VULGAR FRACTION FIVE SIXTHS;No;0;ON; 0035 2044 0036;;;5/6;N;FRACTION FIVE SIXTHS;;;; +215B;VULGAR FRACTION ONE EIGHTH;No;0;ON; 0031 2044 0038;;;1/8;N;FRACTION ONE EIGHTH;;;; +215C;VULGAR FRACTION THREE EIGHTHS;No;0;ON; 0033 2044 0038;;;3/8;N;FRACTION THREE EIGHTHS;;;; +215D;VULGAR FRACTION FIVE EIGHTHS;No;0;ON; 0035 2044 0038;;;5/8;N;FRACTION FIVE EIGHTHS;;;; +215E;VULGAR FRACTION SEVEN EIGHTHS;No;0;ON; 0037 2044 0038;;;7/8;N;FRACTION SEVEN EIGHTHS;;;; +215F;FRACTION NUMERATOR ONE;No;0;ON; 0031 2044;;;1;N;;;;; +2160;ROMAN NUMERAL ONE;Nl;0;L; 0049;;;1;N;;;;2170; +2161;ROMAN NUMERAL TWO;Nl;0;L; 0049 0049;;;2;N;;;;2171; +2162;ROMAN NUMERAL THREE;Nl;0;L; 0049 0049 0049;;;3;N;;;;2172; +2163;ROMAN NUMERAL FOUR;Nl;0;L; 0049 0056;;;4;N;;;;2173; +2164;ROMAN NUMERAL FIVE;Nl;0;L; 0056;;;5;N;;;;2174; +2165;ROMAN NUMERAL SIX;Nl;0;L; 0056 0049;;;6;N;;;;2175; +2166;ROMAN NUMERAL SEVEN;Nl;0;L; 0056 0049 0049;;;7;N;;;;2176; +2167;ROMAN NUMERAL EIGHT;Nl;0;L; 0056 0049 0049 0049;;;8;N;;;;2177; +2168;ROMAN NUMERAL NINE;Nl;0;L; 0049 0058;;;9;N;;;;2178; +2169;ROMAN NUMERAL TEN;Nl;0;L; 0058;;;10;N;;;;2179; +216A;ROMAN NUMERAL ELEVEN;Nl;0;L; 0058 0049;;;11;N;;;;217A; +216B;ROMAN NUMERAL TWELVE;Nl;0;L; 0058 0049 0049;;;12;N;;;;217B; +216C;ROMAN NUMERAL FIFTY;Nl;0;L; 004C;;;50;N;;;;217C; +216D;ROMAN NUMERAL ONE HUNDRED;Nl;0;L; 0043;;;100;N;;;;217D; +216E;ROMAN NUMERAL FIVE HUNDRED;Nl;0;L; 0044;;;500;N;;;;217E; +216F;ROMAN NUMERAL ONE THOUSAND;Nl;0;L; 004D;;;1000;N;;;;217F; +2170;SMALL ROMAN NUMERAL ONE;Nl;0;L; 0069;;;1;N;;;2160;;2160 +2171;SMALL ROMAN NUMERAL TWO;Nl;0;L; 0069 0069;;;2;N;;;2161;;2161 +2172;SMALL ROMAN NUMERAL THREE;Nl;0;L; 0069 0069 0069;;;3;N;;;2162;;2162 +2173;SMALL ROMAN NUMERAL FOUR;Nl;0;L; 0069 0076;;;4;N;;;2163;;2163 +2174;SMALL ROMAN NUMERAL FIVE;Nl;0;L; 0076;;;5;N;;;2164;;2164 +2175;SMALL ROMAN NUMERAL SIX;Nl;0;L; 0076 0069;;;6;N;;;2165;;2165 +2176;SMALL ROMAN NUMERAL SEVEN;Nl;0;L; 0076 0069 0069;;;7;N;;;2166;;2166 +2177;SMALL ROMAN NUMERAL EIGHT;Nl;0;L; 0076 0069 0069 0069;;;8;N;;;2167;;2167 +2178;SMALL ROMAN NUMERAL NINE;Nl;0;L; 0069 0078;;;9;N;;;2168;;2168 +2179;SMALL ROMAN NUMERAL TEN;Nl;0;L; 0078;;;10;N;;;2169;;2169 +217A;SMALL ROMAN NUMERAL ELEVEN;Nl;0;L; 0078 0069;;;11;N;;;216A;;216A +217B;SMALL ROMAN NUMERAL TWELVE;Nl;0;L; 0078 0069 0069;;;12;N;;;216B;;216B +217C;SMALL ROMAN NUMERAL FIFTY;Nl;0;L; 006C;;;50;N;;;216C;;216C +217D;SMALL ROMAN NUMERAL ONE HUNDRED;Nl;0;L; 0063;;;100;N;;;216D;;216D +217E;SMALL ROMAN NUMERAL FIVE HUNDRED;Nl;0;L; 0064;;;500;N;;;216E;;216E +217F;SMALL ROMAN NUMERAL ONE THOUSAND;Nl;0;L; 006D;;;1000;N;;;216F;;216F +2180;ROMAN NUMERAL ONE THOUSAND C D;Nl;0;L;;;;1000;N;;;;; +2181;ROMAN NUMERAL FIVE THOUSAND;Nl;0;L;;;;5000;N;;;;; +2182;ROMAN NUMERAL TEN THOUSAND;Nl;0;L;;;;10000;N;;;;; +2183;ROMAN NUMERAL REVERSED ONE HUNDRED;Nl;0;L;;;;;N;;;;; +2190;LEFTWARDS ARROW;Sm;0;ON;;;;;N;LEFT ARROW;;;; +2191;UPWARDS ARROW;Sm;0;ON;;;;;N;UP ARROW;;;; +2192;RIGHTWARDS ARROW;Sm;0;ON;;;;;N;RIGHT ARROW;;;; +2193;DOWNWARDS ARROW;Sm;0;ON;;;;;N;DOWN ARROW;;;; +2194;LEFT RIGHT ARROW;Sm;0;ON;;;;;N;;;;; +2195;UP DOWN ARROW;So;0;ON;;;;;N;;;;; +2196;NORTH WEST ARROW;So;0;ON;;;;;N;UPPER LEFT ARROW;;;; +2197;NORTH EAST ARROW;So;0;ON;;;;;N;UPPER RIGHT ARROW;;;; +2198;SOUTH EAST ARROW;So;0;ON;;;;;N;LOWER RIGHT ARROW;;;; +2199;SOUTH WEST ARROW;So;0;ON;;;;;N;LOWER LEFT ARROW;;;; +219A;LEFTWARDS ARROW WITH STROKE;Sm;0;ON;2190 0338;;;;N;LEFT ARROW WITH STROKE;;;; +219B;RIGHTWARDS ARROW WITH STROKE;Sm;0;ON;2192 0338;;;;N;RIGHT ARROW WITH STROKE;;;; +219C;LEFTWARDS WAVE ARROW;So;0;ON;;;;;N;LEFT WAVE ARROW;;;; +219D;RIGHTWARDS WAVE ARROW;So;0;ON;;;;;N;RIGHT WAVE ARROW;;;; +219E;LEFTWARDS TWO HEADED ARROW;So;0;ON;;;;;N;LEFT TWO HEADED ARROW;;;; +219F;UPWARDS TWO HEADED ARROW;So;0;ON;;;;;N;UP TWO HEADED ARROW;;;; +21A0;RIGHTWARDS TWO HEADED ARROW;Sm;0;ON;;;;;N;RIGHT TWO HEADED ARROW;;;; +21A1;DOWNWARDS TWO HEADED ARROW;So;0;ON;;;;;N;DOWN TWO HEADED ARROW;;;; +21A2;LEFTWARDS ARROW WITH TAIL;So;0;ON;;;;;N;LEFT ARROW WITH TAIL;;;; +21A3;RIGHTWARDS ARROW WITH TAIL;Sm;0;ON;;;;;N;RIGHT ARROW WITH TAIL;;;; +21A4;LEFTWARDS ARROW FROM BAR;So;0;ON;;;;;N;LEFT ARROW FROM BAR;;;; +21A5;UPWARDS ARROW FROM BAR;So;0;ON;;;;;N;UP ARROW FROM BAR;;;; +21A6;RIGHTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;RIGHT ARROW FROM BAR;;;; +21A7;DOWNWARDS ARROW FROM BAR;So;0;ON;;;;;N;DOWN ARROW FROM BAR;;;; +21A8;UP DOWN ARROW WITH BASE;So;0;ON;;;;;N;;;;; +21A9;LEFTWARDS ARROW WITH HOOK;So;0;ON;;;;;N;LEFT ARROW WITH HOOK;;;; +21AA;RIGHTWARDS ARROW WITH HOOK;So;0;ON;;;;;N;RIGHT ARROW WITH HOOK;;;; +21AB;LEFTWARDS ARROW WITH LOOP;So;0;ON;;;;;N;LEFT ARROW WITH LOOP;;;; +21AC;RIGHTWARDS ARROW WITH LOOP;So;0;ON;;;;;N;RIGHT ARROW WITH LOOP;;;; +21AD;LEFT RIGHT WAVE ARROW;So;0;ON;;;;;N;;;;; +21AE;LEFT RIGHT ARROW WITH STROKE;Sm;0;ON;2194 0338;;;;N;;;;; +21AF;DOWNWARDS ZIGZAG ARROW;So;0;ON;;;;;N;DOWN ZIGZAG ARROW;;;; +21B0;UPWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;UP ARROW WITH TIP LEFT;;;; +21B1;UPWARDS ARROW WITH TIP RIGHTWARDS;So;0;ON;;;;;N;UP ARROW WITH TIP RIGHT;;;; +21B2;DOWNWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH TIP LEFT;;;; +21B3;DOWNWARDS ARROW WITH TIP RIGHTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH TIP RIGHT;;;; +21B4;RIGHTWARDS ARROW WITH CORNER DOWNWARDS;So;0;ON;;;;;N;RIGHT ARROW WITH CORNER DOWN;;;; +21B5;DOWNWARDS ARROW WITH CORNER LEFTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH CORNER LEFT;;;; +21B6;ANTICLOCKWISE TOP SEMICIRCLE ARROW;So;0;ON;;;;;N;;;;; +21B7;CLOCKWISE TOP SEMICIRCLE ARROW;So;0;ON;;;;;N;;;;; +21B8;NORTH WEST ARROW TO LONG BAR;So;0;ON;;;;;N;UPPER LEFT ARROW TO LONG BAR;;;; +21B9;LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR;So;0;ON;;;;;N;LEFT ARROW TO BAR OVER RIGHT ARROW TO BAR;;;; +21BA;ANTICLOCKWISE OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;; +21BB;CLOCKWISE OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;; +21BC;LEFTWARDS HARPOON WITH BARB UPWARDS;So;0;ON;;;;;N;LEFT HARPOON WITH BARB UP;;;; +21BD;LEFTWARDS HARPOON WITH BARB DOWNWARDS;So;0;ON;;;;;N;LEFT HARPOON WITH BARB DOWN;;;; +21BE;UPWARDS HARPOON WITH BARB RIGHTWARDS;So;0;ON;;;;;N;UP HARPOON WITH BARB RIGHT;;;; +21BF;UPWARDS HARPOON WITH BARB LEFTWARDS;So;0;ON;;;;;N;UP HARPOON WITH BARB LEFT;;;; +21C0;RIGHTWARDS HARPOON WITH BARB UPWARDS;So;0;ON;;;;;N;RIGHT HARPOON WITH BARB UP;;;; +21C1;RIGHTWARDS HARPOON WITH BARB DOWNWARDS;So;0;ON;;;;;N;RIGHT HARPOON WITH BARB DOWN;;;; +21C2;DOWNWARDS HARPOON WITH BARB RIGHTWARDS;So;0;ON;;;;;N;DOWN HARPOON WITH BARB RIGHT;;;; +21C3;DOWNWARDS HARPOON WITH BARB LEFTWARDS;So;0;ON;;;;;N;DOWN HARPOON WITH BARB LEFT;;;; +21C4;RIGHTWARDS ARROW OVER LEFTWARDS ARROW;So;0;ON;;;;;N;RIGHT ARROW OVER LEFT ARROW;;;; +21C5;UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW;So;0;ON;;;;;N;UP ARROW LEFT OF DOWN ARROW;;;; +21C6;LEFTWARDS ARROW OVER RIGHTWARDS ARROW;So;0;ON;;;;;N;LEFT ARROW OVER RIGHT ARROW;;;; +21C7;LEFTWARDS PAIRED ARROWS;So;0;ON;;;;;N;LEFT PAIRED ARROWS;;;; +21C8;UPWARDS PAIRED ARROWS;So;0;ON;;;;;N;UP PAIRED ARROWS;;;; +21C9;RIGHTWARDS PAIRED ARROWS;So;0;ON;;;;;N;RIGHT PAIRED ARROWS;;;; +21CA;DOWNWARDS PAIRED ARROWS;So;0;ON;;;;;N;DOWN PAIRED ARROWS;;;; +21CB;LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON;So;0;ON;;;;;N;LEFT HARPOON OVER RIGHT HARPOON;;;; +21CC;RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON;So;0;ON;;;;;N;RIGHT HARPOON OVER LEFT HARPOON;;;; +21CD;LEFTWARDS DOUBLE ARROW WITH STROKE;So;0;ON;21D0 0338;;;;N;LEFT DOUBLE ARROW WITH STROKE;;;; +21CE;LEFT RIGHT DOUBLE ARROW WITH STROKE;Sm;0;ON;21D4 0338;;;;N;;;;; +21CF;RIGHTWARDS DOUBLE ARROW WITH STROKE;Sm;0;ON;21D2 0338;;;;N;RIGHT DOUBLE ARROW WITH STROKE;;;; +21D0;LEFTWARDS DOUBLE ARROW;So;0;ON;;;;;N;LEFT DOUBLE ARROW;;;; +21D1;UPWARDS DOUBLE ARROW;So;0;ON;;;;;N;UP DOUBLE ARROW;;;; +21D2;RIGHTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;RIGHT DOUBLE ARROW;;;; +21D3;DOWNWARDS DOUBLE ARROW;So;0;ON;;;;;N;DOWN DOUBLE ARROW;;;; +21D4;LEFT RIGHT DOUBLE ARROW;Sm;0;ON;;;;;N;;;;; +21D5;UP DOWN DOUBLE ARROW;So;0;ON;;;;;N;;;;; +21D6;NORTH WEST DOUBLE ARROW;So;0;ON;;;;;N;UPPER LEFT DOUBLE ARROW;;;; +21D7;NORTH EAST DOUBLE ARROW;So;0;ON;;;;;N;UPPER RIGHT DOUBLE ARROW;;;; +21D8;SOUTH EAST DOUBLE ARROW;So;0;ON;;;;;N;LOWER RIGHT DOUBLE ARROW;;;; +21D9;SOUTH WEST DOUBLE ARROW;So;0;ON;;;;;N;LOWER LEFT DOUBLE ARROW;;;; +21DA;LEFTWARDS TRIPLE ARROW;So;0;ON;;;;;N;LEFT TRIPLE ARROW;;;; +21DB;RIGHTWARDS TRIPLE ARROW;So;0;ON;;;;;N;RIGHT TRIPLE ARROW;;;; +21DC;LEFTWARDS SQUIGGLE ARROW;So;0;ON;;;;;N;LEFT SQUIGGLE ARROW;;;; +21DD;RIGHTWARDS SQUIGGLE ARROW;So;0;ON;;;;;N;RIGHT SQUIGGLE ARROW;;;; +21DE;UPWARDS ARROW WITH DOUBLE STROKE;So;0;ON;;;;;N;UP ARROW WITH DOUBLE STROKE;;;; +21DF;DOWNWARDS ARROW WITH DOUBLE STROKE;So;0;ON;;;;;N;DOWN ARROW WITH DOUBLE STROKE;;;; +21E0;LEFTWARDS DASHED ARROW;So;0;ON;;;;;N;LEFT DASHED ARROW;;;; +21E1;UPWARDS DASHED ARROW;So;0;ON;;;;;N;UP DASHED ARROW;;;; +21E2;RIGHTWARDS DASHED ARROW;So;0;ON;;;;;N;RIGHT DASHED ARROW;;;; +21E3;DOWNWARDS DASHED ARROW;So;0;ON;;;;;N;DOWN DASHED ARROW;;;; +21E4;LEFTWARDS ARROW TO BAR;So;0;ON;;;;;N;LEFT ARROW TO BAR;;;; +21E5;RIGHTWARDS ARROW TO BAR;So;0;ON;;;;;N;RIGHT ARROW TO BAR;;;; +21E6;LEFTWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE LEFT ARROW;;;; +21E7;UPWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE UP ARROW;;;; +21E8;RIGHTWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE RIGHT ARROW;;;; +21E9;DOWNWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE DOWN ARROW;;;; +21EA;UPWARDS WHITE ARROW FROM BAR;So;0;ON;;;;;N;WHITE UP ARROW FROM BAR;;;; +21EB;UPWARDS WHITE ARROW ON PEDESTAL;So;0;ON;;;;;N;;;;; +21EC;UPWARDS WHITE ARROW ON PEDESTAL WITH HORIZONTAL BAR;So;0;ON;;;;;N;;;;; +21ED;UPWARDS WHITE ARROW ON PEDESTAL WITH VERTICAL BAR;So;0;ON;;;;;N;;;;; +21EE;UPWARDS WHITE DOUBLE ARROW;So;0;ON;;;;;N;;;;; +21EF;UPWARDS WHITE DOUBLE ARROW ON PEDESTAL;So;0;ON;;;;;N;;;;; +21F0;RIGHTWARDS WHITE ARROW FROM WALL;So;0;ON;;;;;N;;;;; +21F1;NORTH WEST ARROW TO CORNER;So;0;ON;;;;;N;;;;; +21F2;SOUTH EAST ARROW TO CORNER;So;0;ON;;;;;N;;;;; +21F3;UP DOWN WHITE ARROW;So;0;ON;;;;;N;;;;; +21F4;RIGHT ARROW WITH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; +21F5;DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW;Sm;0;ON;;;;;N;;;;; +21F6;THREE RIGHTWARDS ARROWS;Sm;0;ON;;;;;N;;;;; +21F7;LEFTWARDS ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21F8;RIGHTWARDS ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21F9;LEFT RIGHT ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21FA;LEFTWARDS ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21FB;RIGHTWARDS ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21FC;LEFT RIGHT ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21FD;LEFTWARDS OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;; +21FE;RIGHTWARDS OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;; +21FF;LEFT RIGHT OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;; +2200;FOR ALL;Sm;0;ON;;;;;N;;;;; +2201;COMPLEMENT;Sm;0;ON;;;;;Y;;;;; +2202;PARTIAL DIFFERENTIAL;Sm;0;ON;;;;;Y;;;;; +2203;THERE EXISTS;Sm;0;ON;;;;;Y;;;;; +2204;THERE DOES NOT EXIST;Sm;0;ON;2203 0338;;;;Y;;;;; +2205;EMPTY SET;Sm;0;ON;;;;;N;;;;; +2206;INCREMENT;Sm;0;ON;;;;;N;;;;; +2207;NABLA;Sm;0;ON;;;;;N;;;;; +2208;ELEMENT OF;Sm;0;ON;;;;;Y;;;;; +2209;NOT AN ELEMENT OF;Sm;0;ON;2208 0338;;;;Y;;;;; +220A;SMALL ELEMENT OF;Sm;0;ON;;;;;Y;;;;; +220B;CONTAINS AS MEMBER;Sm;0;ON;;;;;Y;;;;; +220C;DOES NOT CONTAIN AS MEMBER;Sm;0;ON;220B 0338;;;;Y;;;;; +220D;SMALL CONTAINS AS MEMBER;Sm;0;ON;;;;;Y;;;;; +220E;END OF PROOF;Sm;0;ON;;;;;N;;;;; +220F;N-ARY PRODUCT;Sm;0;ON;;;;;N;;;;; +2210;N-ARY COPRODUCT;Sm;0;ON;;;;;N;;;;; +2211;N-ARY SUMMATION;Sm;0;ON;;;;;Y;;;;; +2212;MINUS SIGN;Sm;0;ET;;;;;N;;;;; +2213;MINUS-OR-PLUS SIGN;Sm;0;ET;;;;;N;;;;; +2214;DOT PLUS;Sm;0;ON;;;;;N;;;;; +2215;DIVISION SLASH;Sm;0;ON;;;;;Y;;;;; +2216;SET MINUS;Sm;0;ON;;;;;Y;;;;; +2217;ASTERISK OPERATOR;Sm;0;ON;;;;;N;;;;; +2218;RING OPERATOR;Sm;0;ON;;;;;N;;;;; +2219;BULLET OPERATOR;Sm;0;ON;;;;;N;;;;; +221A;SQUARE ROOT;Sm;0;ON;;;;;Y;;;;; +221B;CUBE ROOT;Sm;0;ON;;;;;Y;;;;; +221C;FOURTH ROOT;Sm;0;ON;;;;;Y;;;;; +221D;PROPORTIONAL TO;Sm;0;ON;;;;;Y;;;;; +221E;INFINITY;Sm;0;ON;;;;;N;;;;; +221F;RIGHT ANGLE;Sm;0;ON;;;;;Y;;;;; +2220;ANGLE;Sm;0;ON;;;;;Y;;;;; +2221;MEASURED ANGLE;Sm;0;ON;;;;;Y;;;;; +2222;SPHERICAL ANGLE;Sm;0;ON;;;;;Y;;;;; +2223;DIVIDES;Sm;0;ON;;;;;N;;;;; +2224;DOES NOT DIVIDE;Sm;0;ON;2223 0338;;;;Y;;;;; +2225;PARALLEL TO;Sm;0;ON;;;;;N;;;;; +2226;NOT PARALLEL TO;Sm;0;ON;2225 0338;;;;Y;;;;; +2227;LOGICAL AND;Sm;0;ON;;;;;N;;;;; +2228;LOGICAL OR;Sm;0;ON;;;;;N;;;;; +2229;INTERSECTION;Sm;0;ON;;;;;N;;;;; +222A;UNION;Sm;0;ON;;;;;N;;;;; +222B;INTEGRAL;Sm;0;ON;;;;;Y;;;;; +222C;DOUBLE INTEGRAL;Sm;0;ON; 222B 222B;;;;Y;;;;; +222D;TRIPLE INTEGRAL;Sm;0;ON; 222B 222B 222B;;;;Y;;;;; +222E;CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;; +222F;SURFACE INTEGRAL;Sm;0;ON; 222E 222E;;;;Y;;;;; +2230;VOLUME INTEGRAL;Sm;0;ON; 222E 222E 222E;;;;Y;;;;; +2231;CLOCKWISE INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2232;CLOCKWISE CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2233;ANTICLOCKWISE CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2234;THEREFORE;Sm;0;ON;;;;;N;;;;; +2235;BECAUSE;Sm;0;ON;;;;;N;;;;; +2236;RATIO;Sm;0;ON;;;;;N;;;;; +2237;PROPORTION;Sm;0;ON;;;;;N;;;;; +2238;DOT MINUS;Sm;0;ON;;;;;N;;;;; +2239;EXCESS;Sm;0;ON;;;;;Y;;;;; +223A;GEOMETRIC PROPORTION;Sm;0;ON;;;;;N;;;;; +223B;HOMOTHETIC;Sm;0;ON;;;;;Y;;;;; +223C;TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; +223D;REVERSED TILDE;Sm;0;ON;;;;;Y;;lazy S;;; +223E;INVERTED LAZY S;Sm;0;ON;;;;;Y;;;;; +223F;SINE WAVE;Sm;0;ON;;;;;Y;;;;; +2240;WREATH PRODUCT;Sm;0;ON;;;;;Y;;;;; +2241;NOT TILDE;Sm;0;ON;223C 0338;;;;Y;;;;; +2242;MINUS TILDE;Sm;0;ON;;;;;Y;;;;; +2243;ASYMPTOTICALLY EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2244;NOT ASYMPTOTICALLY EQUAL TO;Sm;0;ON;2243 0338;;;;Y;;;;; +2245;APPROXIMATELY EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2246;APPROXIMATELY BUT NOT ACTUALLY EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2247;NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO;Sm;0;ON;2245 0338;;;;Y;;;;; +2248;ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2249;NOT ALMOST EQUAL TO;Sm;0;ON;2248 0338;;;;Y;;;;; +224A;ALMOST EQUAL OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +224B;TRIPLE TILDE;Sm;0;ON;;;;;Y;;;;; +224C;ALL EQUAL TO;Sm;0;ON;;;;;Y;;;;; +224D;EQUIVALENT TO;Sm;0;ON;;;;;N;;;;; +224E;GEOMETRICALLY EQUIVALENT TO;Sm;0;ON;;;;;N;;;;; +224F;DIFFERENCE BETWEEN;Sm;0;ON;;;;;N;;;;; +2250;APPROACHES THE LIMIT;Sm;0;ON;;;;;N;;;;; +2251;GEOMETRICALLY EQUAL TO;Sm;0;ON;;;;;N;;;;; +2252;APPROXIMATELY EQUAL TO OR THE IMAGE OF;Sm;0;ON;;;;;Y;;;;; +2253;IMAGE OF OR APPROXIMATELY EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2254;COLON EQUALS;Sm;0;ON;;;;;Y;COLON EQUAL;;;; +2255;EQUALS COLON;Sm;0;ON;;;;;Y;EQUAL COLON;;;; +2256;RING IN EQUAL TO;Sm;0;ON;;;;;N;;;;; +2257;RING EQUAL TO;Sm;0;ON;;;;;N;;;;; +2258;CORRESPONDS TO;Sm;0;ON;;;;;N;;;;; +2259;ESTIMATES;Sm;0;ON;;;;;N;;;;; +225A;EQUIANGULAR TO;Sm;0;ON;;;;;N;;;;; +225B;STAR EQUALS;Sm;0;ON;;;;;N;;;;; +225C;DELTA EQUAL TO;Sm;0;ON;;;;;N;;;;; +225D;EQUAL TO BY DEFINITION;Sm;0;ON;;;;;N;;;;; +225E;MEASURED BY;Sm;0;ON;;;;;N;;;;; +225F;QUESTIONED EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2260;NOT EQUAL TO;Sm;0;ON;003D 0338;;;;Y;;;;; +2261;IDENTICAL TO;Sm;0;ON;;;;;N;;;;; +2262;NOT IDENTICAL TO;Sm;0;ON;2261 0338;;;;Y;;;;; +2263;STRICTLY EQUIVALENT TO;Sm;0;ON;;;;;N;;;;; +2264;LESS-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN OR EQUAL TO;;;; +2265;GREATER-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN OR EQUAL TO;;;; +2266;LESS-THAN OVER EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN OVER EQUAL TO;;;; +2267;GREATER-THAN OVER EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN OVER EQUAL TO;;;; +2268;LESS-THAN BUT NOT EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN BUT NOT EQUAL TO;;;; +2269;GREATER-THAN BUT NOT EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN BUT NOT EQUAL TO;;;; +226A;MUCH LESS-THAN;Sm;0;ON;;;;;Y;MUCH LESS THAN;;;; +226B;MUCH GREATER-THAN;Sm;0;ON;;;;;Y;MUCH GREATER THAN;;;; +226C;BETWEEN;Sm;0;ON;;;;;N;;;;; +226D;NOT EQUIVALENT TO;Sm;0;ON;224D 0338;;;;N;;;;; +226E;NOT LESS-THAN;Sm;0;ON;003C 0338;;;;Y;NOT LESS THAN;;;; +226F;NOT GREATER-THAN;Sm;0;ON;003E 0338;;;;Y;NOT GREATER THAN;;;; +2270;NEITHER LESS-THAN NOR EQUAL TO;Sm;0;ON;2264 0338;;;;Y;NEITHER LESS THAN NOR EQUAL TO;;;; +2271;NEITHER GREATER-THAN NOR EQUAL TO;Sm;0;ON;2265 0338;;;;Y;NEITHER GREATER THAN NOR EQUAL TO;;;; +2272;LESS-THAN OR EQUIVALENT TO;Sm;0;ON;;;;;Y;LESS THAN OR EQUIVALENT TO;;;; +2273;GREATER-THAN OR EQUIVALENT TO;Sm;0;ON;;;;;Y;GREATER THAN OR EQUIVALENT TO;;;; +2274;NEITHER LESS-THAN NOR EQUIVALENT TO;Sm;0;ON;2272 0338;;;;Y;NEITHER LESS THAN NOR EQUIVALENT TO;;;; +2275;NEITHER GREATER-THAN NOR EQUIVALENT TO;Sm;0;ON;2273 0338;;;;Y;NEITHER GREATER THAN NOR EQUIVALENT TO;;;; +2276;LESS-THAN OR GREATER-THAN;Sm;0;ON;;;;;Y;LESS THAN OR GREATER THAN;;;; +2277;GREATER-THAN OR LESS-THAN;Sm;0;ON;;;;;Y;GREATER THAN OR LESS THAN;;;; +2278;NEITHER LESS-THAN NOR GREATER-THAN;Sm;0;ON;2276 0338;;;;Y;NEITHER LESS THAN NOR GREATER THAN;;;; +2279;NEITHER GREATER-THAN NOR LESS-THAN;Sm;0;ON;2277 0338;;;;Y;NEITHER GREATER THAN NOR LESS THAN;;;; +227A;PRECEDES;Sm;0;ON;;;;;Y;;;;; +227B;SUCCEEDS;Sm;0;ON;;;;;Y;;;;; +227C;PRECEDES OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +227D;SUCCEEDS OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +227E;PRECEDES OR EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;; +227F;SUCCEEDS OR EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;; +2280;DOES NOT PRECEDE;Sm;0;ON;227A 0338;;;;Y;;;;; +2281;DOES NOT SUCCEED;Sm;0;ON;227B 0338;;;;Y;;;;; +2282;SUBSET OF;Sm;0;ON;;;;;Y;;;;; +2283;SUPERSET OF;Sm;0;ON;;;;;Y;;;;; +2284;NOT A SUBSET OF;Sm;0;ON;2282 0338;;;;Y;;;;; +2285;NOT A SUPERSET OF;Sm;0;ON;2283 0338;;;;Y;;;;; +2286;SUBSET OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2287;SUPERSET OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2288;NEITHER A SUBSET OF NOR EQUAL TO;Sm;0;ON;2286 0338;;;;Y;;;;; +2289;NEITHER A SUPERSET OF NOR EQUAL TO;Sm;0;ON;2287 0338;;;;Y;;;;; +228A;SUBSET OF WITH NOT EQUAL TO;Sm;0;ON;;;;;Y;SUBSET OF OR NOT EQUAL TO;;;; +228B;SUPERSET OF WITH NOT EQUAL TO;Sm;0;ON;;;;;Y;SUPERSET OF OR NOT EQUAL TO;;;; +228C;MULTISET;Sm;0;ON;;;;;Y;;;;; +228D;MULTISET MULTIPLICATION;Sm;0;ON;;;;;N;;;;; +228E;MULTISET UNION;Sm;0;ON;;;;;N;;;;; +228F;SQUARE IMAGE OF;Sm;0;ON;;;;;Y;;;;; +2290;SQUARE ORIGINAL OF;Sm;0;ON;;;;;Y;;;;; +2291;SQUARE IMAGE OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2292;SQUARE ORIGINAL OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2293;SQUARE CAP;Sm;0;ON;;;;;N;;;;; +2294;SQUARE CUP;Sm;0;ON;;;;;N;;;;; +2295;CIRCLED PLUS;Sm;0;ON;;;;;N;;;;; +2296;CIRCLED MINUS;Sm;0;ON;;;;;N;;;;; +2297;CIRCLED TIMES;Sm;0;ON;;;;;N;;;;; +2298;CIRCLED DIVISION SLASH;Sm;0;ON;;;;;Y;;;;; +2299;CIRCLED DOT OPERATOR;Sm;0;ON;;;;;N;;;;; +229A;CIRCLED RING OPERATOR;Sm;0;ON;;;;;N;;;;; +229B;CIRCLED ASTERISK OPERATOR;Sm;0;ON;;;;;N;;;;; +229C;CIRCLED EQUALS;Sm;0;ON;;;;;N;;;;; +229D;CIRCLED DASH;Sm;0;ON;;;;;N;;;;; +229E;SQUARED PLUS;Sm;0;ON;;;;;N;;;;; +229F;SQUARED MINUS;Sm;0;ON;;;;;N;;;;; +22A0;SQUARED TIMES;Sm;0;ON;;;;;N;;;;; +22A1;SQUARED DOT OPERATOR;Sm;0;ON;;;;;N;;;;; +22A2;RIGHT TACK;Sm;0;ON;;;;;Y;;;;; +22A3;LEFT TACK;Sm;0;ON;;;;;Y;;;;; +22A4;DOWN TACK;Sm;0;ON;;;;;N;;;;; +22A5;UP TACK;Sm;0;ON;;;;;N;;;;; +22A6;ASSERTION;Sm;0;ON;;;;;Y;;;;; +22A7;MODELS;Sm;0;ON;;;;;Y;;;;; +22A8;TRUE;Sm;0;ON;;;;;Y;;;;; +22A9;FORCES;Sm;0;ON;;;;;Y;;;;; +22AA;TRIPLE VERTICAL BAR RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +22AB;DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +22AC;DOES NOT PROVE;Sm;0;ON;22A2 0338;;;;Y;;;;; +22AD;NOT TRUE;Sm;0;ON;22A8 0338;;;;Y;;;;; +22AE;DOES NOT FORCE;Sm;0;ON;22A9 0338;;;;Y;;;;; +22AF;NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE;Sm;0;ON;22AB 0338;;;;Y;;;;; +22B0;PRECEDES UNDER RELATION;Sm;0;ON;;;;;Y;;;;; +22B1;SUCCEEDS UNDER RELATION;Sm;0;ON;;;;;Y;;;;; +22B2;NORMAL SUBGROUP OF;Sm;0;ON;;;;;Y;;;;; +22B3;CONTAINS AS NORMAL SUBGROUP;Sm;0;ON;;;;;Y;;;;; +22B4;NORMAL SUBGROUP OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +22B5;CONTAINS AS NORMAL SUBGROUP OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +22B6;ORIGINAL OF;Sm;0;ON;;;;;Y;;;;; +22B7;IMAGE OF;Sm;0;ON;;;;;Y;;;;; +22B8;MULTIMAP;Sm;0;ON;;;;;Y;;;;; +22B9;HERMITIAN CONJUGATE MATRIX;Sm;0;ON;;;;;N;;;;; +22BA;INTERCALATE;Sm;0;ON;;;;;N;;;;; +22BB;XOR;Sm;0;ON;;;;;N;;;;; +22BC;NAND;Sm;0;ON;;;;;N;;;;; +22BD;NOR;Sm;0;ON;;;;;N;;;;; +22BE;RIGHT ANGLE WITH ARC;Sm;0;ON;;;;;Y;;;;; +22BF;RIGHT TRIANGLE;Sm;0;ON;;;;;Y;;;;; +22C0;N-ARY LOGICAL AND;Sm;0;ON;;;;;N;;;;; +22C1;N-ARY LOGICAL OR;Sm;0;ON;;;;;N;;;;; +22C2;N-ARY INTERSECTION;Sm;0;ON;;;;;N;;;;; +22C3;N-ARY UNION;Sm;0;ON;;;;;N;;;;; +22C4;DIAMOND OPERATOR;Sm;0;ON;;;;;N;;;;; +22C5;DOT OPERATOR;Sm;0;ON;;;;;N;;;;; +22C6;STAR OPERATOR;Sm;0;ON;;;;;N;;;;; +22C7;DIVISION TIMES;Sm;0;ON;;;;;N;;;;; +22C8;BOWTIE;Sm;0;ON;;;;;N;;;;; +22C9;LEFT NORMAL FACTOR SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;; +22CA;RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;; +22CB;LEFT SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;; +22CC;RIGHT SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;; +22CD;REVERSED TILDE EQUALS;Sm;0;ON;;;;;Y;;;;; +22CE;CURLY LOGICAL OR;Sm;0;ON;;;;;N;;;;; +22CF;CURLY LOGICAL AND;Sm;0;ON;;;;;N;;;;; +22D0;DOUBLE SUBSET;Sm;0;ON;;;;;Y;;;;; +22D1;DOUBLE SUPERSET;Sm;0;ON;;;;;Y;;;;; +22D2;DOUBLE INTERSECTION;Sm;0;ON;;;;;N;;;;; +22D3;DOUBLE UNION;Sm;0;ON;;;;;N;;;;; +22D4;PITCHFORK;Sm;0;ON;;;;;N;;;;; +22D5;EQUAL AND PARALLEL TO;Sm;0;ON;;;;;N;;;;; +22D6;LESS-THAN WITH DOT;Sm;0;ON;;;;;Y;LESS THAN WITH DOT;;;; +22D7;GREATER-THAN WITH DOT;Sm;0;ON;;;;;Y;GREATER THAN WITH DOT;;;; +22D8;VERY MUCH LESS-THAN;Sm;0;ON;;;;;Y;VERY MUCH LESS THAN;;;; +22D9;VERY MUCH GREATER-THAN;Sm;0;ON;;;;;Y;VERY MUCH GREATER THAN;;;; +22DA;LESS-THAN EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;LESS THAN EQUAL TO OR GREATER THAN;;;; +22DB;GREATER-THAN EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;GREATER THAN EQUAL TO OR LESS THAN;;;; +22DC;EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;EQUAL TO OR LESS THAN;;;; +22DD;EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;EQUAL TO OR GREATER THAN;;;; +22DE;EQUAL TO OR PRECEDES;Sm;0;ON;;;;;Y;;;;; +22DF;EQUAL TO OR SUCCEEDS;Sm;0;ON;;;;;Y;;;;; +22E0;DOES NOT PRECEDE OR EQUAL;Sm;0;ON;227C 0338;;;;Y;;;;; +22E1;DOES NOT SUCCEED OR EQUAL;Sm;0;ON;227D 0338;;;;Y;;;;; +22E2;NOT SQUARE IMAGE OF OR EQUAL TO;Sm;0;ON;2291 0338;;;;Y;;;;; +22E3;NOT SQUARE ORIGINAL OF OR EQUAL TO;Sm;0;ON;2292 0338;;;;Y;;;;; +22E4;SQUARE IMAGE OF OR NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +22E5;SQUARE ORIGINAL OF OR NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +22E6;LESS-THAN BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;LESS THAN BUT NOT EQUIVALENT TO;;;; +22E7;GREATER-THAN BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;GREATER THAN BUT NOT EQUIVALENT TO;;;; +22E8;PRECEDES BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;; +22E9;SUCCEEDS BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;; +22EA;NOT NORMAL SUBGROUP OF;Sm;0;ON;22B2 0338;;;;Y;;;;; +22EB;DOES NOT CONTAIN AS NORMAL SUBGROUP;Sm;0;ON;22B3 0338;;;;Y;;;;; +22EC;NOT NORMAL SUBGROUP OF OR EQUAL TO;Sm;0;ON;22B4 0338;;;;Y;;;;; +22ED;DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL;Sm;0;ON;22B5 0338;;;;Y;;;;; +22EE;VERTICAL ELLIPSIS;Sm;0;ON;;;;;N;;;;; +22EF;MIDLINE HORIZONTAL ELLIPSIS;Sm;0;ON;;;;;N;;;;; +22F0;UP RIGHT DIAGONAL ELLIPSIS;Sm;0;ON;;;;;Y;;;;; +22F1;DOWN RIGHT DIAGONAL ELLIPSIS;Sm;0;ON;;;;;Y;;;;; +22F2;ELEMENT OF WITH LONG HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22F3;ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22F4;SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22F5;ELEMENT OF WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +22F6;ELEMENT OF WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +22F7;SMALL ELEMENT OF WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +22F8;ELEMENT OF WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; +22F9;ELEMENT OF WITH TWO HORIZONTAL STROKES;Sm;0;ON;;;;;Y;;;;; +22FA;CONTAINS WITH LONG HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22FB;CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22FC;SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22FD;CONTAINS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +22FE;SMALL CONTAINS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +22FF;Z NOTATION BAG MEMBERSHIP;Sm;0;ON;;;;;Y;;;;; +2300;DIAMETER SIGN;So;0;ON;;;;;N;;;;; +2301;ELECTRIC ARROW;So;0;ON;;;;;N;;;;; +2302;HOUSE;So;0;ON;;;;;N;;;;; +2303;UP ARROWHEAD;So;0;ON;;;;;N;;;;; +2304;DOWN ARROWHEAD;So;0;ON;;;;;N;;;;; +2305;PROJECTIVE;So;0;ON;;;;;N;;;;; +2306;PERSPECTIVE;So;0;ON;;;;;N;;;;; +2307;WAVY LINE;So;0;ON;;;;;N;;;;; +2308;LEFT CEILING;Sm;0;ON;;;;;Y;;;;; +2309;RIGHT CEILING;Sm;0;ON;;;;;Y;;;;; +230A;LEFT FLOOR;Sm;0;ON;;;;;Y;;;;; +230B;RIGHT FLOOR;Sm;0;ON;;;;;Y;;;;; +230C;BOTTOM RIGHT CROP;So;0;ON;;;;;N;;;;; +230D;BOTTOM LEFT CROP;So;0;ON;;;;;N;;;;; +230E;TOP RIGHT CROP;So;0;ON;;;;;N;;;;; +230F;TOP LEFT CROP;So;0;ON;;;;;N;;;;; +2310;REVERSED NOT SIGN;So;0;ON;;;;;N;;;;; +2311;SQUARE LOZENGE;So;0;ON;;;;;N;;;;; +2312;ARC;So;0;ON;;;;;N;;;;; +2313;SEGMENT;So;0;ON;;;;;N;;;;; +2314;SECTOR;So;0;ON;;;;;N;;;;; +2315;TELEPHONE RECORDER;So;0;ON;;;;;N;;;;; +2316;POSITION INDICATOR;So;0;ON;;;;;N;;;;; +2317;VIEWDATA SQUARE;So;0;ON;;;;;N;;;;; +2318;PLACE OF INTEREST SIGN;So;0;ON;;;;;N;COMMAND KEY;;;; +2319;TURNED NOT SIGN;So;0;ON;;;;;N;;;;; +231A;WATCH;So;0;ON;;;;;N;;;;; +231B;HOURGLASS;So;0;ON;;;;;N;;;;; +231C;TOP LEFT CORNER;So;0;ON;;;;;N;;;;; +231D;TOP RIGHT CORNER;So;0;ON;;;;;N;;;;; +231E;BOTTOM LEFT CORNER;So;0;ON;;;;;N;;;;; +231F;BOTTOM RIGHT CORNER;So;0;ON;;;;;N;;;;; +2320;TOP HALF INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2321;BOTTOM HALF INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2322;FROWN;So;0;ON;;;;;N;;;;; +2323;SMILE;So;0;ON;;;;;N;;;;; +2324;UP ARROWHEAD BETWEEN TWO HORIZONTAL BARS;So;0;ON;;;;;N;ENTER KEY;;;; +2325;OPTION KEY;So;0;ON;;;;;N;;;;; +2326;ERASE TO THE RIGHT;So;0;ON;;;;;N;DELETE TO THE RIGHT KEY;;;; +2327;X IN A RECTANGLE BOX;So;0;ON;;;;;N;CLEAR KEY;;;; +2328;KEYBOARD;So;0;ON;;;;;N;;;;; +2329;LEFT-POINTING ANGLE BRACKET;Ps;0;ON;3008;;;;Y;BRA;;;; +232A;RIGHT-POINTING ANGLE BRACKET;Pe;0;ON;3009;;;;Y;KET;;;; +232B;ERASE TO THE LEFT;So;0;ON;;;;;N;DELETE TO THE LEFT KEY;;;; +232C;BENZENE RING;So;0;ON;;;;;N;;;;; +232D;CYLINDRICITY;So;0;ON;;;;;N;;;;; +232E;ALL AROUND-PROFILE;So;0;ON;;;;;N;;;;; +232F;SYMMETRY;So;0;ON;;;;;N;;;;; +2330;TOTAL RUNOUT;So;0;ON;;;;;N;;;;; +2331;DIMENSION ORIGIN;So;0;ON;;;;;N;;;;; +2332;CONICAL TAPER;So;0;ON;;;;;N;;;;; +2333;SLOPE;So;0;ON;;;;;N;;;;; +2334;COUNTERBORE;So;0;ON;;;;;N;;;;; +2335;COUNTERSINK;So;0;ON;;;;;N;;;;; +2336;APL FUNCTIONAL SYMBOL I-BEAM;So;0;L;;;;;N;;;;; +2337;APL FUNCTIONAL SYMBOL SQUISH QUAD;So;0;L;;;;;N;;;;; +2338;APL FUNCTIONAL SYMBOL QUAD EQUAL;So;0;L;;;;;N;;;;; +2339;APL FUNCTIONAL SYMBOL QUAD DIVIDE;So;0;L;;;;;N;;;;; +233A;APL FUNCTIONAL SYMBOL QUAD DIAMOND;So;0;L;;;;;N;;;;; +233B;APL FUNCTIONAL SYMBOL QUAD JOT;So;0;L;;;;;N;;;;; +233C;APL FUNCTIONAL SYMBOL QUAD CIRCLE;So;0;L;;;;;N;;;;; +233D;APL FUNCTIONAL SYMBOL CIRCLE STILE;So;0;L;;;;;N;;;;; +233E;APL FUNCTIONAL SYMBOL CIRCLE JOT;So;0;L;;;;;N;;;;; +233F;APL FUNCTIONAL SYMBOL SLASH BAR;So;0;L;;;;;N;;;;; +2340;APL FUNCTIONAL SYMBOL BACKSLASH BAR;So;0;L;;;;;N;;;;; +2341;APL FUNCTIONAL SYMBOL QUAD SLASH;So;0;L;;;;;N;;;;; +2342;APL FUNCTIONAL SYMBOL QUAD BACKSLASH;So;0;L;;;;;N;;;;; +2343;APL FUNCTIONAL SYMBOL QUAD LESS-THAN;So;0;L;;;;;N;;;;; +2344;APL FUNCTIONAL SYMBOL QUAD GREATER-THAN;So;0;L;;;;;N;;;;; +2345;APL FUNCTIONAL SYMBOL LEFTWARDS VANE;So;0;L;;;;;N;;;;; +2346;APL FUNCTIONAL SYMBOL RIGHTWARDS VANE;So;0;L;;;;;N;;;;; +2347;APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW;So;0;L;;;;;N;;;;; +2348;APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW;So;0;L;;;;;N;;;;; +2349;APL FUNCTIONAL SYMBOL CIRCLE BACKSLASH;So;0;L;;;;;N;;;;; +234A;APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR;So;0;L;;;;;N;;*;;; +234B;APL FUNCTIONAL SYMBOL DELTA STILE;So;0;L;;;;;N;;;;; +234C;APL FUNCTIONAL SYMBOL QUAD DOWN CARET;So;0;L;;;;;N;;;;; +234D;APL FUNCTIONAL SYMBOL QUAD DELTA;So;0;L;;;;;N;;;;; +234E;APL FUNCTIONAL SYMBOL DOWN TACK JOT;So;0;L;;;;;N;;*;;; +234F;APL FUNCTIONAL SYMBOL UPWARDS VANE;So;0;L;;;;;N;;;;; +2350;APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW;So;0;L;;;;;N;;;;; +2351;APL FUNCTIONAL SYMBOL UP TACK OVERBAR;So;0;L;;;;;N;;*;;; +2352;APL FUNCTIONAL SYMBOL DEL STILE;So;0;L;;;;;N;;;;; +2353;APL FUNCTIONAL SYMBOL QUAD UP CARET;So;0;L;;;;;N;;;;; +2354;APL FUNCTIONAL SYMBOL QUAD DEL;So;0;L;;;;;N;;;;; +2355;APL FUNCTIONAL SYMBOL UP TACK JOT;So;0;L;;;;;N;;*;;; +2356;APL FUNCTIONAL SYMBOL DOWNWARDS VANE;So;0;L;;;;;N;;;;; +2357;APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW;So;0;L;;;;;N;;;;; +2358;APL FUNCTIONAL SYMBOL QUOTE UNDERBAR;So;0;L;;;;;N;;;;; +2359;APL FUNCTIONAL SYMBOL DELTA UNDERBAR;So;0;L;;;;;N;;;;; +235A;APL FUNCTIONAL SYMBOL DIAMOND UNDERBAR;So;0;L;;;;;N;;;;; +235B;APL FUNCTIONAL SYMBOL JOT UNDERBAR;So;0;L;;;;;N;;;;; +235C;APL FUNCTIONAL SYMBOL CIRCLE UNDERBAR;So;0;L;;;;;N;;;;; +235D;APL FUNCTIONAL SYMBOL UP SHOE JOT;So;0;L;;;;;N;;;;; +235E;APL FUNCTIONAL SYMBOL QUOTE QUAD;So;0;L;;;;;N;;;;; +235F;APL FUNCTIONAL SYMBOL CIRCLE STAR;So;0;L;;;;;N;;;;; +2360;APL FUNCTIONAL SYMBOL QUAD COLON;So;0;L;;;;;N;;;;; +2361;APL FUNCTIONAL SYMBOL UP TACK DIAERESIS;So;0;L;;;;;N;;*;;; +2362;APL FUNCTIONAL SYMBOL DEL DIAERESIS;So;0;L;;;;;N;;;;; +2363;APL FUNCTIONAL SYMBOL STAR DIAERESIS;So;0;L;;;;;N;;;;; +2364;APL FUNCTIONAL SYMBOL JOT DIAERESIS;So;0;L;;;;;N;;;;; +2365;APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS;So;0;L;;;;;N;;;;; +2366;APL FUNCTIONAL SYMBOL DOWN SHOE STILE;So;0;L;;;;;N;;;;; +2367;APL FUNCTIONAL SYMBOL LEFT SHOE STILE;So;0;L;;;;;N;;;;; +2368;APL FUNCTIONAL SYMBOL TILDE DIAERESIS;So;0;L;;;;;N;;;;; +2369;APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS;So;0;L;;;;;N;;;;; +236A;APL FUNCTIONAL SYMBOL COMMA BAR;So;0;L;;;;;N;;;;; +236B;APL FUNCTIONAL SYMBOL DEL TILDE;So;0;L;;;;;N;;;;; +236C;APL FUNCTIONAL SYMBOL ZILDE;So;0;L;;;;;N;;;;; +236D;APL FUNCTIONAL SYMBOL STILE TILDE;So;0;L;;;;;N;;;;; +236E;APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR;So;0;L;;;;;N;;;;; +236F;APL FUNCTIONAL SYMBOL QUAD NOT EQUAL;So;0;L;;;;;N;;;;; +2370;APL FUNCTIONAL SYMBOL QUAD QUESTION;So;0;L;;;;;N;;;;; +2371;APL FUNCTIONAL SYMBOL DOWN CARET TILDE;So;0;L;;;;;N;;;;; +2372;APL FUNCTIONAL SYMBOL UP CARET TILDE;So;0;L;;;;;N;;;;; +2373;APL FUNCTIONAL SYMBOL IOTA;So;0;L;;;;;N;;;;; +2374;APL FUNCTIONAL SYMBOL RHO;So;0;L;;;;;N;;;;; +2375;APL FUNCTIONAL SYMBOL OMEGA;So;0;L;;;;;N;;;;; +2376;APL FUNCTIONAL SYMBOL ALPHA UNDERBAR;So;0;L;;;;;N;;;;; +2377;APL FUNCTIONAL SYMBOL EPSILON UNDERBAR;So;0;L;;;;;N;;;;; +2378;APL FUNCTIONAL SYMBOL IOTA UNDERBAR;So;0;L;;;;;N;;;;; +2379;APL FUNCTIONAL SYMBOL OMEGA UNDERBAR;So;0;L;;;;;N;;;;; +237A;APL FUNCTIONAL SYMBOL ALPHA;So;0;L;;;;;N;;;;; +237B;NOT CHECK MARK;So;0;ON;;;;;N;;;;; +237C;RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW;Sm;0;ON;;;;;N;;;;; +237D;SHOULDERED OPEN BOX;So;0;ON;;;;;N;;;;; +237E;BELL SYMBOL;So;0;ON;;;;;N;;;;; +237F;VERTICAL LINE WITH MIDDLE DOT;So;0;ON;;;;;N;;;;; +2380;INSERTION SYMBOL;So;0;ON;;;;;N;;;;; +2381;CONTINUOUS UNDERLINE SYMBOL;So;0;ON;;;;;N;;;;; +2382;DISCONTINUOUS UNDERLINE SYMBOL;So;0;ON;;;;;N;;;;; +2383;EMPHASIS SYMBOL;So;0;ON;;;;;N;;;;; +2384;COMPOSITION SYMBOL;So;0;ON;;;;;N;;;;; +2385;WHITE SQUARE WITH CENTRE VERTICAL LINE;So;0;ON;;;;;N;;;;; +2386;ENTER SYMBOL;So;0;ON;;;;;N;;;;; +2387;ALTERNATIVE KEY SYMBOL;So;0;ON;;;;;N;;;;; +2388;HELM SYMBOL;So;0;ON;;;;;N;;;;; +2389;CIRCLED HORIZONTAL BAR WITH NOTCH;So;0;ON;;;;;N;;pause;;; +238A;CIRCLED TRIANGLE DOWN;So;0;ON;;;;;N;;break;;; +238B;BROKEN CIRCLE WITH NORTHWEST ARROW;So;0;ON;;;;;N;;escape;;; +238C;UNDO SYMBOL;So;0;ON;;;;;N;;;;; +238D;MONOSTABLE SYMBOL;So;0;ON;;;;;N;;;;; +238E;HYSTERESIS SYMBOL;So;0;ON;;;;;N;;;;; +238F;OPEN-CIRCUIT-OUTPUT H-TYPE SYMBOL;So;0;ON;;;;;N;;;;; +2390;OPEN-CIRCUIT-OUTPUT L-TYPE SYMBOL;So;0;ON;;;;;N;;;;; +2391;PASSIVE-PULL-DOWN-OUTPUT SYMBOL;So;0;ON;;;;;N;;;;; +2392;PASSIVE-PULL-UP-OUTPUT SYMBOL;So;0;ON;;;;;N;;;;; +2393;DIRECT CURRENT SYMBOL FORM TWO;So;0;ON;;;;;N;;;;; +2394;SOFTWARE-FUNCTION SYMBOL;So;0;ON;;;;;N;;;;; +2395;APL FUNCTIONAL SYMBOL QUAD;So;0;L;;;;;N;;;;; +2396;DECIMAL SEPARATOR KEY SYMBOL;So;0;ON;;;;;N;;;;; +2397;PREVIOUS PAGE;So;0;ON;;;;;N;;;;; +2398;NEXT PAGE;So;0;ON;;;;;N;;;;; +2399;PRINT SCREEN SYMBOL;So;0;ON;;;;;N;;;;; +239A;CLEAR SCREEN SYMBOL;So;0;ON;;;;;N;;;;; +239B;LEFT PARENTHESIS UPPER HOOK;Sm;0;ON;;;;;N;;;;; +239C;LEFT PARENTHESIS EXTENSION;Sm;0;ON;;;;;N;;;;; +239D;LEFT PARENTHESIS LOWER HOOK;Sm;0;ON;;;;;N;;;;; +239E;RIGHT PARENTHESIS UPPER HOOK;Sm;0;ON;;;;;N;;;;; +239F;RIGHT PARENTHESIS EXTENSION;Sm;0;ON;;;;;N;;;;; +23A0;RIGHT PARENTHESIS LOWER HOOK;Sm;0;ON;;;;;N;;;;; +23A1;LEFT SQUARE BRACKET UPPER CORNER;Sm;0;ON;;;;;N;;;;; +23A2;LEFT SQUARE BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;; +23A3;LEFT SQUARE BRACKET LOWER CORNER;Sm;0;ON;;;;;N;;;;; +23A4;RIGHT SQUARE BRACKET UPPER CORNER;Sm;0;ON;;;;;N;;;;; +23A5;RIGHT SQUARE BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;; +23A6;RIGHT SQUARE BRACKET LOWER CORNER;Sm;0;ON;;;;;N;;;;; +23A7;LEFT CURLY BRACKET UPPER HOOK;Sm;0;ON;;;;;N;;;;; +23A8;LEFT CURLY BRACKET MIDDLE PIECE;Sm;0;ON;;;;;N;;;;; +23A9;LEFT CURLY BRACKET LOWER HOOK;Sm;0;ON;;;;;N;;;;; +23AA;CURLY BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;; +23AB;RIGHT CURLY BRACKET UPPER HOOK;Sm;0;ON;;;;;N;;;;; +23AC;RIGHT CURLY BRACKET MIDDLE PIECE;Sm;0;ON;;;;;N;;;;; +23AD;RIGHT CURLY BRACKET LOWER HOOK;Sm;0;ON;;;;;N;;;;; +23AE;INTEGRAL EXTENSION;Sm;0;ON;;;;;N;;;;; +23AF;HORIZONTAL LINE EXTENSION;Sm;0;ON;;;;;N;;;;; +23B0;UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION;Sm;0;ON;;;;;N;;;;; +23B1;UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION;Sm;0;ON;;;;;N;;;;; +23B2;SUMMATION TOP;Sm;0;ON;;;;;N;;;;; +23B3;SUMMATION BOTTOM;Sm;0;ON;;;;;N;;;;; +23B4;TOP SQUARE BRACKET;Ps;0;ON;;;;;N;;;;; +23B5;BOTTOM SQUARE BRACKET;Pe;0;ON;;;;;N;;;;; +23B6;BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET;Po;0;ON;;;;;N;;;;; +23B7;RADICAL SYMBOL BOTTOM;So;0;ON;;;;;N;;;;; +23B8;LEFT VERTICAL BOX LINE;So;0;ON;;;;;N;;;;; +23B9;RIGHT VERTICAL BOX LINE;So;0;ON;;;;;N;;;;; +23BA;HORIZONTAL SCAN LINE-1;So;0;ON;;;;;N;;;;; +23BB;HORIZONTAL SCAN LINE-3;So;0;ON;;;;;N;;;;; +23BC;HORIZONTAL SCAN LINE-7;So;0;ON;;;;;N;;;;; +23BD;HORIZONTAL SCAN LINE-9;So;0;ON;;;;;N;;;;; +23BE;DENTISTRY SYMBOL LIGHT VERTICAL AND TOP RIGHT;So;0;ON;;;;;N;;;;; +23BF;DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM RIGHT;So;0;ON;;;;;N;;;;; +23C0;DENTISTRY SYMBOL LIGHT VERTICAL WITH CIRCLE;So;0;ON;;;;;N;;;;; +23C1;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH CIRCLE;So;0;ON;;;;;N;;;;; +23C2;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH CIRCLE;So;0;ON;;;;;N;;;;; +23C3;DENTISTRY SYMBOL LIGHT VERTICAL WITH TRIANGLE;So;0;ON;;;;;N;;;;; +23C4;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH TRIANGLE;So;0;ON;;;;;N;;;;; +23C5;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH TRIANGLE;So;0;ON;;;;;N;;;;; +23C6;DENTISTRY SYMBOL LIGHT VERTICAL AND WAVE;So;0;ON;;;;;N;;;;; +23C7;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH WAVE;So;0;ON;;;;;N;;;;; +23C8;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH WAVE;So;0;ON;;;;;N;;;;; +23C9;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL;So;0;ON;;;;;N;;;;; +23CA;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL;So;0;ON;;;;;N;;;;; +23CB;DENTISTRY SYMBOL LIGHT VERTICAL AND TOP LEFT;So;0;ON;;;;;N;;;;; +23CC;DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM LEFT;So;0;ON;;;;;N;;;;; +23CD;SQUARE FOOT;So;0;ON;;;;;N;;;;; +23CE;RETURN SYMBOL;So;0;ON;;;;;N;;;;; +2400;SYMBOL FOR NULL;So;0;ON;;;;;N;GRAPHIC FOR NULL;;;; +2401;SYMBOL FOR START OF HEADING;So;0;ON;;;;;N;GRAPHIC FOR START OF HEADING;;;; +2402;SYMBOL FOR START OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR START OF TEXT;;;; +2403;SYMBOL FOR END OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR END OF TEXT;;;; +2404;SYMBOL FOR END OF TRANSMISSION;So;0;ON;;;;;N;GRAPHIC FOR END OF TRANSMISSION;;;; +2405;SYMBOL FOR ENQUIRY;So;0;ON;;;;;N;GRAPHIC FOR ENQUIRY;;;; +2406;SYMBOL FOR ACKNOWLEDGE;So;0;ON;;;;;N;GRAPHIC FOR ACKNOWLEDGE;;;; +2407;SYMBOL FOR BELL;So;0;ON;;;;;N;GRAPHIC FOR BELL;;;; +2408;SYMBOL FOR BACKSPACE;So;0;ON;;;;;N;GRAPHIC FOR BACKSPACE;;;; +2409;SYMBOL FOR HORIZONTAL TABULATION;So;0;ON;;;;;N;GRAPHIC FOR HORIZONTAL TABULATION;;;; +240A;SYMBOL FOR LINE FEED;So;0;ON;;;;;N;GRAPHIC FOR LINE FEED;;;; +240B;SYMBOL FOR VERTICAL TABULATION;So;0;ON;;;;;N;GRAPHIC FOR VERTICAL TABULATION;;;; +240C;SYMBOL FOR FORM FEED;So;0;ON;;;;;N;GRAPHIC FOR FORM FEED;;;; +240D;SYMBOL FOR CARRIAGE RETURN;So;0;ON;;;;;N;GRAPHIC FOR CARRIAGE RETURN;;;; +240E;SYMBOL FOR SHIFT OUT;So;0;ON;;;;;N;GRAPHIC FOR SHIFT OUT;;;; +240F;SYMBOL FOR SHIFT IN;So;0;ON;;;;;N;GRAPHIC FOR SHIFT IN;;;; +2410;SYMBOL FOR DATA LINK ESCAPE;So;0;ON;;;;;N;GRAPHIC FOR DATA LINK ESCAPE;;;; +2411;SYMBOL FOR DEVICE CONTROL ONE;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL ONE;;;; +2412;SYMBOL FOR DEVICE CONTROL TWO;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL TWO;;;; +2413;SYMBOL FOR DEVICE CONTROL THREE;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL THREE;;;; +2414;SYMBOL FOR DEVICE CONTROL FOUR;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL FOUR;;;; +2415;SYMBOL FOR NEGATIVE ACKNOWLEDGE;So;0;ON;;;;;N;GRAPHIC FOR NEGATIVE ACKNOWLEDGE;;;; +2416;SYMBOL FOR SYNCHRONOUS IDLE;So;0;ON;;;;;N;GRAPHIC FOR SYNCHRONOUS IDLE;;;; +2417;SYMBOL FOR END OF TRANSMISSION BLOCK;So;0;ON;;;;;N;GRAPHIC FOR END OF TRANSMISSION BLOCK;;;; +2418;SYMBOL FOR CANCEL;So;0;ON;;;;;N;GRAPHIC FOR CANCEL;;;; +2419;SYMBOL FOR END OF MEDIUM;So;0;ON;;;;;N;GRAPHIC FOR END OF MEDIUM;;;; +241A;SYMBOL FOR SUBSTITUTE;So;0;ON;;;;;N;GRAPHIC FOR SUBSTITUTE;;;; +241B;SYMBOL FOR ESCAPE;So;0;ON;;;;;N;GRAPHIC FOR ESCAPE;;;; +241C;SYMBOL FOR FILE SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR FILE SEPARATOR;;;; +241D;SYMBOL FOR GROUP SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR GROUP SEPARATOR;;;; +241E;SYMBOL FOR RECORD SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR RECORD SEPARATOR;;;; +241F;SYMBOL FOR UNIT SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR UNIT SEPARATOR;;;; +2420;SYMBOL FOR SPACE;So;0;ON;;;;;N;GRAPHIC FOR SPACE;;;; +2421;SYMBOL FOR DELETE;So;0;ON;;;;;N;GRAPHIC FOR DELETE;;;; +2422;BLANK SYMBOL;So;0;ON;;;;;N;BLANK;;;; +2423;OPEN BOX;So;0;ON;;;;;N;;;;; +2424;SYMBOL FOR NEWLINE;So;0;ON;;;;;N;GRAPHIC FOR NEWLINE;;;; +2425;SYMBOL FOR DELETE FORM TWO;So;0;ON;;;;;N;;;;; +2426;SYMBOL FOR SUBSTITUTE FORM TWO;So;0;ON;;;;;N;;;;; +2440;OCR HOOK;So;0;ON;;;;;N;;;;; +2441;OCR CHAIR;So;0;ON;;;;;N;;;;; +2442;OCR FORK;So;0;ON;;;;;N;;;;; +2443;OCR INVERTED FORK;So;0;ON;;;;;N;;;;; +2444;OCR BELT BUCKLE;So;0;ON;;;;;N;;;;; +2445;OCR BOW TIE;So;0;ON;;;;;N;;;;; +2446;OCR BRANCH BANK IDENTIFICATION;So;0;ON;;;;;N;;;;; +2447;OCR AMOUNT OF CHECK;So;0;ON;;;;;N;;;;; +2448;OCR DASH;So;0;ON;;;;;N;;;;; +2449;OCR CUSTOMER ACCOUNT NUMBER;So;0;ON;;;;;N;;;;; +244A;OCR DOUBLE BACKSLASH;So;0;ON;;;;;N;;;;; +2460;CIRCLED DIGIT ONE;No;0;EN; 0031;;1;1;N;;;;; +2461;CIRCLED DIGIT TWO;No;0;EN; 0032;;2;2;N;;;;; +2462;CIRCLED DIGIT THREE;No;0;EN; 0033;;3;3;N;;;;; +2463;CIRCLED DIGIT FOUR;No;0;EN; 0034;;4;4;N;;;;; +2464;CIRCLED DIGIT FIVE;No;0;EN; 0035;;5;5;N;;;;; +2465;CIRCLED DIGIT SIX;No;0;EN; 0036;;6;6;N;;;;; +2466;CIRCLED DIGIT SEVEN;No;0;EN; 0037;;7;7;N;;;;; +2467;CIRCLED DIGIT EIGHT;No;0;EN; 0038;;8;8;N;;;;; +2468;CIRCLED DIGIT NINE;No;0;EN; 0039;;9;9;N;;;;; +2469;CIRCLED NUMBER TEN;No;0;EN; 0031 0030;;;10;N;;;;; +246A;CIRCLED NUMBER ELEVEN;No;0;EN; 0031 0031;;;11;N;;;;; +246B;CIRCLED NUMBER TWELVE;No;0;EN; 0031 0032;;;12;N;;;;; +246C;CIRCLED NUMBER THIRTEEN;No;0;EN; 0031 0033;;;13;N;;;;; +246D;CIRCLED NUMBER FOURTEEN;No;0;EN; 0031 0034;;;14;N;;;;; +246E;CIRCLED NUMBER FIFTEEN;No;0;EN; 0031 0035;;;15;N;;;;; +246F;CIRCLED NUMBER SIXTEEN;No;0;EN; 0031 0036;;;16;N;;;;; +2470;CIRCLED NUMBER SEVENTEEN;No;0;EN; 0031 0037;;;17;N;;;;; +2471;CIRCLED NUMBER EIGHTEEN;No;0;EN; 0031 0038;;;18;N;;;;; +2472;CIRCLED NUMBER NINETEEN;No;0;EN; 0031 0039;;;19;N;;;;; +2473;CIRCLED NUMBER TWENTY;No;0;EN; 0032 0030;;;20;N;;;;; +2474;PARENTHESIZED DIGIT ONE;No;0;EN; 0028 0031 0029;;1;1;N;;;;; +2475;PARENTHESIZED DIGIT TWO;No;0;EN; 0028 0032 0029;;2;2;N;;;;; +2476;PARENTHESIZED DIGIT THREE;No;0;EN; 0028 0033 0029;;3;3;N;;;;; +2477;PARENTHESIZED DIGIT FOUR;No;0;EN; 0028 0034 0029;;4;4;N;;;;; +2478;PARENTHESIZED DIGIT FIVE;No;0;EN; 0028 0035 0029;;5;5;N;;;;; +2479;PARENTHESIZED DIGIT SIX;No;0;EN; 0028 0036 0029;;6;6;N;;;;; +247A;PARENTHESIZED DIGIT SEVEN;No;0;EN; 0028 0037 0029;;7;7;N;;;;; +247B;PARENTHESIZED DIGIT EIGHT;No;0;EN; 0028 0038 0029;;8;8;N;;;;; +247C;PARENTHESIZED DIGIT NINE;No;0;EN; 0028 0039 0029;;9;9;N;;;;; +247D;PARENTHESIZED NUMBER TEN;No;0;EN; 0028 0031 0030 0029;;;10;N;;;;; +247E;PARENTHESIZED NUMBER ELEVEN;No;0;EN; 0028 0031 0031 0029;;;11;N;;;;; +247F;PARENTHESIZED NUMBER TWELVE;No;0;EN; 0028 0031 0032 0029;;;12;N;;;;; +2480;PARENTHESIZED NUMBER THIRTEEN;No;0;EN; 0028 0031 0033 0029;;;13;N;;;;; +2481;PARENTHESIZED NUMBER FOURTEEN;No;0;EN; 0028 0031 0034 0029;;;14;N;;;;; +2482;PARENTHESIZED NUMBER FIFTEEN;No;0;EN; 0028 0031 0035 0029;;;15;N;;;;; +2483;PARENTHESIZED NUMBER SIXTEEN;No;0;EN; 0028 0031 0036 0029;;;16;N;;;;; +2484;PARENTHESIZED NUMBER SEVENTEEN;No;0;EN; 0028 0031 0037 0029;;;17;N;;;;; +2485;PARENTHESIZED NUMBER EIGHTEEN;No;0;EN; 0028 0031 0038 0029;;;18;N;;;;; +2486;PARENTHESIZED NUMBER NINETEEN;No;0;EN; 0028 0031 0039 0029;;;19;N;;;;; +2487;PARENTHESIZED NUMBER TWENTY;No;0;EN; 0028 0032 0030 0029;;;20;N;;;;; +2488;DIGIT ONE FULL STOP;No;0;EN; 0031 002E;;1;1;N;DIGIT ONE PERIOD;;;; +2489;DIGIT TWO FULL STOP;No;0;EN; 0032 002E;;2;2;N;DIGIT TWO PERIOD;;;; +248A;DIGIT THREE FULL STOP;No;0;EN; 0033 002E;;3;3;N;DIGIT THREE PERIOD;;;; +248B;DIGIT FOUR FULL STOP;No;0;EN; 0034 002E;;4;4;N;DIGIT FOUR PERIOD;;;; +248C;DIGIT FIVE FULL STOP;No;0;EN; 0035 002E;;5;5;N;DIGIT FIVE PERIOD;;;; +248D;DIGIT SIX FULL STOP;No;0;EN; 0036 002E;;6;6;N;DIGIT SIX PERIOD;;;; +248E;DIGIT SEVEN FULL STOP;No;0;EN; 0037 002E;;7;7;N;DIGIT SEVEN PERIOD;;;; +248F;DIGIT EIGHT FULL STOP;No;0;EN; 0038 002E;;8;8;N;DIGIT EIGHT PERIOD;;;; +2490;DIGIT NINE FULL STOP;No;0;EN; 0039 002E;;9;9;N;DIGIT NINE PERIOD;;;; +2491;NUMBER TEN FULL STOP;No;0;EN; 0031 0030 002E;;;10;N;NUMBER TEN PERIOD;;;; +2492;NUMBER ELEVEN FULL STOP;No;0;EN; 0031 0031 002E;;;11;N;NUMBER ELEVEN PERIOD;;;; +2493;NUMBER TWELVE FULL STOP;No;0;EN; 0031 0032 002E;;;12;N;NUMBER TWELVE PERIOD;;;; +2494;NUMBER THIRTEEN FULL STOP;No;0;EN; 0031 0033 002E;;;13;N;NUMBER THIRTEEN PERIOD;;;; +2495;NUMBER FOURTEEN FULL STOP;No;0;EN; 0031 0034 002E;;;14;N;NUMBER FOURTEEN PERIOD;;;; +2496;NUMBER FIFTEEN FULL STOP;No;0;EN; 0031 0035 002E;;;15;N;NUMBER FIFTEEN PERIOD;;;; +2497;NUMBER SIXTEEN FULL STOP;No;0;EN; 0031 0036 002E;;;16;N;NUMBER SIXTEEN PERIOD;;;; +2498;NUMBER SEVENTEEN FULL STOP;No;0;EN; 0031 0037 002E;;;17;N;NUMBER SEVENTEEN PERIOD;;;; +2499;NUMBER EIGHTEEN FULL STOP;No;0;EN; 0031 0038 002E;;;18;N;NUMBER EIGHTEEN PERIOD;;;; +249A;NUMBER NINETEEN FULL STOP;No;0;EN; 0031 0039 002E;;;19;N;NUMBER NINETEEN PERIOD;;;; +249B;NUMBER TWENTY FULL STOP;No;0;EN; 0032 0030 002E;;;20;N;NUMBER TWENTY PERIOD;;;; +249C;PARENTHESIZED LATIN SMALL LETTER A;So;0;L; 0028 0061 0029;;;;N;;;;; +249D;PARENTHESIZED LATIN SMALL LETTER B;So;0;L; 0028 0062 0029;;;;N;;;;; +249E;PARENTHESIZED LATIN SMALL LETTER C;So;0;L; 0028 0063 0029;;;;N;;;;; +249F;PARENTHESIZED LATIN SMALL LETTER D;So;0;L; 0028 0064 0029;;;;N;;;;; +24A0;PARENTHESIZED LATIN SMALL LETTER E;So;0;L; 0028 0065 0029;;;;N;;;;; +24A1;PARENTHESIZED LATIN SMALL LETTER F;So;0;L; 0028 0066 0029;;;;N;;;;; +24A2;PARENTHESIZED LATIN SMALL LETTER G;So;0;L; 0028 0067 0029;;;;N;;;;; +24A3;PARENTHESIZED LATIN SMALL LETTER H;So;0;L; 0028 0068 0029;;;;N;;;;; +24A4;PARENTHESIZED LATIN SMALL LETTER I;So;0;L; 0028 0069 0029;;;;N;;;;; +24A5;PARENTHESIZED LATIN SMALL LETTER J;So;0;L; 0028 006A 0029;;;;N;;;;; +24A6;PARENTHESIZED LATIN SMALL LETTER K;So;0;L; 0028 006B 0029;;;;N;;;;; +24A7;PARENTHESIZED LATIN SMALL LETTER L;So;0;L; 0028 006C 0029;;;;N;;;;; +24A8;PARENTHESIZED LATIN SMALL LETTER M;So;0;L; 0028 006D 0029;;;;N;;;;; +24A9;PARENTHESIZED LATIN SMALL LETTER N;So;0;L; 0028 006E 0029;;;;N;;;;; +24AA;PARENTHESIZED LATIN SMALL LETTER O;So;0;L; 0028 006F 0029;;;;N;;;;; +24AB;PARENTHESIZED LATIN SMALL LETTER P;So;0;L; 0028 0070 0029;;;;N;;;;; +24AC;PARENTHESIZED LATIN SMALL LETTER Q;So;0;L; 0028 0071 0029;;;;N;;;;; +24AD;PARENTHESIZED LATIN SMALL LETTER R;So;0;L; 0028 0072 0029;;;;N;;;;; +24AE;PARENTHESIZED LATIN SMALL LETTER S;So;0;L; 0028 0073 0029;;;;N;;;;; +24AF;PARENTHESIZED LATIN SMALL LETTER T;So;0;L; 0028 0074 0029;;;;N;;;;; +24B0;PARENTHESIZED LATIN SMALL LETTER U;So;0;L; 0028 0075 0029;;;;N;;;;; +24B1;PARENTHESIZED LATIN SMALL LETTER V;So;0;L; 0028 0076 0029;;;;N;;;;; +24B2;PARENTHESIZED LATIN SMALL LETTER W;So;0;L; 0028 0077 0029;;;;N;;;;; +24B3;PARENTHESIZED LATIN SMALL LETTER X;So;0;L; 0028 0078 0029;;;;N;;;;; +24B4;PARENTHESIZED LATIN SMALL LETTER Y;So;0;L; 0028 0079 0029;;;;N;;;;; +24B5;PARENTHESIZED LATIN SMALL LETTER Z;So;0;L; 0028 007A 0029;;;;N;;;;; +24B6;CIRCLED LATIN CAPITAL LETTER A;So;0;L; 0041;;;;N;;;;24D0; +24B7;CIRCLED LATIN CAPITAL LETTER B;So;0;L; 0042;;;;N;;;;24D1; +24B8;CIRCLED LATIN CAPITAL LETTER C;So;0;L; 0043;;;;N;;;;24D2; +24B9;CIRCLED LATIN CAPITAL LETTER D;So;0;L; 0044;;;;N;;;;24D3; +24BA;CIRCLED LATIN CAPITAL LETTER E;So;0;L; 0045;;;;N;;;;24D4; +24BB;CIRCLED LATIN CAPITAL LETTER F;So;0;L; 0046;;;;N;;;;24D5; +24BC;CIRCLED LATIN CAPITAL LETTER G;So;0;L; 0047;;;;N;;;;24D6; +24BD;CIRCLED LATIN CAPITAL LETTER H;So;0;L; 0048;;;;N;;;;24D7; +24BE;CIRCLED LATIN CAPITAL LETTER I;So;0;L; 0049;;;;N;;;;24D8; +24BF;CIRCLED LATIN CAPITAL LETTER J;So;0;L; 004A;;;;N;;;;24D9; +24C0;CIRCLED LATIN CAPITAL LETTER K;So;0;L; 004B;;;;N;;;;24DA; +24C1;CIRCLED LATIN CAPITAL LETTER L;So;0;L; 004C;;;;N;;;;24DB; +24C2;CIRCLED LATIN CAPITAL LETTER M;So;0;L; 004D;;;;N;;;;24DC; +24C3;CIRCLED LATIN CAPITAL LETTER N;So;0;L; 004E;;;;N;;;;24DD; +24C4;CIRCLED LATIN CAPITAL LETTER O;So;0;L; 004F;;;;N;;;;24DE; +24C5;CIRCLED LATIN CAPITAL LETTER P;So;0;L; 0050;;;;N;;;;24DF; +24C6;CIRCLED LATIN CAPITAL LETTER Q;So;0;L; 0051;;;;N;;;;24E0; +24C7;CIRCLED LATIN CAPITAL LETTER R;So;0;L; 0052;;;;N;;;;24E1; +24C8;CIRCLED LATIN CAPITAL LETTER S;So;0;L; 0053;;;;N;;;;24E2; +24C9;CIRCLED LATIN CAPITAL LETTER T;So;0;L; 0054;;;;N;;;;24E3; +24CA;CIRCLED LATIN CAPITAL LETTER U;So;0;L; 0055;;;;N;;;;24E4; +24CB;CIRCLED LATIN CAPITAL LETTER V;So;0;L; 0056;;;;N;;;;24E5; +24CC;CIRCLED LATIN CAPITAL LETTER W;So;0;L; 0057;;;;N;;;;24E6; +24CD;CIRCLED LATIN CAPITAL LETTER X;So;0;L; 0058;;;;N;;;;24E7; +24CE;CIRCLED LATIN CAPITAL LETTER Y;So;0;L; 0059;;;;N;;;;24E8; +24CF;CIRCLED LATIN CAPITAL LETTER Z;So;0;L; 005A;;;;N;;;;24E9; +24D0;CIRCLED LATIN SMALL LETTER A;So;0;L; 0061;;;;N;;;24B6;;24B6 +24D1;CIRCLED LATIN SMALL LETTER B;So;0;L; 0062;;;;N;;;24B7;;24B7 +24D2;CIRCLED LATIN SMALL LETTER C;So;0;L; 0063;;;;N;;;24B8;;24B8 +24D3;CIRCLED LATIN SMALL LETTER D;So;0;L; 0064;;;;N;;;24B9;;24B9 +24D4;CIRCLED LATIN SMALL LETTER E;So;0;L; 0065;;;;N;;;24BA;;24BA +24D5;CIRCLED LATIN SMALL LETTER F;So;0;L; 0066;;;;N;;;24BB;;24BB +24D6;CIRCLED LATIN SMALL LETTER G;So;0;L; 0067;;;;N;;;24BC;;24BC +24D7;CIRCLED LATIN SMALL LETTER H;So;0;L; 0068;;;;N;;;24BD;;24BD +24D8;CIRCLED LATIN SMALL LETTER I;So;0;L; 0069;;;;N;;;24BE;;24BE +24D9;CIRCLED LATIN SMALL LETTER J;So;0;L; 006A;;;;N;;;24BF;;24BF +24DA;CIRCLED LATIN SMALL LETTER K;So;0;L; 006B;;;;N;;;24C0;;24C0 +24DB;CIRCLED LATIN SMALL LETTER L;So;0;L; 006C;;;;N;;;24C1;;24C1 +24DC;CIRCLED LATIN SMALL LETTER M;So;0;L; 006D;;;;N;;;24C2;;24C2 +24DD;CIRCLED LATIN SMALL LETTER N;So;0;L; 006E;;;;N;;;24C3;;24C3 +24DE;CIRCLED LATIN SMALL LETTER O;So;0;L; 006F;;;;N;;;24C4;;24C4 +24DF;CIRCLED LATIN SMALL LETTER P;So;0;L; 0070;;;;N;;;24C5;;24C5 +24E0;CIRCLED LATIN SMALL LETTER Q;So;0;L; 0071;;;;N;;;24C6;;24C6 +24E1;CIRCLED LATIN SMALL LETTER R;So;0;L; 0072;;;;N;;;24C7;;24C7 +24E2;CIRCLED LATIN SMALL LETTER S;So;0;L; 0073;;;;N;;;24C8;;24C8 +24E3;CIRCLED LATIN SMALL LETTER T;So;0;L; 0074;;;;N;;;24C9;;24C9 +24E4;CIRCLED LATIN SMALL LETTER U;So;0;L; 0075;;;;N;;;24CA;;24CA +24E5;CIRCLED LATIN SMALL LETTER V;So;0;L; 0076;;;;N;;;24CB;;24CB +24E6;CIRCLED LATIN SMALL LETTER W;So;0;L; 0077;;;;N;;;24CC;;24CC +24E7;CIRCLED LATIN SMALL LETTER X;So;0;L; 0078;;;;N;;;24CD;;24CD +24E8;CIRCLED LATIN SMALL LETTER Y;So;0;L; 0079;;;;N;;;24CE;;24CE +24E9;CIRCLED LATIN SMALL LETTER Z;So;0;L; 007A;;;;N;;;24CF;;24CF +24EA;CIRCLED DIGIT ZERO;No;0;EN; 0030;;0;0;N;;;;; +24EB;NEGATIVE CIRCLED NUMBER ELEVEN;No;0;ON;;;;11;N;;;;; +24EC;NEGATIVE CIRCLED NUMBER TWELVE;No;0;ON;;;;12;N;;;;; +24ED;NEGATIVE CIRCLED NUMBER THIRTEEN;No;0;ON;;;;13;N;;;;; +24EE;NEGATIVE CIRCLED NUMBER FOURTEEN;No;0;ON;;;;14;N;;;;; +24EF;NEGATIVE CIRCLED NUMBER FIFTEEN;No;0;ON;;;;15;N;;;;; +24F0;NEGATIVE CIRCLED NUMBER SIXTEEN;No;0;ON;;;;16;N;;;;; +24F1;NEGATIVE CIRCLED NUMBER SEVENTEEN;No;0;ON;;;;17;N;;;;; +24F2;NEGATIVE CIRCLED NUMBER EIGHTEEN;No;0;ON;;;;18;N;;;;; +24F3;NEGATIVE CIRCLED NUMBER NINETEEN;No;0;ON;;;;19;N;;;;; +24F4;NEGATIVE CIRCLED NUMBER TWENTY;No;0;ON;;;;20;N;;;;; +24F5;DOUBLE CIRCLED DIGIT ONE;No;0;ON;;;1;1;N;;;;; +24F6;DOUBLE CIRCLED DIGIT TWO;No;0;ON;;;2;2;N;;;;; +24F7;DOUBLE CIRCLED DIGIT THREE;No;0;ON;;;3;3;N;;;;; +24F8;DOUBLE CIRCLED DIGIT FOUR;No;0;ON;;;4;4;N;;;;; +24F9;DOUBLE CIRCLED DIGIT FIVE;No;0;ON;;;5;5;N;;;;; +24FA;DOUBLE CIRCLED DIGIT SIX;No;0;ON;;;6;6;N;;;;; +24FB;DOUBLE CIRCLED DIGIT SEVEN;No;0;ON;;;7;7;N;;;;; +24FC;DOUBLE CIRCLED DIGIT EIGHT;No;0;ON;;;8;8;N;;;;; +24FD;DOUBLE CIRCLED DIGIT NINE;No;0;ON;;;9;9;N;;;;; +24FE;DOUBLE CIRCLED NUMBER TEN;No;0;ON;;;;10;N;;;;; +2500;BOX DRAWINGS LIGHT HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT HORIZONTAL;;;; +2501;BOX DRAWINGS HEAVY HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY HORIZONTAL;;;; +2502;BOX DRAWINGS LIGHT VERTICAL;So;0;ON;;;;;N;FORMS LIGHT VERTICAL;;;; +2503;BOX DRAWINGS HEAVY VERTICAL;So;0;ON;;;;;N;FORMS HEAVY VERTICAL;;;; +2504;BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT TRIPLE DASH HORIZONTAL;;;; +2505;BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY TRIPLE DASH HORIZONTAL;;;; +2506;BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT TRIPLE DASH VERTICAL;;;; +2507;BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY TRIPLE DASH VERTICAL;;;; +2508;BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT QUADRUPLE DASH HORIZONTAL;;;; +2509;BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY QUADRUPLE DASH HORIZONTAL;;;; +250A;BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT QUADRUPLE DASH VERTICAL;;;; +250B;BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY QUADRUPLE DASH VERTICAL;;;; +250C;BOX DRAWINGS LIGHT DOWN AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT DOWN AND RIGHT;;;; +250D;BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND RIGHT HEAVY;;;; +250E;BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND RIGHT LIGHT;;;; +250F;BOX DRAWINGS HEAVY DOWN AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY DOWN AND RIGHT;;;; +2510;BOX DRAWINGS LIGHT DOWN AND LEFT;So;0;ON;;;;;N;FORMS LIGHT DOWN AND LEFT;;;; +2511;BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND LEFT HEAVY;;;; +2512;BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND LEFT LIGHT;;;; +2513;BOX DRAWINGS HEAVY DOWN AND LEFT;So;0;ON;;;;;N;FORMS HEAVY DOWN AND LEFT;;;; +2514;BOX DRAWINGS LIGHT UP AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT UP AND RIGHT;;;; +2515;BOX DRAWINGS UP LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND RIGHT HEAVY;;;; +2516;BOX DRAWINGS UP HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND RIGHT LIGHT;;;; +2517;BOX DRAWINGS HEAVY UP AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY UP AND RIGHT;;;; +2518;BOX DRAWINGS LIGHT UP AND LEFT;So;0;ON;;;;;N;FORMS LIGHT UP AND LEFT;;;; +2519;BOX DRAWINGS UP LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND LEFT HEAVY;;;; +251A;BOX DRAWINGS UP HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND LEFT LIGHT;;;; +251B;BOX DRAWINGS HEAVY UP AND LEFT;So;0;ON;;;;;N;FORMS HEAVY UP AND LEFT;;;; +251C;BOX DRAWINGS LIGHT VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND RIGHT;;;; +251D;BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND RIGHT HEAVY;;;; +251E;BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND RIGHT DOWN LIGHT;;;; +251F;BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND RIGHT UP LIGHT;;;; +2520;BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND RIGHT LIGHT;;;; +2521;BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND RIGHT UP HEAVY;;;; +2522;BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND RIGHT DOWN HEAVY;;;; +2523;BOX DRAWINGS HEAVY VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND RIGHT;;;; +2524;BOX DRAWINGS LIGHT VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND LEFT;;;; +2525;BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND LEFT HEAVY;;;; +2526;BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND LEFT DOWN LIGHT;;;; +2527;BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND LEFT UP LIGHT;;;; +2528;BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND LEFT LIGHT;;;; +2529;BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND LEFT UP HEAVY;;;; +252A;BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND LEFT DOWN HEAVY;;;; +252B;BOX DRAWINGS HEAVY VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND LEFT;;;; +252C;BOX DRAWINGS LIGHT DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT DOWN AND HORIZONTAL;;;; +252D;BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT DOWN LIGHT;;;; +252E;BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT DOWN LIGHT;;;; +252F;BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND HORIZONTAL HEAVY;;;; +2530;BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND HORIZONTAL LIGHT;;;; +2531;BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT DOWN HEAVY;;;; +2532;BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT DOWN HEAVY;;;; +2533;BOX DRAWINGS HEAVY DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY DOWN AND HORIZONTAL;;;; +2534;BOX DRAWINGS LIGHT UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT UP AND HORIZONTAL;;;; +2535;BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT UP LIGHT;;;; +2536;BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT UP LIGHT;;;; +2537;BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND HORIZONTAL HEAVY;;;; +2538;BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND HORIZONTAL LIGHT;;;; +2539;BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT UP HEAVY;;;; +253A;BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT UP HEAVY;;;; +253B;BOX DRAWINGS HEAVY UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY UP AND HORIZONTAL;;;; +253C;BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND HORIZONTAL;;;; +253D;BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT VERTICAL LIGHT;;;; +253E;BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT VERTICAL LIGHT;;;; +253F;BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND HORIZONTAL HEAVY;;;; +2540;BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND DOWN HORIZONTAL LIGHT;;;; +2541;BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND UP HORIZONTAL LIGHT;;;; +2542;BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND HORIZONTAL LIGHT;;;; +2543;BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS LEFT UP HEAVY AND RIGHT DOWN LIGHT;;;; +2544;BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS RIGHT UP HEAVY AND LEFT DOWN LIGHT;;;; +2545;BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS LEFT DOWN HEAVY AND RIGHT UP LIGHT;;;; +2546;BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS RIGHT DOWN HEAVY AND LEFT UP LIGHT;;;; +2547;BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND UP HORIZONTAL HEAVY;;;; +2548;BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND DOWN HORIZONTAL HEAVY;;;; +2549;BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT VERTICAL HEAVY;;;; +254A;BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT VERTICAL HEAVY;;;; +254B;BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND HORIZONTAL;;;; +254C;BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT DOUBLE DASH HORIZONTAL;;;; +254D;BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY DOUBLE DASH HORIZONTAL;;;; +254E;BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT DOUBLE DASH VERTICAL;;;; +254F;BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY DOUBLE DASH VERTICAL;;;; +2550;BOX DRAWINGS DOUBLE HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE HORIZONTAL;;;; +2551;BOX DRAWINGS DOUBLE VERTICAL;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL;;;; +2552;BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND RIGHT DOUBLE;;;; +2553;BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND RIGHT SINGLE;;;; +2554;BOX DRAWINGS DOUBLE DOWN AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND RIGHT;;;; +2555;BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND LEFT DOUBLE;;;; +2556;BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND LEFT SINGLE;;;; +2557;BOX DRAWINGS DOUBLE DOWN AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND LEFT;;;; +2558;BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND RIGHT DOUBLE;;;; +2559;BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND RIGHT SINGLE;;;; +255A;BOX DRAWINGS DOUBLE UP AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE UP AND RIGHT;;;; +255B;BOX DRAWINGS UP SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND LEFT DOUBLE;;;; +255C;BOX DRAWINGS UP DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND LEFT SINGLE;;;; +255D;BOX DRAWINGS DOUBLE UP AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE UP AND LEFT;;;; +255E;BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND RIGHT DOUBLE;;;; +255F;BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND RIGHT SINGLE;;;; +2560;BOX DRAWINGS DOUBLE VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND RIGHT;;;; +2561;BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND LEFT DOUBLE;;;; +2562;BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND LEFT SINGLE;;;; +2563;BOX DRAWINGS DOUBLE VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND LEFT;;;; +2564;BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND HORIZONTAL DOUBLE;;;; +2565;BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND HORIZONTAL SINGLE;;;; +2566;BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND HORIZONTAL;;;; +2567;BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND HORIZONTAL DOUBLE;;;; +2568;BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND HORIZONTAL SINGLE;;;; +2569;BOX DRAWINGS DOUBLE UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE UP AND HORIZONTAL;;;; +256A;BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND HORIZONTAL DOUBLE;;;; +256B;BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND HORIZONTAL SINGLE;;;; +256C;BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND HORIZONTAL;;;; +256D;BOX DRAWINGS LIGHT ARC DOWN AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT ARC DOWN AND RIGHT;;;; +256E;BOX DRAWINGS LIGHT ARC DOWN AND LEFT;So;0;ON;;;;;N;FORMS LIGHT ARC DOWN AND LEFT;;;; +256F;BOX DRAWINGS LIGHT ARC UP AND LEFT;So;0;ON;;;;;N;FORMS LIGHT ARC UP AND LEFT;;;; +2570;BOX DRAWINGS LIGHT ARC UP AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT ARC UP AND RIGHT;;;; +2571;BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT;;;; +2572;BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT;;;; +2573;BOX DRAWINGS LIGHT DIAGONAL CROSS;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL CROSS;;;; +2574;BOX DRAWINGS LIGHT LEFT;So;0;ON;;;;;N;FORMS LIGHT LEFT;;;; +2575;BOX DRAWINGS LIGHT UP;So;0;ON;;;;;N;FORMS LIGHT UP;;;; +2576;BOX DRAWINGS LIGHT RIGHT;So;0;ON;;;;;N;FORMS LIGHT RIGHT;;;; +2577;BOX DRAWINGS LIGHT DOWN;So;0;ON;;;;;N;FORMS LIGHT DOWN;;;; +2578;BOX DRAWINGS HEAVY LEFT;So;0;ON;;;;;N;FORMS HEAVY LEFT;;;; +2579;BOX DRAWINGS HEAVY UP;So;0;ON;;;;;N;FORMS HEAVY UP;;;; +257A;BOX DRAWINGS HEAVY RIGHT;So;0;ON;;;;;N;FORMS HEAVY RIGHT;;;; +257B;BOX DRAWINGS HEAVY DOWN;So;0;ON;;;;;N;FORMS HEAVY DOWN;;;; +257C;BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT;So;0;ON;;;;;N;FORMS LIGHT LEFT AND HEAVY RIGHT;;;; +257D;BOX DRAWINGS LIGHT UP AND HEAVY DOWN;So;0;ON;;;;;N;FORMS LIGHT UP AND HEAVY DOWN;;;; +257E;BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT;So;0;ON;;;;;N;FORMS HEAVY LEFT AND LIGHT RIGHT;;;; +257F;BOX DRAWINGS HEAVY UP AND LIGHT DOWN;So;0;ON;;;;;N;FORMS HEAVY UP AND LIGHT DOWN;;;; +2580;UPPER HALF BLOCK;So;0;ON;;;;;N;;;;; +2581;LOWER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +2582;LOWER ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +2583;LOWER THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +2584;LOWER HALF BLOCK;So;0;ON;;;;;N;;;;; +2585;LOWER FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +2586;LOWER THREE QUARTERS BLOCK;So;0;ON;;;;;N;LOWER THREE QUARTER BLOCK;;;; +2587;LOWER SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +2588;FULL BLOCK;So;0;ON;;;;;N;;;;; +2589;LEFT SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +258A;LEFT THREE QUARTERS BLOCK;So;0;ON;;;;;N;LEFT THREE QUARTER BLOCK;;;; +258B;LEFT FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +258C;LEFT HALF BLOCK;So;0;ON;;;;;N;;;;; +258D;LEFT THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +258E;LEFT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +258F;LEFT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +2590;RIGHT HALF BLOCK;So;0;ON;;;;;N;;;;; +2591;LIGHT SHADE;So;0;ON;;;;;N;;;;; +2592;MEDIUM SHADE;So;0;ON;;;;;N;;;;; +2593;DARK SHADE;So;0;ON;;;;;N;;;;; +2594;UPPER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +2595;RIGHT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +2596;QUADRANT LOWER LEFT;So;0;ON;;;;;N;;;;; +2597;QUADRANT LOWER RIGHT;So;0;ON;;;;;N;;;;; +2598;QUADRANT UPPER LEFT;So;0;ON;;;;;N;;;;; +2599;QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;; +259A;QUADRANT UPPER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;; +259B;QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT;So;0;ON;;;;;N;;;;; +259C;QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT;So;0;ON;;;;;N;;;;; +259D;QUADRANT UPPER RIGHT;So;0;ON;;;;;N;;;;; +259E;QUADRANT UPPER RIGHT AND LOWER LEFT;So;0;ON;;;;;N;;;;; +259F;QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;; +25A0;BLACK SQUARE;So;0;ON;;;;;N;;;;; +25A1;WHITE SQUARE;So;0;ON;;;;;N;;;;; +25A2;WHITE SQUARE WITH ROUNDED CORNERS;So;0;ON;;;;;N;;;;; +25A3;WHITE SQUARE CONTAINING BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;; +25A4;SQUARE WITH HORIZONTAL FILL;So;0;ON;;;;;N;;;;; +25A5;SQUARE WITH VERTICAL FILL;So;0;ON;;;;;N;;;;; +25A6;SQUARE WITH ORTHOGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;; +25A7;SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL;So;0;ON;;;;;N;;;;; +25A8;SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL;So;0;ON;;;;;N;;;;; +25A9;SQUARE WITH DIAGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;; +25AA;BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;; +25AB;WHITE SMALL SQUARE;So;0;ON;;;;;N;;;;; +25AC;BLACK RECTANGLE;So;0;ON;;;;;N;;;;; +25AD;WHITE RECTANGLE;So;0;ON;;;;;N;;;;; +25AE;BLACK VERTICAL RECTANGLE;So;0;ON;;;;;N;;;;; +25AF;WHITE VERTICAL RECTANGLE;So;0;ON;;;;;N;;;;; +25B0;BLACK PARALLELOGRAM;So;0;ON;;;;;N;;;;; +25B1;WHITE PARALLELOGRAM;So;0;ON;;;;;N;;;;; +25B2;BLACK UP-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK UP POINTING TRIANGLE;;;; +25B3;WHITE UP-POINTING TRIANGLE;So;0;ON;;;;;N;WHITE UP POINTING TRIANGLE;;;; +25B4;BLACK UP-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK UP POINTING SMALL TRIANGLE;;;; +25B5;WHITE UP-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE UP POINTING SMALL TRIANGLE;;;; +25B6;BLACK RIGHT-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK RIGHT POINTING TRIANGLE;;;; +25B7;WHITE RIGHT-POINTING TRIANGLE;Sm;0;ON;;;;;N;WHITE RIGHT POINTING TRIANGLE;;;; +25B8;BLACK RIGHT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK RIGHT POINTING SMALL TRIANGLE;;;; +25B9;WHITE RIGHT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE RIGHT POINTING SMALL TRIANGLE;;;; +25BA;BLACK RIGHT-POINTING POINTER;So;0;ON;;;;;N;BLACK RIGHT POINTING POINTER;;;; +25BB;WHITE RIGHT-POINTING POINTER;So;0;ON;;;;;N;WHITE RIGHT POINTING POINTER;;;; +25BC;BLACK DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK DOWN POINTING TRIANGLE;;;; +25BD;WHITE DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;WHITE DOWN POINTING TRIANGLE;;;; +25BE;BLACK DOWN-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK DOWN POINTING SMALL TRIANGLE;;;; +25BF;WHITE DOWN-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE DOWN POINTING SMALL TRIANGLE;;;; +25C0;BLACK LEFT-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK LEFT POINTING TRIANGLE;;;; +25C1;WHITE LEFT-POINTING TRIANGLE;Sm;0;ON;;;;;N;WHITE LEFT POINTING TRIANGLE;;;; +25C2;BLACK LEFT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK LEFT POINTING SMALL TRIANGLE;;;; +25C3;WHITE LEFT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE LEFT POINTING SMALL TRIANGLE;;;; +25C4;BLACK LEFT-POINTING POINTER;So;0;ON;;;;;N;BLACK LEFT POINTING POINTER;;;; +25C5;WHITE LEFT-POINTING POINTER;So;0;ON;;;;;N;WHITE LEFT POINTING POINTER;;;; +25C6;BLACK DIAMOND;So;0;ON;;;;;N;;;;; +25C7;WHITE DIAMOND;So;0;ON;;;;;N;;;;; +25C8;WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND;So;0;ON;;;;;N;;;;; +25C9;FISHEYE;So;0;ON;;;;;N;;;;; +25CA;LOZENGE;So;0;ON;;;;;N;;;;; +25CB;WHITE CIRCLE;So;0;ON;;;;;N;;;;; +25CC;DOTTED CIRCLE;So;0;ON;;;;;N;;;;; +25CD;CIRCLE WITH VERTICAL FILL;So;0;ON;;;;;N;;;;; +25CE;BULLSEYE;So;0;ON;;;;;N;;;;; +25CF;BLACK CIRCLE;So;0;ON;;;;;N;;;;; +25D0;CIRCLE WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;; +25D1;CIRCLE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;; +25D2;CIRCLE WITH LOWER HALF BLACK;So;0;ON;;;;;N;;;;; +25D3;CIRCLE WITH UPPER HALF BLACK;So;0;ON;;;;;N;;;;; +25D4;CIRCLE WITH UPPER RIGHT QUADRANT BLACK;So;0;ON;;;;;N;;;;; +25D5;CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK;So;0;ON;;;;;N;;;;; +25D6;LEFT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;; +25D7;RIGHT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;; +25D8;INVERSE BULLET;So;0;ON;;;;;N;;;;; +25D9;INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;; +25DA;UPPER HALF INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;; +25DB;LOWER HALF INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;; +25DC;UPPER LEFT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;; +25DD;UPPER RIGHT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;; +25DE;LOWER RIGHT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;; +25DF;LOWER LEFT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;; +25E0;UPPER HALF CIRCLE;So;0;ON;;;;;N;;;;; +25E1;LOWER HALF CIRCLE;So;0;ON;;;;;N;;;;; +25E2;BLACK LOWER RIGHT TRIANGLE;So;0;ON;;;;;N;;;;; +25E3;BLACK LOWER LEFT TRIANGLE;So;0;ON;;;;;N;;;;; +25E4;BLACK UPPER LEFT TRIANGLE;So;0;ON;;;;;N;;;;; +25E5;BLACK UPPER RIGHT TRIANGLE;So;0;ON;;;;;N;;;;; +25E6;WHITE BULLET;So;0;ON;;;;;N;;;;; +25E7;SQUARE WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;; +25E8;SQUARE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;; +25E9;SQUARE WITH UPPER LEFT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;; +25EA;SQUARE WITH LOWER RIGHT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;; +25EB;WHITE SQUARE WITH VERTICAL BISECTING LINE;So;0;ON;;;;;N;;;;; +25EC;WHITE UP-POINTING TRIANGLE WITH DOT;So;0;ON;;;;;N;WHITE UP POINTING TRIANGLE WITH DOT;;;; +25ED;UP-POINTING TRIANGLE WITH LEFT HALF BLACK;So;0;ON;;;;;N;UP POINTING TRIANGLE WITH LEFT HALF BLACK;;;; +25EE;UP-POINTING TRIANGLE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;UP POINTING TRIANGLE WITH RIGHT HALF BLACK;;;; +25EF;LARGE CIRCLE;So;0;ON;;;;;N;;;;; +25F0;WHITE SQUARE WITH UPPER LEFT QUADRANT;So;0;ON;;;;;N;;;;; +25F1;WHITE SQUARE WITH LOWER LEFT QUADRANT;So;0;ON;;;;;N;;;;; +25F2;WHITE SQUARE WITH LOWER RIGHT QUADRANT;So;0;ON;;;;;N;;;;; +25F3;WHITE SQUARE WITH UPPER RIGHT QUADRANT;So;0;ON;;;;;N;;;;; +25F4;WHITE CIRCLE WITH UPPER LEFT QUADRANT;So;0;ON;;;;;N;;;;; +25F5;WHITE CIRCLE WITH LOWER LEFT QUADRANT;So;0;ON;;;;;N;;;;; +25F6;WHITE CIRCLE WITH LOWER RIGHT QUADRANT;So;0;ON;;;;;N;;;;; +25F7;WHITE CIRCLE WITH UPPER RIGHT QUADRANT;So;0;ON;;;;;N;;;;; +25F8;UPPER LEFT TRIANGLE;Sm;0;ON;;;;;N;;;;; +25F9;UPPER RIGHT TRIANGLE;Sm;0;ON;;;;;N;;;;; +25FA;LOWER LEFT TRIANGLE;Sm;0;ON;;;;;N;;;;; +25FB;WHITE MEDIUM SQUARE;Sm;0;ON;;;;;N;;;;; +25FC;BLACK MEDIUM SQUARE;Sm;0;ON;;;;;N;;;;; +25FD;WHITE MEDIUM SMALL SQUARE;Sm;0;ON;;;;;N;;;;; +25FE;BLACK MEDIUM SMALL SQUARE;Sm;0;ON;;;;;N;;;;; +25FF;LOWER RIGHT TRIANGLE;Sm;0;ON;;;;;N;;;;; +2600;BLACK SUN WITH RAYS;So;0;ON;;;;;N;;;;; +2601;CLOUD;So;0;ON;;;;;N;;;;; +2602;UMBRELLA;So;0;ON;;;;;N;;;;; +2603;SNOWMAN;So;0;ON;;;;;N;;;;; +2604;COMET;So;0;ON;;;;;N;;;;; +2605;BLACK STAR;So;0;ON;;;;;N;;;;; +2606;WHITE STAR;So;0;ON;;;;;N;;;;; +2607;LIGHTNING;So;0;ON;;;;;N;;;;; +2608;THUNDERSTORM;So;0;ON;;;;;N;;;;; +2609;SUN;So;0;ON;;;;;N;;;;; +260A;ASCENDING NODE;So;0;ON;;;;;N;;;;; +260B;DESCENDING NODE;So;0;ON;;;;;N;;;;; +260C;CONJUNCTION;So;0;ON;;;;;N;;;;; +260D;OPPOSITION;So;0;ON;;;;;N;;;;; +260E;BLACK TELEPHONE;So;0;ON;;;;;N;;;;; +260F;WHITE TELEPHONE;So;0;ON;;;;;N;;;;; +2610;BALLOT BOX;So;0;ON;;;;;N;;;;; +2611;BALLOT BOX WITH CHECK;So;0;ON;;;;;N;;;;; +2612;BALLOT BOX WITH X;So;0;ON;;;;;N;;;;; +2613;SALTIRE;So;0;ON;;;;;N;;;;; +2616;WHITE SHOGI PIECE;So;0;ON;;;;;N;;;;; +2617;BLACK SHOGI PIECE;So;0;ON;;;;;N;;;;; +2619;REVERSED ROTATED FLORAL HEART BULLET;So;0;ON;;;;;N;;;;; +261A;BLACK LEFT POINTING INDEX;So;0;ON;;;;;N;;;;; +261B;BLACK RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;; +261C;WHITE LEFT POINTING INDEX;So;0;ON;;;;;N;;;;; +261D;WHITE UP POINTING INDEX;So;0;ON;;;;;N;;;;; +261E;WHITE RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;; +261F;WHITE DOWN POINTING INDEX;So;0;ON;;;;;N;;;;; +2620;SKULL AND CROSSBONES;So;0;ON;;;;;N;;;;; +2621;CAUTION SIGN;So;0;ON;;;;;N;;;;; +2622;RADIOACTIVE SIGN;So;0;ON;;;;;N;;;;; +2623;BIOHAZARD SIGN;So;0;ON;;;;;N;;;;; +2624;CADUCEUS;So;0;ON;;;;;N;;;;; +2625;ANKH;So;0;ON;;;;;N;;;;; +2626;ORTHODOX CROSS;So;0;ON;;;;;N;;;;; +2627;CHI RHO;So;0;ON;;;;;N;;;;; +2628;CROSS OF LORRAINE;So;0;ON;;;;;N;;;;; +2629;CROSS OF JERUSALEM;So;0;ON;;;;;N;;;;; +262A;STAR AND CRESCENT;So;0;ON;;;;;N;;;;; +262B;FARSI SYMBOL;So;0;ON;;;;;N;SYMBOL OF IRAN;;;; +262C;ADI SHAKTI;So;0;ON;;;;;N;;;;; +262D;HAMMER AND SICKLE;So;0;ON;;;;;N;;;;; +262E;PEACE SYMBOL;So;0;ON;;;;;N;;;;; +262F;YIN YANG;So;0;ON;;;;;N;;;;; +2630;TRIGRAM FOR HEAVEN;So;0;ON;;;;;N;;;;; +2631;TRIGRAM FOR LAKE;So;0;ON;;;;;N;;;;; +2632;TRIGRAM FOR FIRE;So;0;ON;;;;;N;;;;; +2633;TRIGRAM FOR THUNDER;So;0;ON;;;;;N;;;;; +2634;TRIGRAM FOR WIND;So;0;ON;;;;;N;;;;; +2635;TRIGRAM FOR WATER;So;0;ON;;;;;N;;;;; +2636;TRIGRAM FOR MOUNTAIN;So;0;ON;;;;;N;;;;; +2637;TRIGRAM FOR EARTH;So;0;ON;;;;;N;;;;; +2638;WHEEL OF DHARMA;So;0;ON;;;;;N;;;;; +2639;WHITE FROWNING FACE;So;0;ON;;;;;N;;;;; +263A;WHITE SMILING FACE;So;0;ON;;;;;N;;;;; +263B;BLACK SMILING FACE;So;0;ON;;;;;N;;;;; +263C;WHITE SUN WITH RAYS;So;0;ON;;;;;N;;;;; +263D;FIRST QUARTER MOON;So;0;ON;;;;;N;;;;; +263E;LAST QUARTER MOON;So;0;ON;;;;;N;;;;; +263F;MERCURY;So;0;ON;;;;;N;;;;; +2640;FEMALE SIGN;So;0;ON;;;;;N;;;;; +2641;EARTH;So;0;ON;;;;;N;;;;; +2642;MALE SIGN;So;0;ON;;;;;N;;;;; +2643;JUPITER;So;0;ON;;;;;N;;;;; +2644;SATURN;So;0;ON;;;;;N;;;;; +2645;URANUS;So;0;ON;;;;;N;;;;; +2646;NEPTUNE;So;0;ON;;;;;N;;;;; +2647;PLUTO;So;0;ON;;;;;N;;;;; +2648;ARIES;So;0;ON;;;;;N;;;;; +2649;TAURUS;So;0;ON;;;;;N;;;;; +264A;GEMINI;So;0;ON;;;;;N;;;;; +264B;CANCER;So;0;ON;;;;;N;;;;; +264C;LEO;So;0;ON;;;;;N;;;;; +264D;VIRGO;So;0;ON;;;;;N;;;;; +264E;LIBRA;So;0;ON;;;;;N;;;;; +264F;SCORPIUS;So;0;ON;;;;;N;;;;; +2650;SAGITTARIUS;So;0;ON;;;;;N;;;;; +2651;CAPRICORN;So;0;ON;;;;;N;;;;; +2652;AQUARIUS;So;0;ON;;;;;N;;;;; +2653;PISCES;So;0;ON;;;;;N;;;;; +2654;WHITE CHESS KING;So;0;ON;;;;;N;;;;; +2655;WHITE CHESS QUEEN;So;0;ON;;;;;N;;;;; +2656;WHITE CHESS ROOK;So;0;ON;;;;;N;;;;; +2657;WHITE CHESS BISHOP;So;0;ON;;;;;N;;;;; +2658;WHITE CHESS KNIGHT;So;0;ON;;;;;N;;;;; +2659;WHITE CHESS PAWN;So;0;ON;;;;;N;;;;; +265A;BLACK CHESS KING;So;0;ON;;;;;N;;;;; +265B;BLACK CHESS QUEEN;So;0;ON;;;;;N;;;;; +265C;BLACK CHESS ROOK;So;0;ON;;;;;N;;;;; +265D;BLACK CHESS BISHOP;So;0;ON;;;;;N;;;;; +265E;BLACK CHESS KNIGHT;So;0;ON;;;;;N;;;;; +265F;BLACK CHESS PAWN;So;0;ON;;;;;N;;;;; +2660;BLACK SPADE SUIT;So;0;ON;;;;;N;;;;; +2661;WHITE HEART SUIT;So;0;ON;;;;;N;;;;; +2662;WHITE DIAMOND SUIT;So;0;ON;;;;;N;;;;; +2663;BLACK CLUB SUIT;So;0;ON;;;;;N;;;;; +2664;WHITE SPADE SUIT;So;0;ON;;;;;N;;;;; +2665;BLACK HEART SUIT;So;0;ON;;;;;N;;;;; +2666;BLACK DIAMOND SUIT;So;0;ON;;;;;N;;;;; +2667;WHITE CLUB SUIT;So;0;ON;;;;;N;;;;; +2668;HOT SPRINGS;So;0;ON;;;;;N;;;;; +2669;QUARTER NOTE;So;0;ON;;;;;N;;;;; +266A;EIGHTH NOTE;So;0;ON;;;;;N;;;;; +266B;BEAMED EIGHTH NOTES;So;0;ON;;;;;N;BARRED EIGHTH NOTES;;;; +266C;BEAMED SIXTEENTH NOTES;So;0;ON;;;;;N;BARRED SIXTEENTH NOTES;;;; +266D;MUSIC FLAT SIGN;So;0;ON;;;;;N;FLAT;;;; +266E;MUSIC NATURAL SIGN;So;0;ON;;;;;N;NATURAL;;;; +266F;MUSIC SHARP SIGN;Sm;0;ON;;;;;N;SHARP;;;; +2670;WEST SYRIAC CROSS;So;0;ON;;;;;N;;;;; +2671;EAST SYRIAC CROSS;So;0;ON;;;;;N;;;;; +2672;UNIVERSAL RECYCLING SYMBOL;So;0;ON;;;;;N;;;;; +2673;RECYCLING SYMBOL FOR TYPE-1 PLASTICS;So;0;ON;;;;;N;;pete;;; +2674;RECYCLING SYMBOL FOR TYPE-2 PLASTICS;So;0;ON;;;;;N;;hdpe;;; +2675;RECYCLING SYMBOL FOR TYPE-3 PLASTICS;So;0;ON;;;;;N;;pvc;;; +2676;RECYCLING SYMBOL FOR TYPE-4 PLASTICS;So;0;ON;;;;;N;;ldpe;;; +2677;RECYCLING SYMBOL FOR TYPE-5 PLASTICS;So;0;ON;;;;;N;;pp;;; +2678;RECYCLING SYMBOL FOR TYPE-6 PLASTICS;So;0;ON;;;;;N;;ps;;; +2679;RECYCLING SYMBOL FOR TYPE-7 PLASTICS;So;0;ON;;;;;N;;other;;; +267A;RECYCLING SYMBOL FOR GENERIC MATERIALS;So;0;ON;;;;;N;;;;; +267B;BLACK UNIVERSAL RECYCLING SYMBOL;So;0;ON;;;;;N;;;;; +267C;RECYCLED PAPER SYMBOL;So;0;ON;;;;;N;;;;; +267D;PARTIALLY-RECYCLED PAPER SYMBOL;So;0;ON;;;;;N;;;;; +2680;DIE FACE-1;So;0;ON;;;;;N;;;;; +2681;DIE FACE-2;So;0;ON;;;;;N;;;;; +2682;DIE FACE-3;So;0;ON;;;;;N;;;;; +2683;DIE FACE-4;So;0;ON;;;;;N;;;;; +2684;DIE FACE-5;So;0;ON;;;;;N;;;;; +2685;DIE FACE-6;So;0;ON;;;;;N;;;;; +2686;WHITE CIRCLE WITH DOT RIGHT;So;0;ON;;;;;N;;;;; +2687;WHITE CIRCLE WITH TWO DOTS;So;0;ON;;;;;N;;;;; +2688;BLACK CIRCLE WITH WHITE DOT RIGHT;So;0;ON;;;;;N;;;;; +2689;BLACK CIRCLE WITH TWO WHITE DOTS;So;0;ON;;;;;N;;;;; +2701;UPPER BLADE SCISSORS;So;0;ON;;;;;N;;;;; +2702;BLACK SCISSORS;So;0;ON;;;;;N;;;;; +2703;LOWER BLADE SCISSORS;So;0;ON;;;;;N;;;;; +2704;WHITE SCISSORS;So;0;ON;;;;;N;;;;; +2706;TELEPHONE LOCATION SIGN;So;0;ON;;;;;N;;;;; +2707;TAPE DRIVE;So;0;ON;;;;;N;;;;; +2708;AIRPLANE;So;0;ON;;;;;N;;;;; +2709;ENVELOPE;So;0;ON;;;;;N;;;;; +270C;VICTORY HAND;So;0;ON;;;;;N;;;;; +270D;WRITING HAND;So;0;ON;;;;;N;;;;; +270E;LOWER RIGHT PENCIL;So;0;ON;;;;;N;;;;; +270F;PENCIL;So;0;ON;;;;;N;;;;; +2710;UPPER RIGHT PENCIL;So;0;ON;;;;;N;;;;; +2711;WHITE NIB;So;0;ON;;;;;N;;;;; +2712;BLACK NIB;So;0;ON;;;;;N;;;;; +2713;CHECK MARK;So;0;ON;;;;;N;;;;; +2714;HEAVY CHECK MARK;So;0;ON;;;;;N;;;;; +2715;MULTIPLICATION X;So;0;ON;;;;;N;;;;; +2716;HEAVY MULTIPLICATION X;So;0;ON;;;;;N;;;;; +2717;BALLOT X;So;0;ON;;;;;N;;;;; +2718;HEAVY BALLOT X;So;0;ON;;;;;N;;;;; +2719;OUTLINED GREEK CROSS;So;0;ON;;;;;N;;;;; +271A;HEAVY GREEK CROSS;So;0;ON;;;;;N;;;;; +271B;OPEN CENTRE CROSS;So;0;ON;;;;;N;OPEN CENTER CROSS;;;; +271C;HEAVY OPEN CENTRE CROSS;So;0;ON;;;;;N;HEAVY OPEN CENTER CROSS;;;; +271D;LATIN CROSS;So;0;ON;;;;;N;;;;; +271E;SHADOWED WHITE LATIN CROSS;So;0;ON;;;;;N;;;;; +271F;OUTLINED LATIN CROSS;So;0;ON;;;;;N;;;;; +2720;MALTESE CROSS;So;0;ON;;;;;N;;;;; +2721;STAR OF DAVID;So;0;ON;;;;;N;;;;; +2722;FOUR TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +2723;FOUR BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +2724;HEAVY FOUR BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +2725;FOUR CLUB-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +2726;BLACK FOUR POINTED STAR;So;0;ON;;;;;N;;;;; +2727;WHITE FOUR POINTED STAR;So;0;ON;;;;;N;;;;; +2729;STRESS OUTLINED WHITE STAR;So;0;ON;;;;;N;;;;; +272A;CIRCLED WHITE STAR;So;0;ON;;;;;N;;;;; +272B;OPEN CENTRE BLACK STAR;So;0;ON;;;;;N;OPEN CENTER BLACK STAR;;;; +272C;BLACK CENTRE WHITE STAR;So;0;ON;;;;;N;BLACK CENTER WHITE STAR;;;; +272D;OUTLINED BLACK STAR;So;0;ON;;;;;N;;;;; +272E;HEAVY OUTLINED BLACK STAR;So;0;ON;;;;;N;;;;; +272F;PINWHEEL STAR;So;0;ON;;;;;N;;;;; +2730;SHADOWED WHITE STAR;So;0;ON;;;;;N;;;;; +2731;HEAVY ASTERISK;So;0;ON;;;;;N;;;;; +2732;OPEN CENTRE ASTERISK;So;0;ON;;;;;N;OPEN CENTER ASTERISK;;;; +2733;EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +2734;EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +2735;EIGHT POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;; +2736;SIX POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +2737;EIGHT POINTED RECTILINEAR BLACK STAR;So;0;ON;;;;;N;;;;; +2738;HEAVY EIGHT POINTED RECTILINEAR BLACK STAR;So;0;ON;;;;;N;;;;; +2739;TWELVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +273A;SIXTEEN POINTED ASTERISK;So;0;ON;;;;;N;;;;; +273B;TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +273C;OPEN CENTRE TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;OPEN CENTER TEARDROP-SPOKED ASTERISK;;;; +273D;HEAVY TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +273E;SIX PETALLED BLACK AND WHITE FLORETTE;So;0;ON;;;;;N;;;;; +273F;BLACK FLORETTE;So;0;ON;;;;;N;;;;; +2740;WHITE FLORETTE;So;0;ON;;;;;N;;;;; +2741;EIGHT PETALLED OUTLINED BLACK FLORETTE;So;0;ON;;;;;N;;;;; +2742;CIRCLED OPEN CENTRE EIGHT POINTED STAR;So;0;ON;;;;;N;CIRCLED OPEN CENTER EIGHT POINTED STAR;;;; +2743;HEAVY TEARDROP-SPOKED PINWHEEL ASTERISK;So;0;ON;;;;;N;;;;; +2744;SNOWFLAKE;So;0;ON;;;;;N;;;;; +2745;TIGHT TRIFOLIATE SNOWFLAKE;So;0;ON;;;;;N;;;;; +2746;HEAVY CHEVRON SNOWFLAKE;So;0;ON;;;;;N;;;;; +2747;SPARKLE;So;0;ON;;;;;N;;;;; +2748;HEAVY SPARKLE;So;0;ON;;;;;N;;;;; +2749;BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +274A;EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;; +274B;HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;; +274D;SHADOWED WHITE CIRCLE;So;0;ON;;;;;N;;;;; +274F;LOWER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; +2750;UPPER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; +2751;LOWER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; +2752;UPPER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; +2756;BLACK DIAMOND MINUS WHITE X;So;0;ON;;;;;N;;;;; +2758;LIGHT VERTICAL BAR;So;0;ON;;;;;N;;;;; +2759;MEDIUM VERTICAL BAR;So;0;ON;;;;;N;;;;; +275A;HEAVY VERTICAL BAR;So;0;ON;;;;;N;;;;; +275B;HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +275C;HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +275D;HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +275E;HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +2761;CURVED STEM PARAGRAPH SIGN ORNAMENT;So;0;ON;;;;;N;;;;; +2762;HEAVY EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +2763;HEAVY HEART EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +2764;HEAVY BLACK HEART;So;0;ON;;;;;N;;;;; +2765;ROTATED HEAVY BLACK HEART BULLET;So;0;ON;;;;;N;;;;; +2766;FLORAL HEART;So;0;ON;;;;;N;;;;; +2767;ROTATED FLORAL HEART BULLET;So;0;ON;;;;;N;;;;; +2768;MEDIUM LEFT PARENTHESIS ORNAMENT;Ps;0;ON;;;;;Y;;;;; +2769;MEDIUM RIGHT PARENTHESIS ORNAMENT;Pe;0;ON;;;;;Y;;;;; +276A;MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT;Ps;0;ON;;;;;Y;;;;; +276B;MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT;Pe;0;ON;;;;;Y;;;;; +276C;MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;; +276D;MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;; +276E;HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT;Ps;0;ON;;;;;Y;;;;; +276F;HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT;Pe;0;ON;;;;;Y;;;;; +2770;HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;; +2771;HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;; +2772;LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;; +2773;LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;; +2774;MEDIUM LEFT CURLY BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;; +2775;MEDIUM RIGHT CURLY BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;; +2776;DINGBAT NEGATIVE CIRCLED DIGIT ONE;No;0;ON;;;1;1;N;INVERSE CIRCLED DIGIT ONE;;;; +2777;DINGBAT NEGATIVE CIRCLED DIGIT TWO;No;0;ON;;;2;2;N;INVERSE CIRCLED DIGIT TWO;;;; +2778;DINGBAT NEGATIVE CIRCLED DIGIT THREE;No;0;ON;;;3;3;N;INVERSE CIRCLED DIGIT THREE;;;; +2779;DINGBAT NEGATIVE CIRCLED DIGIT FOUR;No;0;ON;;;4;4;N;INVERSE CIRCLED DIGIT FOUR;;;; +277A;DINGBAT NEGATIVE CIRCLED DIGIT FIVE;No;0;ON;;;5;5;N;INVERSE CIRCLED DIGIT FIVE;;;; +277B;DINGBAT NEGATIVE CIRCLED DIGIT SIX;No;0;ON;;;6;6;N;INVERSE CIRCLED DIGIT SIX;;;; +277C;DINGBAT NEGATIVE CIRCLED DIGIT SEVEN;No;0;ON;;;7;7;N;INVERSE CIRCLED DIGIT SEVEN;;;; +277D;DINGBAT NEGATIVE CIRCLED DIGIT EIGHT;No;0;ON;;;8;8;N;INVERSE CIRCLED DIGIT EIGHT;;;; +277E;DINGBAT NEGATIVE CIRCLED DIGIT NINE;No;0;ON;;;9;9;N;INVERSE CIRCLED DIGIT NINE;;;; +277F;DINGBAT NEGATIVE CIRCLED NUMBER TEN;No;0;ON;;;;10;N;INVERSE CIRCLED NUMBER TEN;;;; +2780;DINGBAT CIRCLED SANS-SERIF DIGIT ONE;No;0;ON;;;1;1;N;CIRCLED SANS-SERIF DIGIT ONE;;;; +2781;DINGBAT CIRCLED SANS-SERIF DIGIT TWO;No;0;ON;;;2;2;N;CIRCLED SANS-SERIF DIGIT TWO;;;; +2782;DINGBAT CIRCLED SANS-SERIF DIGIT THREE;No;0;ON;;;3;3;N;CIRCLED SANS-SERIF DIGIT THREE;;;; +2783;DINGBAT CIRCLED SANS-SERIF DIGIT FOUR;No;0;ON;;;4;4;N;CIRCLED SANS-SERIF DIGIT FOUR;;;; +2784;DINGBAT CIRCLED SANS-SERIF DIGIT FIVE;No;0;ON;;;5;5;N;CIRCLED SANS-SERIF DIGIT FIVE;;;; +2785;DINGBAT CIRCLED SANS-SERIF DIGIT SIX;No;0;ON;;;6;6;N;CIRCLED SANS-SERIF DIGIT SIX;;;; +2786;DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN;No;0;ON;;;7;7;N;CIRCLED SANS-SERIF DIGIT SEVEN;;;; +2787;DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT;No;0;ON;;;8;8;N;CIRCLED SANS-SERIF DIGIT EIGHT;;;; +2788;DINGBAT CIRCLED SANS-SERIF DIGIT NINE;No;0;ON;;;9;9;N;CIRCLED SANS-SERIF DIGIT NINE;;;; +2789;DINGBAT CIRCLED SANS-SERIF NUMBER TEN;No;0;ON;;;;10;N;CIRCLED SANS-SERIF NUMBER TEN;;;; +278A;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE;No;0;ON;;;1;1;N;INVERSE CIRCLED SANS-SERIF DIGIT ONE;;;; +278B;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO;No;0;ON;;;2;2;N;INVERSE CIRCLED SANS-SERIF DIGIT TWO;;;; +278C;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE;No;0;ON;;;3;3;N;INVERSE CIRCLED SANS-SERIF DIGIT THREE;;;; +278D;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR;No;0;ON;;;4;4;N;INVERSE CIRCLED SANS-SERIF DIGIT FOUR;;;; +278E;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE;No;0;ON;;;5;5;N;INVERSE CIRCLED SANS-SERIF DIGIT FIVE;;;; +278F;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX;No;0;ON;;;6;6;N;INVERSE CIRCLED SANS-SERIF DIGIT SIX;;;; +2790;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN;No;0;ON;;;7;7;N;INVERSE CIRCLED SANS-SERIF DIGIT SEVEN;;;; +2791;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT;No;0;ON;;;8;8;N;INVERSE CIRCLED SANS-SERIF DIGIT EIGHT;;;; +2792;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE;No;0;ON;;;9;9;N;INVERSE CIRCLED SANS-SERIF DIGIT NINE;;;; +2793;DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN;No;0;ON;;;;10;N;INVERSE CIRCLED SANS-SERIF NUMBER TEN;;;; +2794;HEAVY WIDE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WIDE-HEADED RIGHT ARROW;;;; +2798;HEAVY SOUTH EAST ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT ARROW;;;; +2799;HEAVY RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY RIGHT ARROW;;;; +279A;HEAVY NORTH EAST ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT ARROW;;;; +279B;DRAFTING POINT RIGHTWARDS ARROW;So;0;ON;;;;;N;DRAFTING POINT RIGHT ARROW;;;; +279C;HEAVY ROUND-TIPPED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY ROUND-TIPPED RIGHT ARROW;;;; +279D;TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;TRIANGLE-HEADED RIGHT ARROW;;;; +279E;HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY TRIANGLE-HEADED RIGHT ARROW;;;; +279F;DASHED TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;DASHED TRIANGLE-HEADED RIGHT ARROW;;;; +27A0;HEAVY DASHED TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY DASHED TRIANGLE-HEADED RIGHT ARROW;;;; +27A1;BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;BLACK RIGHT ARROW;;;; +27A2;THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;THREE-D TOP-LIGHTED RIGHT ARROWHEAD;;;; +27A3;THREE-D BOTTOM-LIGHTED RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;THREE-D BOTTOM-LIGHTED RIGHT ARROWHEAD;;;; +27A4;BLACK RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;BLACK RIGHT ARROWHEAD;;;; +27A5;HEAVY BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK CURVED DOWN AND RIGHT ARROW;;;; +27A6;HEAVY BLACK CURVED UPWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK CURVED UP AND RIGHT ARROW;;;; +27A7;SQUAT BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;SQUAT BLACK RIGHT ARROW;;;; +27A8;HEAVY CONCAVE-POINTED BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY CONCAVE-POINTED BLACK RIGHT ARROW;;;; +27A9;RIGHT-SHADED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;RIGHT-SHADED WHITE RIGHT ARROW;;;; +27AA;LEFT-SHADED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;LEFT-SHADED WHITE RIGHT ARROW;;;; +27AB;BACK-TILTED SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;BACK-TILTED SHADOWED WHITE RIGHT ARROW;;;; +27AC;FRONT-TILTED SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;FRONT-TILTED SHADOWED WHITE RIGHT ARROW;;;; +27AD;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;; +27AE;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;; +27AF;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;; +27B1;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;; +27B2;CIRCLED HEAVY WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;CIRCLED HEAVY WHITE RIGHT ARROW;;;; +27B3;WHITE-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;WHITE-FEATHERED RIGHT ARROW;;;; +27B4;BLACK-FEATHERED SOUTH EAST ARROW;So;0;ON;;;;;N;BLACK-FEATHERED LOWER RIGHT ARROW;;;; +27B5;BLACK-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;BLACK-FEATHERED RIGHT ARROW;;;; +27B6;BLACK-FEATHERED NORTH EAST ARROW;So;0;ON;;;;;N;BLACK-FEATHERED UPPER RIGHT ARROW;;;; +27B7;HEAVY BLACK-FEATHERED SOUTH EAST ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED LOWER RIGHT ARROW;;;; +27B8;HEAVY BLACK-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED RIGHT ARROW;;;; +27B9;HEAVY BLACK-FEATHERED NORTH EAST ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED UPPER RIGHT ARROW;;;; +27BA;TEARDROP-BARBED RIGHTWARDS ARROW;So;0;ON;;;;;N;TEARDROP-BARBED RIGHT ARROW;;;; +27BB;HEAVY TEARDROP-SHANKED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY TEARDROP-SHANKED RIGHT ARROW;;;; +27BC;WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;WEDGE-TAILED RIGHT ARROW;;;; +27BD;HEAVY WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WEDGE-TAILED RIGHT ARROW;;;; +27BE;OPEN-OUTLINED RIGHTWARDS ARROW;So;0;ON;;;;;N;OPEN-OUTLINED RIGHT ARROW;;;; +27D0;WHITE DIAMOND WITH CENTRED DOT;Sm;0;ON;;;;;N;;;;; +27D1;AND WITH DOT;Sm;0;ON;;;;;N;;;;; +27D2;ELEMENT OF OPENING UPWARDS;Sm;0;ON;;;;;N;;;;; +27D3;LOWER RIGHT CORNER WITH DOT;Sm;0;ON;;;;;Y;;;;; +27D4;UPPER LEFT CORNER WITH DOT;Sm;0;ON;;;;;Y;;;;; +27D5;LEFT OUTER JOIN;Sm;0;ON;;;;;Y;;;;; +27D6;RIGHT OUTER JOIN;Sm;0;ON;;;;;Y;;;;; +27D7;FULL OUTER JOIN;Sm;0;ON;;;;;N;;;;; +27D8;LARGE UP TACK;Sm;0;ON;;;;;N;;;;; +27D9;LARGE DOWN TACK;Sm;0;ON;;;;;N;;;;; +27DA;LEFT AND RIGHT DOUBLE TURNSTILE;Sm;0;ON;;;;;N;;;;; +27DB;LEFT AND RIGHT TACK;Sm;0;ON;;;;;N;;;;; +27DC;LEFT MULTIMAP;Sm;0;ON;;;;;Y;;;;; +27DD;LONG RIGHT TACK;Sm;0;ON;;;;;Y;;;;; +27DE;LONG LEFT TACK;Sm;0;ON;;;;;Y;;;;; +27DF;UP TACK WITH CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;; +27E0;LOZENGE DIVIDED BY HORIZONTAL RULE;Sm;0;ON;;;;;N;;;;; +27E1;WHITE CONCAVE-SIDED DIAMOND;Sm;0;ON;;;;;N;;;;; +27E2;WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK;Sm;0;ON;;;;;Y;;;;; +27E3;WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK;Sm;0;ON;;;;;Y;;;;; +27E4;WHITE SQUARE WITH LEFTWARDS TICK;Sm;0;ON;;;;;Y;;;;; +27E5;WHITE SQUARE WITH RIGHTWARDS TICK;Sm;0;ON;;;;;Y;;;;; +27E6;MATHEMATICAL LEFT WHITE SQUARE BRACKET;Ps;0;ON;;;;;Y;;;;; +27E7;MATHEMATICAL RIGHT WHITE SQUARE BRACKET;Pe;0;ON;;;;;Y;;;;; +27E8;MATHEMATICAL LEFT ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;; +27E9;MATHEMATICAL RIGHT ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;; +27EA;MATHEMATICAL LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;; +27EB;MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;; +27F0;UPWARDS QUADRUPLE ARROW;Sm;0;ON;;;;;N;;;;; +27F1;DOWNWARDS QUADRUPLE ARROW;Sm;0;ON;;;;;N;;;;; +27F2;ANTICLOCKWISE GAPPED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;; +27F3;CLOCKWISE GAPPED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;; +27F4;RIGHT ARROW WITH CIRCLED PLUS;Sm;0;ON;;;;;N;;;;; +27F5;LONG LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +27F6;LONG RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +27F7;LONG LEFT RIGHT ARROW;Sm;0;ON;;;;;N;;;;; +27F8;LONG LEFTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;;;;; +27F9;LONG RIGHTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;;;;; +27FA;LONG LEFT RIGHT DOUBLE ARROW;Sm;0;ON;;;;;N;;;;; +27FB;LONG LEFTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +27FC;LONG RIGHTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +27FD;LONG LEFTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +27FE;LONG RIGHTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +27FF;LONG RIGHTWARDS SQUIGGLE ARROW;Sm;0;ON;;;;;N;;;;; +2800;BRAILLE PATTERN BLANK;So;0;ON;;;;;N;;;;; +2801;BRAILLE PATTERN DOTS-1;So;0;ON;;;;;N;;;;; +2802;BRAILLE PATTERN DOTS-2;So;0;ON;;;;;N;;;;; +2803;BRAILLE PATTERN DOTS-12;So;0;ON;;;;;N;;;;; +2804;BRAILLE PATTERN DOTS-3;So;0;ON;;;;;N;;;;; +2805;BRAILLE PATTERN DOTS-13;So;0;ON;;;;;N;;;;; +2806;BRAILLE PATTERN DOTS-23;So;0;ON;;;;;N;;;;; +2807;BRAILLE PATTERN DOTS-123;So;0;ON;;;;;N;;;;; +2808;BRAILLE PATTERN DOTS-4;So;0;ON;;;;;N;;;;; +2809;BRAILLE PATTERN DOTS-14;So;0;ON;;;;;N;;;;; +280A;BRAILLE PATTERN DOTS-24;So;0;ON;;;;;N;;;;; +280B;BRAILLE PATTERN DOTS-124;So;0;ON;;;;;N;;;;; +280C;BRAILLE PATTERN DOTS-34;So;0;ON;;;;;N;;;;; +280D;BRAILLE PATTERN DOTS-134;So;0;ON;;;;;N;;;;; +280E;BRAILLE PATTERN DOTS-234;So;0;ON;;;;;N;;;;; +280F;BRAILLE PATTERN DOTS-1234;So;0;ON;;;;;N;;;;; +2810;BRAILLE PATTERN DOTS-5;So;0;ON;;;;;N;;;;; +2811;BRAILLE PATTERN DOTS-15;So;0;ON;;;;;N;;;;; +2812;BRAILLE PATTERN DOTS-25;So;0;ON;;;;;N;;;;; +2813;BRAILLE PATTERN DOTS-125;So;0;ON;;;;;N;;;;; +2814;BRAILLE PATTERN DOTS-35;So;0;ON;;;;;N;;;;; +2815;BRAILLE PATTERN DOTS-135;So;0;ON;;;;;N;;;;; +2816;BRAILLE PATTERN DOTS-235;So;0;ON;;;;;N;;;;; +2817;BRAILLE PATTERN DOTS-1235;So;0;ON;;;;;N;;;;; +2818;BRAILLE PATTERN DOTS-45;So;0;ON;;;;;N;;;;; +2819;BRAILLE PATTERN DOTS-145;So;0;ON;;;;;N;;;;; +281A;BRAILLE PATTERN DOTS-245;So;0;ON;;;;;N;;;;; +281B;BRAILLE PATTERN DOTS-1245;So;0;ON;;;;;N;;;;; +281C;BRAILLE PATTERN DOTS-345;So;0;ON;;;;;N;;;;; +281D;BRAILLE PATTERN DOTS-1345;So;0;ON;;;;;N;;;;; +281E;BRAILLE PATTERN DOTS-2345;So;0;ON;;;;;N;;;;; +281F;BRAILLE PATTERN DOTS-12345;So;0;ON;;;;;N;;;;; +2820;BRAILLE PATTERN DOTS-6;So;0;ON;;;;;N;;;;; +2821;BRAILLE PATTERN DOTS-16;So;0;ON;;;;;N;;;;; +2822;BRAILLE PATTERN DOTS-26;So;0;ON;;;;;N;;;;; +2823;BRAILLE PATTERN DOTS-126;So;0;ON;;;;;N;;;;; +2824;BRAILLE PATTERN DOTS-36;So;0;ON;;;;;N;;;;; +2825;BRAILLE PATTERN DOTS-136;So;0;ON;;;;;N;;;;; +2826;BRAILLE PATTERN DOTS-236;So;0;ON;;;;;N;;;;; +2827;BRAILLE PATTERN DOTS-1236;So;0;ON;;;;;N;;;;; +2828;BRAILLE PATTERN DOTS-46;So;0;ON;;;;;N;;;;; +2829;BRAILLE PATTERN DOTS-146;So;0;ON;;;;;N;;;;; +282A;BRAILLE PATTERN DOTS-246;So;0;ON;;;;;N;;;;; +282B;BRAILLE PATTERN DOTS-1246;So;0;ON;;;;;N;;;;; +282C;BRAILLE PATTERN DOTS-346;So;0;ON;;;;;N;;;;; +282D;BRAILLE PATTERN DOTS-1346;So;0;ON;;;;;N;;;;; +282E;BRAILLE PATTERN DOTS-2346;So;0;ON;;;;;N;;;;; +282F;BRAILLE PATTERN DOTS-12346;So;0;ON;;;;;N;;;;; +2830;BRAILLE PATTERN DOTS-56;So;0;ON;;;;;N;;;;; +2831;BRAILLE PATTERN DOTS-156;So;0;ON;;;;;N;;;;; +2832;BRAILLE PATTERN DOTS-256;So;0;ON;;;;;N;;;;; +2833;BRAILLE PATTERN DOTS-1256;So;0;ON;;;;;N;;;;; +2834;BRAILLE PATTERN DOTS-356;So;0;ON;;;;;N;;;;; +2835;BRAILLE PATTERN DOTS-1356;So;0;ON;;;;;N;;;;; +2836;BRAILLE PATTERN DOTS-2356;So;0;ON;;;;;N;;;;; +2837;BRAILLE PATTERN DOTS-12356;So;0;ON;;;;;N;;;;; +2838;BRAILLE PATTERN DOTS-456;So;0;ON;;;;;N;;;;; +2839;BRAILLE PATTERN DOTS-1456;So;0;ON;;;;;N;;;;; +283A;BRAILLE PATTERN DOTS-2456;So;0;ON;;;;;N;;;;; +283B;BRAILLE PATTERN DOTS-12456;So;0;ON;;;;;N;;;;; +283C;BRAILLE PATTERN DOTS-3456;So;0;ON;;;;;N;;;;; +283D;BRAILLE PATTERN DOTS-13456;So;0;ON;;;;;N;;;;; +283E;BRAILLE PATTERN DOTS-23456;So;0;ON;;;;;N;;;;; +283F;BRAILLE PATTERN DOTS-123456;So;0;ON;;;;;N;;;;; +2840;BRAILLE PATTERN DOTS-7;So;0;ON;;;;;N;;;;; +2841;BRAILLE PATTERN DOTS-17;So;0;ON;;;;;N;;;;; +2842;BRAILLE PATTERN DOTS-27;So;0;ON;;;;;N;;;;; +2843;BRAILLE PATTERN DOTS-127;So;0;ON;;;;;N;;;;; +2844;BRAILLE PATTERN DOTS-37;So;0;ON;;;;;N;;;;; +2845;BRAILLE PATTERN DOTS-137;So;0;ON;;;;;N;;;;; +2846;BRAILLE PATTERN DOTS-237;So;0;ON;;;;;N;;;;; +2847;BRAILLE PATTERN DOTS-1237;So;0;ON;;;;;N;;;;; +2848;BRAILLE PATTERN DOTS-47;So;0;ON;;;;;N;;;;; +2849;BRAILLE PATTERN DOTS-147;So;0;ON;;;;;N;;;;; +284A;BRAILLE PATTERN DOTS-247;So;0;ON;;;;;N;;;;; +284B;BRAILLE PATTERN DOTS-1247;So;0;ON;;;;;N;;;;; +284C;BRAILLE PATTERN DOTS-347;So;0;ON;;;;;N;;;;; +284D;BRAILLE PATTERN DOTS-1347;So;0;ON;;;;;N;;;;; +284E;BRAILLE PATTERN DOTS-2347;So;0;ON;;;;;N;;;;; +284F;BRAILLE PATTERN DOTS-12347;So;0;ON;;;;;N;;;;; +2850;BRAILLE PATTERN DOTS-57;So;0;ON;;;;;N;;;;; +2851;BRAILLE PATTERN DOTS-157;So;0;ON;;;;;N;;;;; +2852;BRAILLE PATTERN DOTS-257;So;0;ON;;;;;N;;;;; +2853;BRAILLE PATTERN DOTS-1257;So;0;ON;;;;;N;;;;; +2854;BRAILLE PATTERN DOTS-357;So;0;ON;;;;;N;;;;; +2855;BRAILLE PATTERN DOTS-1357;So;0;ON;;;;;N;;;;; +2856;BRAILLE PATTERN DOTS-2357;So;0;ON;;;;;N;;;;; +2857;BRAILLE PATTERN DOTS-12357;So;0;ON;;;;;N;;;;; +2858;BRAILLE PATTERN DOTS-457;So;0;ON;;;;;N;;;;; +2859;BRAILLE PATTERN DOTS-1457;So;0;ON;;;;;N;;;;; +285A;BRAILLE PATTERN DOTS-2457;So;0;ON;;;;;N;;;;; +285B;BRAILLE PATTERN DOTS-12457;So;0;ON;;;;;N;;;;; +285C;BRAILLE PATTERN DOTS-3457;So;0;ON;;;;;N;;;;; +285D;BRAILLE PATTERN DOTS-13457;So;0;ON;;;;;N;;;;; +285E;BRAILLE PATTERN DOTS-23457;So;0;ON;;;;;N;;;;; +285F;BRAILLE PATTERN DOTS-123457;So;0;ON;;;;;N;;;;; +2860;BRAILLE PATTERN DOTS-67;So;0;ON;;;;;N;;;;; +2861;BRAILLE PATTERN DOTS-167;So;0;ON;;;;;N;;;;; +2862;BRAILLE PATTERN DOTS-267;So;0;ON;;;;;N;;;;; +2863;BRAILLE PATTERN DOTS-1267;So;0;ON;;;;;N;;;;; +2864;BRAILLE PATTERN DOTS-367;So;0;ON;;;;;N;;;;; +2865;BRAILLE PATTERN DOTS-1367;So;0;ON;;;;;N;;;;; +2866;BRAILLE PATTERN DOTS-2367;So;0;ON;;;;;N;;;;; +2867;BRAILLE PATTERN DOTS-12367;So;0;ON;;;;;N;;;;; +2868;BRAILLE PATTERN DOTS-467;So;0;ON;;;;;N;;;;; +2869;BRAILLE PATTERN DOTS-1467;So;0;ON;;;;;N;;;;; +286A;BRAILLE PATTERN DOTS-2467;So;0;ON;;;;;N;;;;; +286B;BRAILLE PATTERN DOTS-12467;So;0;ON;;;;;N;;;;; +286C;BRAILLE PATTERN DOTS-3467;So;0;ON;;;;;N;;;;; +286D;BRAILLE PATTERN DOTS-13467;So;0;ON;;;;;N;;;;; +286E;BRAILLE PATTERN DOTS-23467;So;0;ON;;;;;N;;;;; +286F;BRAILLE PATTERN DOTS-123467;So;0;ON;;;;;N;;;;; +2870;BRAILLE PATTERN DOTS-567;So;0;ON;;;;;N;;;;; +2871;BRAILLE PATTERN DOTS-1567;So;0;ON;;;;;N;;;;; +2872;BRAILLE PATTERN DOTS-2567;So;0;ON;;;;;N;;;;; +2873;BRAILLE PATTERN DOTS-12567;So;0;ON;;;;;N;;;;; +2874;BRAILLE PATTERN DOTS-3567;So;0;ON;;;;;N;;;;; +2875;BRAILLE PATTERN DOTS-13567;So;0;ON;;;;;N;;;;; +2876;BRAILLE PATTERN DOTS-23567;So;0;ON;;;;;N;;;;; +2877;BRAILLE PATTERN DOTS-123567;So;0;ON;;;;;N;;;;; +2878;BRAILLE PATTERN DOTS-4567;So;0;ON;;;;;N;;;;; +2879;BRAILLE PATTERN DOTS-14567;So;0;ON;;;;;N;;;;; +287A;BRAILLE PATTERN DOTS-24567;So;0;ON;;;;;N;;;;; +287B;BRAILLE PATTERN DOTS-124567;So;0;ON;;;;;N;;;;; +287C;BRAILLE PATTERN DOTS-34567;So;0;ON;;;;;N;;;;; +287D;BRAILLE PATTERN DOTS-134567;So;0;ON;;;;;N;;;;; +287E;BRAILLE PATTERN DOTS-234567;So;0;ON;;;;;N;;;;; +287F;BRAILLE PATTERN DOTS-1234567;So;0;ON;;;;;N;;;;; +2880;BRAILLE PATTERN DOTS-8;So;0;ON;;;;;N;;;;; +2881;BRAILLE PATTERN DOTS-18;So;0;ON;;;;;N;;;;; +2882;BRAILLE PATTERN DOTS-28;So;0;ON;;;;;N;;;;; +2883;BRAILLE PATTERN DOTS-128;So;0;ON;;;;;N;;;;; +2884;BRAILLE PATTERN DOTS-38;So;0;ON;;;;;N;;;;; +2885;BRAILLE PATTERN DOTS-138;So;0;ON;;;;;N;;;;; +2886;BRAILLE PATTERN DOTS-238;So;0;ON;;;;;N;;;;; +2887;BRAILLE PATTERN DOTS-1238;So;0;ON;;;;;N;;;;; +2888;BRAILLE PATTERN DOTS-48;So;0;ON;;;;;N;;;;; +2889;BRAILLE PATTERN DOTS-148;So;0;ON;;;;;N;;;;; +288A;BRAILLE PATTERN DOTS-248;So;0;ON;;;;;N;;;;; +288B;BRAILLE PATTERN DOTS-1248;So;0;ON;;;;;N;;;;; +288C;BRAILLE PATTERN DOTS-348;So;0;ON;;;;;N;;;;; +288D;BRAILLE PATTERN DOTS-1348;So;0;ON;;;;;N;;;;; +288E;BRAILLE PATTERN DOTS-2348;So;0;ON;;;;;N;;;;; +288F;BRAILLE PATTERN DOTS-12348;So;0;ON;;;;;N;;;;; +2890;BRAILLE PATTERN DOTS-58;So;0;ON;;;;;N;;;;; +2891;BRAILLE PATTERN DOTS-158;So;0;ON;;;;;N;;;;; +2892;BRAILLE PATTERN DOTS-258;So;0;ON;;;;;N;;;;; +2893;BRAILLE PATTERN DOTS-1258;So;0;ON;;;;;N;;;;; +2894;BRAILLE PATTERN DOTS-358;So;0;ON;;;;;N;;;;; +2895;BRAILLE PATTERN DOTS-1358;So;0;ON;;;;;N;;;;; +2896;BRAILLE PATTERN DOTS-2358;So;0;ON;;;;;N;;;;; +2897;BRAILLE PATTERN DOTS-12358;So;0;ON;;;;;N;;;;; +2898;BRAILLE PATTERN DOTS-458;So;0;ON;;;;;N;;;;; +2899;BRAILLE PATTERN DOTS-1458;So;0;ON;;;;;N;;;;; +289A;BRAILLE PATTERN DOTS-2458;So;0;ON;;;;;N;;;;; +289B;BRAILLE PATTERN DOTS-12458;So;0;ON;;;;;N;;;;; +289C;BRAILLE PATTERN DOTS-3458;So;0;ON;;;;;N;;;;; +289D;BRAILLE PATTERN DOTS-13458;So;0;ON;;;;;N;;;;; +289E;BRAILLE PATTERN DOTS-23458;So;0;ON;;;;;N;;;;; +289F;BRAILLE PATTERN DOTS-123458;So;0;ON;;;;;N;;;;; +28A0;BRAILLE PATTERN DOTS-68;So;0;ON;;;;;N;;;;; +28A1;BRAILLE PATTERN DOTS-168;So;0;ON;;;;;N;;;;; +28A2;BRAILLE PATTERN DOTS-268;So;0;ON;;;;;N;;;;; +28A3;BRAILLE PATTERN DOTS-1268;So;0;ON;;;;;N;;;;; +28A4;BRAILLE PATTERN DOTS-368;So;0;ON;;;;;N;;;;; +28A5;BRAILLE PATTERN DOTS-1368;So;0;ON;;;;;N;;;;; +28A6;BRAILLE PATTERN DOTS-2368;So;0;ON;;;;;N;;;;; +28A7;BRAILLE PATTERN DOTS-12368;So;0;ON;;;;;N;;;;; +28A8;BRAILLE PATTERN DOTS-468;So;0;ON;;;;;N;;;;; +28A9;BRAILLE PATTERN DOTS-1468;So;0;ON;;;;;N;;;;; +28AA;BRAILLE PATTERN DOTS-2468;So;0;ON;;;;;N;;;;; +28AB;BRAILLE PATTERN DOTS-12468;So;0;ON;;;;;N;;;;; +28AC;BRAILLE PATTERN DOTS-3468;So;0;ON;;;;;N;;;;; +28AD;BRAILLE PATTERN DOTS-13468;So;0;ON;;;;;N;;;;; +28AE;BRAILLE PATTERN DOTS-23468;So;0;ON;;;;;N;;;;; +28AF;BRAILLE PATTERN DOTS-123468;So;0;ON;;;;;N;;;;; +28B0;BRAILLE PATTERN DOTS-568;So;0;ON;;;;;N;;;;; +28B1;BRAILLE PATTERN DOTS-1568;So;0;ON;;;;;N;;;;; +28B2;BRAILLE PATTERN DOTS-2568;So;0;ON;;;;;N;;;;; +28B3;BRAILLE PATTERN DOTS-12568;So;0;ON;;;;;N;;;;; +28B4;BRAILLE PATTERN DOTS-3568;So;0;ON;;;;;N;;;;; +28B5;BRAILLE PATTERN DOTS-13568;So;0;ON;;;;;N;;;;; +28B6;BRAILLE PATTERN DOTS-23568;So;0;ON;;;;;N;;;;; +28B7;BRAILLE PATTERN DOTS-123568;So;0;ON;;;;;N;;;;; +28B8;BRAILLE PATTERN DOTS-4568;So;0;ON;;;;;N;;;;; +28B9;BRAILLE PATTERN DOTS-14568;So;0;ON;;;;;N;;;;; +28BA;BRAILLE PATTERN DOTS-24568;So;0;ON;;;;;N;;;;; +28BB;BRAILLE PATTERN DOTS-124568;So;0;ON;;;;;N;;;;; +28BC;BRAILLE PATTERN DOTS-34568;So;0;ON;;;;;N;;;;; +28BD;BRAILLE PATTERN DOTS-134568;So;0;ON;;;;;N;;;;; +28BE;BRAILLE PATTERN DOTS-234568;So;0;ON;;;;;N;;;;; +28BF;BRAILLE PATTERN DOTS-1234568;So;0;ON;;;;;N;;;;; +28C0;BRAILLE PATTERN DOTS-78;So;0;ON;;;;;N;;;;; +28C1;BRAILLE PATTERN DOTS-178;So;0;ON;;;;;N;;;;; +28C2;BRAILLE PATTERN DOTS-278;So;0;ON;;;;;N;;;;; +28C3;BRAILLE PATTERN DOTS-1278;So;0;ON;;;;;N;;;;; +28C4;BRAILLE PATTERN DOTS-378;So;0;ON;;;;;N;;;;; +28C5;BRAILLE PATTERN DOTS-1378;So;0;ON;;;;;N;;;;; +28C6;BRAILLE PATTERN DOTS-2378;So;0;ON;;;;;N;;;;; +28C7;BRAILLE PATTERN DOTS-12378;So;0;ON;;;;;N;;;;; +28C8;BRAILLE PATTERN DOTS-478;So;0;ON;;;;;N;;;;; +28C9;BRAILLE PATTERN DOTS-1478;So;0;ON;;;;;N;;;;; +28CA;BRAILLE PATTERN DOTS-2478;So;0;ON;;;;;N;;;;; +28CB;BRAILLE PATTERN DOTS-12478;So;0;ON;;;;;N;;;;; +28CC;BRAILLE PATTERN DOTS-3478;So;0;ON;;;;;N;;;;; +28CD;BRAILLE PATTERN DOTS-13478;So;0;ON;;;;;N;;;;; +28CE;BRAILLE PATTERN DOTS-23478;So;0;ON;;;;;N;;;;; +28CF;BRAILLE PATTERN DOTS-123478;So;0;ON;;;;;N;;;;; +28D0;BRAILLE PATTERN DOTS-578;So;0;ON;;;;;N;;;;; +28D1;BRAILLE PATTERN DOTS-1578;So;0;ON;;;;;N;;;;; +28D2;BRAILLE PATTERN DOTS-2578;So;0;ON;;;;;N;;;;; +28D3;BRAILLE PATTERN DOTS-12578;So;0;ON;;;;;N;;;;; +28D4;BRAILLE PATTERN DOTS-3578;So;0;ON;;;;;N;;;;; +28D5;BRAILLE PATTERN DOTS-13578;So;0;ON;;;;;N;;;;; +28D6;BRAILLE PATTERN DOTS-23578;So;0;ON;;;;;N;;;;; +28D7;BRAILLE PATTERN DOTS-123578;So;0;ON;;;;;N;;;;; +28D8;BRAILLE PATTERN DOTS-4578;So;0;ON;;;;;N;;;;; +28D9;BRAILLE PATTERN DOTS-14578;So;0;ON;;;;;N;;;;; +28DA;BRAILLE PATTERN DOTS-24578;So;0;ON;;;;;N;;;;; +28DB;BRAILLE PATTERN DOTS-124578;So;0;ON;;;;;N;;;;; +28DC;BRAILLE PATTERN DOTS-34578;So;0;ON;;;;;N;;;;; +28DD;BRAILLE PATTERN DOTS-134578;So;0;ON;;;;;N;;;;; +28DE;BRAILLE PATTERN DOTS-234578;So;0;ON;;;;;N;;;;; +28DF;BRAILLE PATTERN DOTS-1234578;So;0;ON;;;;;N;;;;; +28E0;BRAILLE PATTERN DOTS-678;So;0;ON;;;;;N;;;;; +28E1;BRAILLE PATTERN DOTS-1678;So;0;ON;;;;;N;;;;; +28E2;BRAILLE PATTERN DOTS-2678;So;0;ON;;;;;N;;;;; +28E3;BRAILLE PATTERN DOTS-12678;So;0;ON;;;;;N;;;;; +28E4;BRAILLE PATTERN DOTS-3678;So;0;ON;;;;;N;;;;; +28E5;BRAILLE PATTERN DOTS-13678;So;0;ON;;;;;N;;;;; +28E6;BRAILLE PATTERN DOTS-23678;So;0;ON;;;;;N;;;;; +28E7;BRAILLE PATTERN DOTS-123678;So;0;ON;;;;;N;;;;; +28E8;BRAILLE PATTERN DOTS-4678;So;0;ON;;;;;N;;;;; +28E9;BRAILLE PATTERN DOTS-14678;So;0;ON;;;;;N;;;;; +28EA;BRAILLE PATTERN DOTS-24678;So;0;ON;;;;;N;;;;; +28EB;BRAILLE PATTERN DOTS-124678;So;0;ON;;;;;N;;;;; +28EC;BRAILLE PATTERN DOTS-34678;So;0;ON;;;;;N;;;;; +28ED;BRAILLE PATTERN DOTS-134678;So;0;ON;;;;;N;;;;; +28EE;BRAILLE PATTERN DOTS-234678;So;0;ON;;;;;N;;;;; +28EF;BRAILLE PATTERN DOTS-1234678;So;0;ON;;;;;N;;;;; +28F0;BRAILLE PATTERN DOTS-5678;So;0;ON;;;;;N;;;;; +28F1;BRAILLE PATTERN DOTS-15678;So;0;ON;;;;;N;;;;; +28F2;BRAILLE PATTERN DOTS-25678;So;0;ON;;;;;N;;;;; +28F3;BRAILLE PATTERN DOTS-125678;So;0;ON;;;;;N;;;;; +28F4;BRAILLE PATTERN DOTS-35678;So;0;ON;;;;;N;;;;; +28F5;BRAILLE PATTERN DOTS-135678;So;0;ON;;;;;N;;;;; +28F6;BRAILLE PATTERN DOTS-235678;So;0;ON;;;;;N;;;;; +28F7;BRAILLE PATTERN DOTS-1235678;So;0;ON;;;;;N;;;;; +28F8;BRAILLE PATTERN DOTS-45678;So;0;ON;;;;;N;;;;; +28F9;BRAILLE PATTERN DOTS-145678;So;0;ON;;;;;N;;;;; +28FA;BRAILLE PATTERN DOTS-245678;So;0;ON;;;;;N;;;;; +28FB;BRAILLE PATTERN DOTS-1245678;So;0;ON;;;;;N;;;;; +28FC;BRAILLE PATTERN DOTS-345678;So;0;ON;;;;;N;;;;; +28FD;BRAILLE PATTERN DOTS-1345678;So;0;ON;;;;;N;;;;; +28FE;BRAILLE PATTERN DOTS-2345678;So;0;ON;;;;;N;;;;; +28FF;BRAILLE PATTERN DOTS-12345678;So;0;ON;;;;;N;;;;; +2900;RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2901;RIGHTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2902;LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2903;RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2904;LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2905;RIGHTWARDS TWO-HEADED ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +2906;LEFTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +2907;RIGHTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +2908;DOWNWARDS ARROW WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; +2909;UPWARDS ARROW WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; +290A;UPWARDS TRIPLE ARROW;Sm;0;ON;;;;;N;;;;; +290B;DOWNWARDS TRIPLE ARROW;Sm;0;ON;;;;;N;;;;; +290C;LEFTWARDS DOUBLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +290D;RIGHTWARDS DOUBLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +290E;LEFTWARDS TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +290F;RIGHTWARDS TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +2910;RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +2911;RIGHTWARDS ARROW WITH DOTTED STEM;Sm;0;ON;;;;;N;;;;; +2912;UPWARDS ARROW TO BAR;Sm;0;ON;;;;;N;;;;; +2913;DOWNWARDS ARROW TO BAR;Sm;0;ON;;;;;N;;;;; +2914;RIGHTWARDS ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2915;RIGHTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2916;RIGHTWARDS TWO-HEADED ARROW WITH TAIL;Sm;0;ON;;;;;N;;;;; +2917;RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2918;RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2919;LEFTWARDS ARROW-TAIL;Sm;0;ON;;;;;N;;;;; +291A;RIGHTWARDS ARROW-TAIL;Sm;0;ON;;;;;N;;;;; +291B;LEFTWARDS DOUBLE ARROW-TAIL;Sm;0;ON;;;;;N;;;;; +291C;RIGHTWARDS DOUBLE ARROW-TAIL;Sm;0;ON;;;;;N;;;;; +291D;LEFTWARDS ARROW TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; +291E;RIGHTWARDS ARROW TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; +291F;LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; +2920;RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; +2921;NORTH WEST AND SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2922;NORTH EAST AND SOUTH WEST ARROW;Sm;0;ON;;;;;N;;;;; +2923;NORTH WEST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;; +2924;NORTH EAST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;; +2925;SOUTH EAST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;; +2926;SOUTH WEST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;; +2927;NORTH WEST ARROW AND NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2928;NORTH EAST ARROW AND SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2929;SOUTH EAST ARROW AND SOUTH WEST ARROW;Sm;0;ON;;;;;N;;;;; +292A;SOUTH WEST ARROW AND NORTH WEST ARROW;Sm;0;ON;;;;;N;;;;; +292B;RISING DIAGONAL CROSSING FALLING DIAGONAL;Sm;0;ON;;;;;N;;;;; +292C;FALLING DIAGONAL CROSSING RISING DIAGONAL;Sm;0;ON;;;;;N;;;;; +292D;SOUTH EAST ARROW CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +292E;NORTH EAST ARROW CROSSING SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +292F;FALLING DIAGONAL CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2930;RISING DIAGONAL CROSSING SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2931;NORTH EAST ARROW CROSSING NORTH WEST ARROW;Sm;0;ON;;;;;N;;;;; +2932;NORTH WEST ARROW CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2933;WAVE ARROW POINTING DIRECTLY RIGHT;Sm;0;ON;;;;;N;;;;; +2934;ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS;Sm;0;ON;;;;;N;;;;; +2935;ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS;Sm;0;ON;;;;;N;;;;; +2936;ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS;Sm;0;ON;;;;;N;;;;; +2937;ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS;Sm;0;ON;;;;;N;;;;; +2938;RIGHT-SIDE ARC CLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +2939;LEFT-SIDE ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +293A;TOP ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +293B;BOTTOM ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +293C;TOP ARC CLOCKWISE ARROW WITH MINUS;Sm;0;ON;;;;;N;;;;; +293D;TOP ARC ANTICLOCKWISE ARROW WITH PLUS;Sm;0;ON;;;;;N;;;;; +293E;LOWER RIGHT SEMICIRCULAR CLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +293F;LOWER LEFT SEMICIRCULAR ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +2940;ANTICLOCKWISE CLOSED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;; +2941;CLOCKWISE CLOSED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;; +2942;RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2943;LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2944;SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2945;RIGHTWARDS ARROW WITH PLUS BELOW;Sm;0;ON;;;;;N;;;;; +2946;LEFTWARDS ARROW WITH PLUS BELOW;Sm;0;ON;;;;;N;;;;; +2947;RIGHTWARDS ARROW THROUGH X;Sm;0;ON;;;;;N;;;;; +2948;LEFT RIGHT ARROW THROUGH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; +2949;UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; +294A;LEFT BARB UP RIGHT BARB DOWN HARPOON;Sm;0;ON;;;;;N;;;;; +294B;LEFT BARB DOWN RIGHT BARB UP HARPOON;Sm;0;ON;;;;;N;;;;; +294C;UP BARB RIGHT DOWN BARB LEFT HARPOON;Sm;0;ON;;;;;N;;;;; +294D;UP BARB LEFT DOWN BARB RIGHT HARPOON;Sm;0;ON;;;;;N;;;;; +294E;LEFT BARB UP RIGHT BARB UP HARPOON;Sm;0;ON;;;;;N;;;;; +294F;UP BARB RIGHT DOWN BARB RIGHT HARPOON;Sm;0;ON;;;;;N;;;;; +2950;LEFT BARB DOWN RIGHT BARB DOWN HARPOON;Sm;0;ON;;;;;N;;;;; +2951;UP BARB LEFT DOWN BARB LEFT HARPOON;Sm;0;ON;;;;;N;;;;; +2952;LEFTWARDS HARPOON WITH BARB UP TO BAR;Sm;0;ON;;;;;N;;;;; +2953;RIGHTWARDS HARPOON WITH BARB UP TO BAR;Sm;0;ON;;;;;N;;;;; +2954;UPWARDS HARPOON WITH BARB RIGHT TO BAR;Sm;0;ON;;;;;N;;;;; +2955;DOWNWARDS HARPOON WITH BARB RIGHT TO BAR;Sm;0;ON;;;;;N;;;;; +2956;LEFTWARDS HARPOON WITH BARB DOWN TO BAR;Sm;0;ON;;;;;N;;;;; +2957;RIGHTWARDS HARPOON WITH BARB DOWN TO BAR;Sm;0;ON;;;;;N;;;;; +2958;UPWARDS HARPOON WITH BARB LEFT TO BAR;Sm;0;ON;;;;;N;;;;; +2959;DOWNWARDS HARPOON WITH BARB LEFT TO BAR;Sm;0;ON;;;;;N;;;;; +295A;LEFTWARDS HARPOON WITH BARB UP FROM BAR;Sm;0;ON;;;;;N;;;;; +295B;RIGHTWARDS HARPOON WITH BARB UP FROM BAR;Sm;0;ON;;;;;N;;;;; +295C;UPWARDS HARPOON WITH BARB RIGHT FROM BAR;Sm;0;ON;;;;;N;;;;; +295D;DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR;Sm;0;ON;;;;;N;;;;; +295E;LEFTWARDS HARPOON WITH BARB DOWN FROM BAR;Sm;0;ON;;;;;N;;;;; +295F;RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR;Sm;0;ON;;;;;N;;;;; +2960;UPWARDS HARPOON WITH BARB LEFT FROM BAR;Sm;0;ON;;;;;N;;;;; +2961;DOWNWARDS HARPOON WITH BARB LEFT FROM BAR;Sm;0;ON;;;;;N;;;;; +2962;LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;; +2963;UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;; +2964;RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;; +2965;DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;; +2966;LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP;Sm;0;ON;;;;;N;;;;; +2967;LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;; +2968;RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP;Sm;0;ON;;;;;N;;;;; +2969;RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;; +296A;LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH;Sm;0;ON;;;;;N;;;;; +296B;LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH;Sm;0;ON;;;;;N;;;;; +296C;RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH;Sm;0;ON;;;;;N;;;;; +296D;RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH;Sm;0;ON;;;;;N;;;;; +296E;UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;; +296F;DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;; +2970;RIGHT DOUBLE ARROW WITH ROUNDED HEAD;Sm;0;ON;;;;;N;;;;; +2971;EQUALS SIGN ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2972;TILDE OPERATOR ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2973;LEFTWARDS ARROW ABOVE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;; +2974;RIGHTWARDS ARROW ABOVE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;; +2975;RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;; +2976;LESS-THAN ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2977;LEFTWARDS ARROW THROUGH LESS-THAN;Sm;0;ON;;;;;N;;;;; +2978;GREATER-THAN ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2979;SUBSET ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +297A;LEFTWARDS ARROW THROUGH SUBSET;Sm;0;ON;;;;;N;;;;; +297B;SUPERSET ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +297C;LEFT FISH TAIL;Sm;0;ON;;;;;N;;;;; +297D;RIGHT FISH TAIL;Sm;0;ON;;;;;N;;;;; +297E;UP FISH TAIL;Sm;0;ON;;;;;N;;;;; +297F;DOWN FISH TAIL;Sm;0;ON;;;;;N;;;;; +2980;TRIPLE VERTICAL BAR DELIMITER;Sm;0;ON;;;;;N;;;;; +2981;Z NOTATION SPOT;Sm;0;ON;;;;;N;;;;; +2982;Z NOTATION TYPE COLON;Sm;0;ON;;;;;N;;;;; +2983;LEFT WHITE CURLY BRACKET;Ps;0;ON;;;;;Y;;;;; +2984;RIGHT WHITE CURLY BRACKET;Pe;0;ON;;;;;Y;;;;; +2985;LEFT WHITE PARENTHESIS;Ps;0;ON;;;;;Y;;;;; +2986;RIGHT WHITE PARENTHESIS;Pe;0;ON;;;;;Y;;;;; +2987;Z NOTATION LEFT IMAGE BRACKET;Ps;0;ON;;;;;Y;;;;; +2988;Z NOTATION RIGHT IMAGE BRACKET;Pe;0;ON;;;;;Y;;;;; +2989;Z NOTATION LEFT BINDING BRACKET;Ps;0;ON;;;;;Y;;;;; +298A;Z NOTATION RIGHT BINDING BRACKET;Pe;0;ON;;;;;Y;;;;; +298B;LEFT SQUARE BRACKET WITH UNDERBAR;Ps;0;ON;;;;;Y;;;;; +298C;RIGHT SQUARE BRACKET WITH UNDERBAR;Pe;0;ON;;;;;Y;;;;; +298D;LEFT SQUARE BRACKET WITH TICK IN TOP CORNER;Ps;0;ON;;;;;Y;;;;; +298E;RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER;Pe;0;ON;;;;;Y;;;;; +298F;LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER;Ps;0;ON;;;;;Y;;;;; +2990;RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER;Pe;0;ON;;;;;Y;;;;; +2991;LEFT ANGLE BRACKET WITH DOT;Ps;0;ON;;;;;Y;;;;; +2992;RIGHT ANGLE BRACKET WITH DOT;Pe;0;ON;;;;;Y;;;;; +2993;LEFT ARC LESS-THAN BRACKET;Ps;0;ON;;;;;Y;;;;; +2994;RIGHT ARC GREATER-THAN BRACKET;Pe;0;ON;;;;;Y;;;;; +2995;DOUBLE LEFT ARC GREATER-THAN BRACKET;Ps;0;ON;;;;;Y;;;;; +2996;DOUBLE RIGHT ARC LESS-THAN BRACKET;Pe;0;ON;;;;;Y;;;;; +2997;LEFT BLACK TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;;;;; +2998;RIGHT BLACK TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;;;;; +2999;DOTTED FENCE;Sm;0;ON;;;;;N;;;;; +299A;VERTICAL ZIGZAG LINE;Sm;0;ON;;;;;N;;;;; +299B;MEASURED ANGLE OPENING LEFT;Sm;0;ON;;;;;Y;;;;; +299C;RIGHT ANGLE VARIANT WITH SQUARE;Sm;0;ON;;;;;Y;;;;; +299D;MEASURED RIGHT ANGLE WITH DOT;Sm;0;ON;;;;;Y;;;;; +299E;ANGLE WITH S INSIDE;Sm;0;ON;;;;;Y;;;;; +299F;ACUTE ANGLE;Sm;0;ON;;;;;Y;;;;; +29A0;SPHERICAL ANGLE OPENING LEFT;Sm;0;ON;;;;;Y;;;;; +29A1;SPHERICAL ANGLE OPENING UP;Sm;0;ON;;;;;Y;;;;; +29A2;TURNED ANGLE;Sm;0;ON;;;;;Y;;;;; +29A3;REVERSED ANGLE;Sm;0;ON;;;;;Y;;;;; +29A4;ANGLE WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; +29A5;REVERSED ANGLE WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; +29A6;OBLIQUE ANGLE OPENING UP;Sm;0;ON;;;;;Y;;;;; +29A7;OBLIQUE ANGLE OPENING DOWN;Sm;0;ON;;;;;Y;;;;; +29A8;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT;Sm;0;ON;;;;;Y;;;;; +29A9;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT;Sm;0;ON;;;;;Y;;;;; +29AA;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT;Sm;0;ON;;;;;Y;;;;; +29AB;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT;Sm;0;ON;;;;;Y;;;;; +29AC;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP;Sm;0;ON;;;;;Y;;;;; +29AD;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP;Sm;0;ON;;;;;Y;;;;; +29AE;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN;Sm;0;ON;;;;;Y;;;;; +29AF;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN;Sm;0;ON;;;;;Y;;;;; +29B0;REVERSED EMPTY SET;Sm;0;ON;;;;;N;;;;; +29B1;EMPTY SET WITH OVERBAR;Sm;0;ON;;;;;N;;;;; +29B2;EMPTY SET WITH SMALL CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;; +29B3;EMPTY SET WITH RIGHT ARROW ABOVE;Sm;0;ON;;;;;N;;;;; +29B4;EMPTY SET WITH LEFT ARROW ABOVE;Sm;0;ON;;;;;N;;;;; +29B5;CIRCLE WITH HORIZONTAL BAR;Sm;0;ON;;;;;N;;;;; +29B6;CIRCLED VERTICAL BAR;Sm;0;ON;;;;;N;;;;; +29B7;CIRCLED PARALLEL;Sm;0;ON;;;;;N;;;;; +29B8;CIRCLED REVERSE SOLIDUS;Sm;0;ON;;;;;Y;;;;; +29B9;CIRCLED PERPENDICULAR;Sm;0;ON;;;;;N;;;;; +29BA;CIRCLE DIVIDED BY HORIZONTAL BAR AND TOP HALF DIVIDED BY VERTICAL BAR;Sm;0;ON;;;;;N;;;;; +29BB;CIRCLE WITH SUPERIMPOSED X;Sm;0;ON;;;;;N;;;;; +29BC;CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN;Sm;0;ON;;;;;N;;;;; +29BD;UP ARROW THROUGH CIRCLE;Sm;0;ON;;;;;N;;;;; +29BE;CIRCLED WHITE BULLET;Sm;0;ON;;;;;N;;;;; +29BF;CIRCLED BULLET;Sm;0;ON;;;;;N;;;;; +29C0;CIRCLED LESS-THAN;Sm;0;ON;;;;;Y;;;;; +29C1;CIRCLED GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +29C2;CIRCLE WITH SMALL CIRCLE TO THE RIGHT;Sm;0;ON;;;;;Y;;;;; +29C3;CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT;Sm;0;ON;;;;;Y;;;;; +29C4;SQUARED RISING DIAGONAL SLASH;Sm;0;ON;;;;;Y;;;;; +29C5;SQUARED FALLING DIAGONAL SLASH;Sm;0;ON;;;;;Y;;;;; +29C6;SQUARED ASTERISK;Sm;0;ON;;;;;N;;;;; +29C7;SQUARED SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; +29C8;SQUARED SQUARE;Sm;0;ON;;;;;N;;;;; +29C9;TWO JOINED SQUARES;Sm;0;ON;;;;;Y;;;;; +29CA;TRIANGLE WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; +29CB;TRIANGLE WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; +29CC;S IN TRIANGLE;Sm;0;ON;;;;;N;;;;; +29CD;TRIANGLE WITH SERIFS AT BOTTOM;Sm;0;ON;;;;;N;;;;; +29CE;RIGHT TRIANGLE ABOVE LEFT TRIANGLE;Sm;0;ON;;;;;Y;;;;; +29CF;LEFT TRIANGLE BESIDE VERTICAL BAR;Sm;0;ON;;;;;Y;;;;; +29D0;VERTICAL BAR BESIDE RIGHT TRIANGLE;Sm;0;ON;;;;;Y;;;;; +29D1;BOWTIE WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29D2;BOWTIE WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29D3;BLACK BOWTIE;Sm;0;ON;;;;;N;;;;; +29D4;TIMES WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29D5;TIMES WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29D6;WHITE HOURGLASS;Sm;0;ON;;;;;N;;;;; +29D7;BLACK HOURGLASS;Sm;0;ON;;;;;N;;;;; +29D8;LEFT WIGGLY FENCE;Ps;0;ON;;;;;Y;;;;; +29D9;RIGHT WIGGLY FENCE;Pe;0;ON;;;;;Y;;;;; +29DA;LEFT DOUBLE WIGGLY FENCE;Ps;0;ON;;;;;Y;;;;; +29DB;RIGHT DOUBLE WIGGLY FENCE;Pe;0;ON;;;;;Y;;;;; +29DC;INCOMPLETE INFINITY;Sm;0;ON;;;;;Y;;;;; +29DD;TIE OVER INFINITY;Sm;0;ON;;;;;N;;;;; +29DE;INFINITY NEGATED WITH VERTICAL BAR;Sm;0;ON;;;;;N;;;;; +29DF;DOUBLE-ENDED MULTIMAP;Sm;0;ON;;;;;N;;;;; +29E0;SQUARE WITH CONTOURED OUTLINE;Sm;0;ON;;;;;N;;;;; +29E1;INCREASES AS;Sm;0;ON;;;;;Y;;;;; +29E2;SHUFFLE PRODUCT;Sm;0;ON;;;;;N;;;;; +29E3;EQUALS SIGN AND SLANTED PARALLEL;Sm;0;ON;;;;;Y;;;;; +29E4;EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE;Sm;0;ON;;;;;Y;;;;; +29E5;IDENTICAL TO AND SLANTED PARALLEL;Sm;0;ON;;;;;Y;;;;; +29E6;GLEICH STARK;Sm;0;ON;;;;;N;;;;; +29E7;THERMODYNAMIC;Sm;0;ON;;;;;N;;;;; +29E8;DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29E9;DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29EA;BLACK DIAMOND WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;; +29EB;BLACK LOZENGE;Sm;0;ON;;;;;N;;;;; +29EC;WHITE CIRCLE WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;; +29ED;BLACK CIRCLE WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;; +29EE;ERROR-BARRED WHITE SQUARE;Sm;0;ON;;;;;N;;;;; +29EF;ERROR-BARRED BLACK SQUARE;Sm;0;ON;;;;;N;;;;; +29F0;ERROR-BARRED WHITE DIAMOND;Sm;0;ON;;;;;N;;;;; +29F1;ERROR-BARRED BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; +29F2;ERROR-BARRED WHITE CIRCLE;Sm;0;ON;;;;;N;;;;; +29F3;ERROR-BARRED BLACK CIRCLE;Sm;0;ON;;;;;N;;;;; +29F4;RULE-DELAYED;Sm;0;ON;;;;;Y;;;;; +29F5;REVERSE SOLIDUS OPERATOR;Sm;0;ON;;;;;Y;;;;; +29F6;SOLIDUS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +29F7;REVERSE SOLIDUS WITH HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +29F8;BIG SOLIDUS;Sm;0;ON;;;;;Y;;;;; +29F9;BIG REVERSE SOLIDUS;Sm;0;ON;;;;;Y;;;;; +29FA;DOUBLE PLUS;Sm;0;ON;;;;;N;;;;; +29FB;TRIPLE PLUS;Sm;0;ON;;;;;N;;;;; +29FC;LEFT-POINTING CURVED ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;; +29FD;RIGHT-POINTING CURVED ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;; +29FE;TINY;Sm;0;ON;;;;;N;;;;; +29FF;MINY;Sm;0;ON;;;;;N;;;;; +2A00;N-ARY CIRCLED DOT OPERATOR;Sm;0;ON;;;;;N;;;;; +2A01;N-ARY CIRCLED PLUS OPERATOR;Sm;0;ON;;;;;N;;;;; +2A02;N-ARY CIRCLED TIMES OPERATOR;Sm;0;ON;;;;;N;;;;; +2A03;N-ARY UNION OPERATOR WITH DOT;Sm;0;ON;;;;;N;;;;; +2A04;N-ARY UNION OPERATOR WITH PLUS;Sm;0;ON;;;;;N;;;;; +2A05;N-ARY SQUARE INTERSECTION OPERATOR;Sm;0;ON;;;;;N;;;;; +2A06;N-ARY SQUARE UNION OPERATOR;Sm;0;ON;;;;;N;;;;; +2A07;TWO LOGICAL AND OPERATOR;Sm;0;ON;;;;;N;;;;; +2A08;TWO LOGICAL OR OPERATOR;Sm;0;ON;;;;;N;;;;; +2A09;N-ARY TIMES OPERATOR;Sm;0;ON;;;;;N;;;;; +2A0A;MODULO TWO SUM;Sm;0;ON;;;;;Y;;;;; +2A0B;SUMMATION WITH INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2A0C;QUADRUPLE INTEGRAL OPERATOR;Sm;0;ON; 222B 222B 222B 222B;;;;Y;;;;; +2A0D;FINITE PART INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2A0E;INTEGRAL WITH DOUBLE STROKE;Sm;0;ON;;;;;Y;;;;; +2A0F;INTEGRAL AVERAGE WITH SLASH;Sm;0;ON;;;;;Y;;;;; +2A10;CIRCULATION FUNCTION;Sm;0;ON;;;;;Y;;;;; +2A11;ANTICLOCKWISE INTEGRATION;Sm;0;ON;;;;;Y;;;;; +2A12;LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE;Sm;0;ON;;;;;Y;;;;; +2A13;LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE;Sm;0;ON;;;;;Y;;;;; +2A14;LINE INTEGRATION NOT INCLUDING THE POLE;Sm;0;ON;;;;;Y;;;;; +2A15;INTEGRAL AROUND A POINT OPERATOR;Sm;0;ON;;;;;Y;;;;; +2A16;QUATERNION INTEGRAL OPERATOR;Sm;0;ON;;;;;Y;;;;; +2A17;INTEGRAL WITH LEFTWARDS ARROW WITH HOOK;Sm;0;ON;;;;;Y;;;;; +2A18;INTEGRAL WITH TIMES SIGN;Sm;0;ON;;;;;Y;;;;; +2A19;INTEGRAL WITH INTERSECTION;Sm;0;ON;;;;;Y;;;;; +2A1A;INTEGRAL WITH UNION;Sm;0;ON;;;;;Y;;;;; +2A1B;INTEGRAL WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +2A1C;INTEGRAL WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; +2A1D;JOIN;Sm;0;ON;;;;;N;;;;; +2A1E;LARGE LEFT TRIANGLE OPERATOR;Sm;0;ON;;;;;Y;;;;; +2A1F;Z NOTATION SCHEMA COMPOSITION;Sm;0;ON;;;;;Y;;;;; +2A20;Z NOTATION SCHEMA PIPING;Sm;0;ON;;;;;Y;;;;; +2A21;Z NOTATION SCHEMA PROJECTION;Sm;0;ON;;;;;Y;;;;; +2A22;PLUS SIGN WITH SMALL CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;; +2A23;PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE;Sm;0;ON;;;;;N;;;;; +2A24;PLUS SIGN WITH TILDE ABOVE;Sm;0;ON;;;;;Y;;;;; +2A25;PLUS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;; +2A26;PLUS SIGN WITH TILDE BELOW;Sm;0;ON;;;;;Y;;;;; +2A27;PLUS SIGN WITH SUBSCRIPT TWO;Sm;0;ON;;;;;N;;;;; +2A28;PLUS SIGN WITH BLACK TRIANGLE;Sm;0;ON;;;;;N;;;;; +2A29;MINUS SIGN WITH COMMA ABOVE;Sm;0;ON;;;;;Y;;;;; +2A2A;MINUS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;; +2A2B;MINUS SIGN WITH FALLING DOTS;Sm;0;ON;;;;;Y;;;;; +2A2C;MINUS SIGN WITH RISING DOTS;Sm;0;ON;;;;;Y;;;;; +2A2D;PLUS SIGN IN LEFT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;; +2A2E;PLUS SIGN IN RIGHT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;; +2A2F;VECTOR OR CROSS PRODUCT;Sm;0;ON;;;;;N;;;;; +2A30;MULTIPLICATION SIGN WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; +2A31;MULTIPLICATION SIGN WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; +2A32;SEMIDIRECT PRODUCT WITH BOTTOM CLOSED;Sm;0;ON;;;;;N;;;;; +2A33;SMASH PRODUCT;Sm;0;ON;;;;;N;;;;; +2A34;MULTIPLICATION SIGN IN LEFT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;; +2A35;MULTIPLICATION SIGN IN RIGHT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;; +2A36;CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT;Sm;0;ON;;;;;N;;;;; +2A37;MULTIPLICATION SIGN IN DOUBLE CIRCLE;Sm;0;ON;;;;;N;;;;; +2A38;CIRCLED DIVISION SIGN;Sm;0;ON;;;;;N;;;;; +2A39;PLUS SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;; +2A3A;MINUS SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;; +2A3B;MULTIPLICATION SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;; +2A3C;INTERIOR PRODUCT;Sm;0;ON;;;;;Y;;;;; +2A3D;RIGHTHAND INTERIOR PRODUCT;Sm;0;ON;;;;;Y;;;;; +2A3E;Z NOTATION RELATIONAL COMPOSITION;Sm;0;ON;;;;;Y;;;;; +2A3F;AMALGAMATION OR COPRODUCT;Sm;0;ON;;;;;N;;;;; +2A40;INTERSECTION WITH DOT;Sm;0;ON;;;;;N;;;;; +2A41;UNION WITH MINUS SIGN;Sm;0;ON;;;;;N;;;;; +2A42;UNION WITH OVERBAR;Sm;0;ON;;;;;N;;;;; +2A43;INTERSECTION WITH OVERBAR;Sm;0;ON;;;;;N;;;;; +2A44;INTERSECTION WITH LOGICAL AND;Sm;0;ON;;;;;N;;;;; +2A45;UNION WITH LOGICAL OR;Sm;0;ON;;;;;N;;;;; +2A46;UNION ABOVE INTERSECTION;Sm;0;ON;;;;;N;;;;; +2A47;INTERSECTION ABOVE UNION;Sm;0;ON;;;;;N;;;;; +2A48;UNION ABOVE BAR ABOVE INTERSECTION;Sm;0;ON;;;;;N;;;;; +2A49;INTERSECTION ABOVE BAR ABOVE UNION;Sm;0;ON;;;;;N;;;;; +2A4A;UNION BESIDE AND JOINED WITH UNION;Sm;0;ON;;;;;N;;;;; +2A4B;INTERSECTION BESIDE AND JOINED WITH INTERSECTION;Sm;0;ON;;;;;N;;;;; +2A4C;CLOSED UNION WITH SERIFS;Sm;0;ON;;;;;N;;;;; +2A4D;CLOSED INTERSECTION WITH SERIFS;Sm;0;ON;;;;;N;;;;; +2A4E;DOUBLE SQUARE INTERSECTION;Sm;0;ON;;;;;N;;;;; +2A4F;DOUBLE SQUARE UNION;Sm;0;ON;;;;;N;;;;; +2A50;CLOSED UNION WITH SERIFS AND SMASH PRODUCT;Sm;0;ON;;;;;N;;;;; +2A51;LOGICAL AND WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; +2A52;LOGICAL OR WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; +2A53;DOUBLE LOGICAL AND;Sm;0;ON;;;;;N;;;;; +2A54;DOUBLE LOGICAL OR;Sm;0;ON;;;;;N;;;;; +2A55;TWO INTERSECTING LOGICAL AND;Sm;0;ON;;;;;N;;;;; +2A56;TWO INTERSECTING LOGICAL OR;Sm;0;ON;;;;;N;;;;; +2A57;SLOPING LARGE OR;Sm;0;ON;;;;;Y;;;;; +2A58;SLOPING LARGE AND;Sm;0;ON;;;;;Y;;;;; +2A59;LOGICAL OR OVERLAPPING LOGICAL AND;Sm;0;ON;;;;;N;;;;; +2A5A;LOGICAL AND WITH MIDDLE STEM;Sm;0;ON;;;;;N;;;;; +2A5B;LOGICAL OR WITH MIDDLE STEM;Sm;0;ON;;;;;N;;;;; +2A5C;LOGICAL AND WITH HORIZONTAL DASH;Sm;0;ON;;;;;N;;;;; +2A5D;LOGICAL OR WITH HORIZONTAL DASH;Sm;0;ON;;;;;N;;;;; +2A5E;LOGICAL AND WITH DOUBLE OVERBAR;Sm;0;ON;;;;;N;;;;; +2A5F;LOGICAL AND WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; +2A60;LOGICAL AND WITH DOUBLE UNDERBAR;Sm;0;ON;;;;;N;;;;; +2A61;SMALL VEE WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; +2A62;LOGICAL OR WITH DOUBLE OVERBAR;Sm;0;ON;;;;;N;;;;; +2A63;LOGICAL OR WITH DOUBLE UNDERBAR;Sm;0;ON;;;;;N;;;;; +2A64;Z NOTATION DOMAIN ANTIRESTRICTION;Sm;0;ON;;;;;Y;;;;; +2A65;Z NOTATION RANGE ANTIRESTRICTION;Sm;0;ON;;;;;Y;;;;; +2A66;EQUALS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;; +2A67;IDENTICAL WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; +2A68;TRIPLE HORIZONTAL BAR WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2A69;TRIPLE HORIZONTAL BAR WITH TRIPLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2A6A;TILDE OPERATOR WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2A6B;TILDE OPERATOR WITH RISING DOTS;Sm;0;ON;;;;;Y;;;;; +2A6C;SIMILAR MINUS SIMILAR;Sm;0;ON;;;;;Y;;;;; +2A6D;CONGRUENT WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2A6E;EQUALS WITH ASTERISK;Sm;0;ON;;;;;N;;;;; +2A6F;ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT;Sm;0;ON;;;;;Y;;;;; +2A70;APPROXIMATELY EQUAL OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2A71;EQUALS SIGN ABOVE PLUS SIGN;Sm;0;ON;;;;;N;;;;; +2A72;PLUS SIGN ABOVE EQUALS SIGN;Sm;0;ON;;;;;N;;;;; +2A73;EQUALS SIGN ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; +2A74;DOUBLE COLON EQUAL;Sm;0;ON; 003A 003A 003D;;;;Y;;;;; +2A75;TWO CONSECUTIVE EQUALS SIGNS;Sm;0;ON; 003D 003D;;;;N;;;;; +2A76;THREE CONSECUTIVE EQUALS SIGNS;Sm;0;ON; 003D 003D 003D;;;;N;;;;; +2A77;EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW;Sm;0;ON;;;;;N;;;;; +2A78;EQUIVALENT WITH FOUR DOTS ABOVE;Sm;0;ON;;;;;N;;;;; +2A79;LESS-THAN WITH CIRCLE INSIDE;Sm;0;ON;;;;;Y;;;;; +2A7A;GREATER-THAN WITH CIRCLE INSIDE;Sm;0;ON;;;;;Y;;;;; +2A7B;LESS-THAN WITH QUESTION MARK ABOVE;Sm;0;ON;;;;;Y;;;;; +2A7C;GREATER-THAN WITH QUESTION MARK ABOVE;Sm;0;ON;;;;;Y;;;;; +2A7D;LESS-THAN OR SLANTED EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2A7E;GREATER-THAN OR SLANTED EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2A7F;LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;; +2A80;GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;; +2A81;LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2A82;GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2A83;LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT;Sm;0;ON;;;;;Y;;;;; +2A84;GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT;Sm;0;ON;;;;;Y;;;;; +2A85;LESS-THAN OR APPROXIMATE;Sm;0;ON;;;;;Y;;;;; +2A86;GREATER-THAN OR APPROXIMATE;Sm;0;ON;;;;;Y;;;;; +2A87;LESS-THAN AND SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2A88;GREATER-THAN AND SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2A89;LESS-THAN AND NOT APPROXIMATE;Sm;0;ON;;;;;Y;;;;; +2A8A;GREATER-THAN AND NOT APPROXIMATE;Sm;0;ON;;;;;Y;;;;; +2A8B;LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A8C;GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A8D;LESS-THAN ABOVE SIMILAR OR EQUAL;Sm;0;ON;;;;;Y;;;;; +2A8E;GREATER-THAN ABOVE SIMILAR OR EQUAL;Sm;0;ON;;;;;Y;;;;; +2A8F;LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A90;GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A91;LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL;Sm;0;ON;;;;;Y;;;;; +2A92;GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL;Sm;0;ON;;;;;Y;;;;; +2A93;LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;; +2A94;GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;; +2A95;SLANTED EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A96;SLANTED EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A97;SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;; +2A98;SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;; +2A99;DOUBLE-LINE EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A9A;DOUBLE-LINE EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A9B;DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A9C;DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A9D;SIMILAR OR LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A9E;SIMILAR OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A9F;SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AA0;SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AA1;DOUBLE NESTED LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2AA2;DOUBLE NESTED GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2AA3;DOUBLE NESTED LESS-THAN WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; +2AA4;GREATER-THAN OVERLAPPING LESS-THAN;Sm;0;ON;;;;;N;;;;; +2AA5;GREATER-THAN BESIDE LESS-THAN;Sm;0;ON;;;;;N;;;;; +2AA6;LESS-THAN CLOSED BY CURVE;Sm;0;ON;;;;;Y;;;;; +2AA7;GREATER-THAN CLOSED BY CURVE;Sm;0;ON;;;;;Y;;;;; +2AA8;LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;; +2AA9;GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;; +2AAA;SMALLER THAN;Sm;0;ON;;;;;Y;;;;; +2AAB;LARGER THAN;Sm;0;ON;;;;;Y;;;;; +2AAC;SMALLER THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AAD;LARGER THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AAE;EQUALS SIGN WITH BUMPY ABOVE;Sm;0;ON;;;;;N;;;;; +2AAF;PRECEDES ABOVE SINGLE-LINE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AB0;SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AB1;PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB2;SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB3;PRECEDES ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AB4;SUCCEEDS ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AB5;PRECEDES ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB6;SUCCEEDS ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB7;PRECEDES ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB8;SUCCEEDS ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB9;PRECEDES ABOVE NOT ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ABA;SUCCEEDS ABOVE NOT ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ABB;DOUBLE PRECEDES;Sm;0;ON;;;;;Y;;;;; +2ABC;DOUBLE SUCCEEDS;Sm;0;ON;;;;;Y;;;;; +2ABD;SUBSET WITH DOT;Sm;0;ON;;;;;Y;;;;; +2ABE;SUPERSET WITH DOT;Sm;0;ON;;;;;Y;;;;; +2ABF;SUBSET WITH PLUS SIGN BELOW;Sm;0;ON;;;;;Y;;;;; +2AC0;SUPERSET WITH PLUS SIGN BELOW;Sm;0;ON;;;;;Y;;;;; +2AC1;SUBSET WITH MULTIPLICATION SIGN BELOW;Sm;0;ON;;;;;Y;;;;; +2AC2;SUPERSET WITH MULTIPLICATION SIGN BELOW;Sm;0;ON;;;;;Y;;;;; +2AC3;SUBSET OF OR EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2AC4;SUPERSET OF OR EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2AC5;SUBSET OF ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AC6;SUPERSET OF ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AC7;SUBSET OF ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; +2AC8;SUPERSET OF ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; +2AC9;SUBSET OF ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ACA;SUPERSET OF ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ACB;SUBSET OF ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ACC;SUPERSET OF ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ACD;SQUARE LEFT OPEN BOX OPERATOR;Sm;0;ON;;;;;Y;;;;; +2ACE;SQUARE RIGHT OPEN BOX OPERATOR;Sm;0;ON;;;;;Y;;;;; +2ACF;CLOSED SUBSET;Sm;0;ON;;;;;Y;;;;; +2AD0;CLOSED SUPERSET;Sm;0;ON;;;;;Y;;;;; +2AD1;CLOSED SUBSET OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AD2;CLOSED SUPERSET OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AD3;SUBSET ABOVE SUPERSET;Sm;0;ON;;;;;Y;;;;; +2AD4;SUPERSET ABOVE SUBSET;Sm;0;ON;;;;;Y;;;;; +2AD5;SUBSET ABOVE SUBSET;Sm;0;ON;;;;;Y;;;;; +2AD6;SUPERSET ABOVE SUPERSET;Sm;0;ON;;;;;Y;;;;; +2AD7;SUPERSET BESIDE SUBSET;Sm;0;ON;;;;;N;;;;; +2AD8;SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET;Sm;0;ON;;;;;N;;;;; +2AD9;ELEMENT OF OPENING DOWNWARDS;Sm;0;ON;;;;;N;;;;; +2ADA;PITCHFORK WITH TEE TOP;Sm;0;ON;;;;;N;;;;; +2ADB;TRANSVERSAL INTERSECTION;Sm;0;ON;;;;;N;;;;; +2ADC;FORKING;Sm;0;ON;2ADD 0338;;;;Y;;not independent;;; +2ADD;NONFORKING;Sm;0;ON;;;;;N;;independent;;; +2ADE;SHORT LEFT TACK;Sm;0;ON;;;;;Y;;;;; +2ADF;SHORT DOWN TACK;Sm;0;ON;;;;;N;;;;; +2AE0;SHORT UP TACK;Sm;0;ON;;;;;N;;;;; +2AE1;PERPENDICULAR WITH S;Sm;0;ON;;;;;N;;;;; +2AE2;VERTICAL BAR TRIPLE RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +2AE3;DOUBLE VERTICAL BAR LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +2AE4;VERTICAL BAR DOUBLE LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +2AE5;DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +2AE6;LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL;Sm;0;ON;;;;;Y;;;;; +2AE7;SHORT DOWN TACK WITH OVERBAR;Sm;0;ON;;;;;N;;;;; +2AE8;SHORT UP TACK WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; +2AE9;SHORT UP TACK ABOVE SHORT DOWN TACK;Sm;0;ON;;;;;N;;;;; +2AEA;DOUBLE DOWN TACK;Sm;0;ON;;;;;N;;;;; +2AEB;DOUBLE UP TACK;Sm;0;ON;;;;;N;;;;; +2AEC;DOUBLE STROKE NOT SIGN;Sm;0;ON;;;;;Y;;;;; +2AED;REVERSED DOUBLE STROKE NOT SIGN;Sm;0;ON;;;;;Y;;;;; +2AEE;DOES NOT DIVIDE WITH REVERSED NEGATION SLASH;Sm;0;ON;;;;;Y;;;;; +2AEF;VERTICAL LINE WITH CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;; +2AF0;VERTICAL LINE WITH CIRCLE BELOW;Sm;0;ON;;;;;N;;;;; +2AF1;DOWN TACK WITH CIRCLE BELOW;Sm;0;ON;;;;;N;;;;; +2AF2;PARALLEL WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; +2AF3;PARALLEL WITH TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; +2AF4;TRIPLE VERTICAL BAR BINARY RELATION;Sm;0;ON;;;;;N;;;;; +2AF5;TRIPLE VERTICAL BAR WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; +2AF6;TRIPLE COLON OPERATOR;Sm;0;ON;;;;;N;;;;; +2AF7;TRIPLE NESTED LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2AF8;TRIPLE NESTED GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2AF9;DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AFA;DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AFB;TRIPLE SOLIDUS BINARY RELATION;Sm;0;ON;;;;;Y;;;;; +2AFC;LARGE TRIPLE VERTICAL BAR OPERATOR;Sm;0;ON;;;;;N;;;;; +2AFD;DOUBLE SOLIDUS OPERATOR;Sm;0;ON;;;;;Y;;;;; +2AFE;WHITE VERTICAL BAR;Sm;0;ON;;;;;N;;;;; +2AFF;N-ARY WHITE VERTICAL BAR;Sm;0;ON;;;;;N;;;;; +2E80;CJK RADICAL REPEAT;So;0;ON;;;;;N;;;;; +2E81;CJK RADICAL CLIFF;So;0;ON;;;;;N;;;;; +2E82;CJK RADICAL SECOND ONE;So;0;ON;;;;;N;;;;; +2E83;CJK RADICAL SECOND TWO;So;0;ON;;;;;N;;;;; +2E84;CJK RADICAL SECOND THREE;So;0;ON;;;;;N;;;;; +2E85;CJK RADICAL PERSON;So;0;ON;;;;;N;;;;; +2E86;CJK RADICAL BOX;So;0;ON;;;;;N;;;;; +2E87;CJK RADICAL TABLE;So;0;ON;;;;;N;;;;; +2E88;CJK RADICAL KNIFE ONE;So;0;ON;;;;;N;;;;; +2E89;CJK RADICAL KNIFE TWO;So;0;ON;;;;;N;;;;; +2E8A;CJK RADICAL DIVINATION;So;0;ON;;;;;N;;;;; +2E8B;CJK RADICAL SEAL;So;0;ON;;;;;N;;;;; +2E8C;CJK RADICAL SMALL ONE;So;0;ON;;;;;N;;;;; +2E8D;CJK RADICAL SMALL TWO;So;0;ON;;;;;N;;;;; +2E8E;CJK RADICAL LAME ONE;So;0;ON;;;;;N;;;;; +2E8F;CJK RADICAL LAME TWO;So;0;ON;;;;;N;;;;; +2E90;CJK RADICAL LAME THREE;So;0;ON;;;;;N;;;;; +2E91;CJK RADICAL LAME FOUR;So;0;ON;;;;;N;;;;; +2E92;CJK RADICAL SNAKE;So;0;ON;;;;;N;;;;; +2E93;CJK RADICAL THREAD;So;0;ON;;;;;N;;;;; +2E94;CJK RADICAL SNOUT ONE;So;0;ON;;;;;N;;;;; +2E95;CJK RADICAL SNOUT TWO;So;0;ON;;;;;N;;;;; +2E96;CJK RADICAL HEART ONE;So;0;ON;;;;;N;;;;; +2E97;CJK RADICAL HEART TWO;So;0;ON;;;;;N;;;;; +2E98;CJK RADICAL HAND;So;0;ON;;;;;N;;;;; +2E99;CJK RADICAL RAP;So;0;ON;;;;;N;;;;; +2E9B;CJK RADICAL CHOKE;So;0;ON;;;;;N;;;;; +2E9C;CJK RADICAL SUN;So;0;ON;;;;;N;;;;; +2E9D;CJK RADICAL MOON;So;0;ON;;;;;N;;;;; +2E9E;CJK RADICAL DEATH;So;0;ON;;;;;N;;;;; +2E9F;CJK RADICAL MOTHER;So;0;ON; 6BCD;;;;N;;;;; +2EA0;CJK RADICAL CIVILIAN;So;0;ON;;;;;N;;;;; +2EA1;CJK RADICAL WATER ONE;So;0;ON;;;;;N;;;;; +2EA2;CJK RADICAL WATER TWO;So;0;ON;;;;;N;;;;; +2EA3;CJK RADICAL FIRE;So;0;ON;;;;;N;;;;; +2EA4;CJK RADICAL PAW ONE;So;0;ON;;;;;N;;;;; +2EA5;CJK RADICAL PAW TWO;So;0;ON;;;;;N;;;;; +2EA6;CJK RADICAL SIMPLIFIED HALF TREE TRUNK;So;0;ON;;;;;N;;;;; +2EA7;CJK RADICAL COW;So;0;ON;;;;;N;;;;; +2EA8;CJK RADICAL DOG;So;0;ON;;;;;N;;;;; +2EA9;CJK RADICAL JADE;So;0;ON;;;;;N;;;;; +2EAA;CJK RADICAL BOLT OF CLOTH;So;0;ON;;;;;N;;;;; +2EAB;CJK RADICAL EYE;So;0;ON;;;;;N;;;;; +2EAC;CJK RADICAL SPIRIT ONE;So;0;ON;;;;;N;;;;; +2EAD;CJK RADICAL SPIRIT TWO;So;0;ON;;;;;N;;;;; +2EAE;CJK RADICAL BAMBOO;So;0;ON;;;;;N;;;;; +2EAF;CJK RADICAL SILK;So;0;ON;;;;;N;;;;; +2EB0;CJK RADICAL C-SIMPLIFIED SILK;So;0;ON;;;;;N;;;;; +2EB1;CJK RADICAL NET ONE;So;0;ON;;;;;N;;;;; +2EB2;CJK RADICAL NET TWO;So;0;ON;;;;;N;;;;; +2EB3;CJK RADICAL NET THREE;So;0;ON;;;;;N;;;;; +2EB4;CJK RADICAL NET FOUR;So;0;ON;;;;;N;;;;; +2EB5;CJK RADICAL MESH;So;0;ON;;;;;N;;;;; +2EB6;CJK RADICAL SHEEP;So;0;ON;;;;;N;;;;; +2EB7;CJK RADICAL RAM;So;0;ON;;;;;N;;;;; +2EB8;CJK RADICAL EWE;So;0;ON;;;;;N;;;;; +2EB9;CJK RADICAL OLD;So;0;ON;;;;;N;;;;; +2EBA;CJK RADICAL BRUSH ONE;So;0;ON;;;;;N;;;;; +2EBB;CJK RADICAL BRUSH TWO;So;0;ON;;;;;N;;;;; +2EBC;CJK RADICAL MEAT;So;0;ON;;;;;N;;;;; +2EBD;CJK RADICAL MORTAR;So;0;ON;;;;;N;;;;; +2EBE;CJK RADICAL GRASS ONE;So;0;ON;;;;;N;;;;; +2EBF;CJK RADICAL GRASS TWO;So;0;ON;;;;;N;;;;; +2EC0;CJK RADICAL GRASS THREE;So;0;ON;;;;;N;;;;; +2EC1;CJK RADICAL TIGER;So;0;ON;;;;;N;;;;; +2EC2;CJK RADICAL CLOTHES;So;0;ON;;;;;N;;;;; +2EC3;CJK RADICAL WEST ONE;So;0;ON;;;;;N;;;;; +2EC4;CJK RADICAL WEST TWO;So;0;ON;;;;;N;;;;; +2EC5;CJK RADICAL C-SIMPLIFIED SEE;So;0;ON;;;;;N;;;;; +2EC6;CJK RADICAL SIMPLIFIED HORN;So;0;ON;;;;;N;;;;; +2EC7;CJK RADICAL HORN;So;0;ON;;;;;N;;;;; +2EC8;CJK RADICAL C-SIMPLIFIED SPEECH;So;0;ON;;;;;N;;;;; +2EC9;CJK RADICAL C-SIMPLIFIED SHELL;So;0;ON;;;;;N;;;;; +2ECA;CJK RADICAL FOOT;So;0;ON;;;;;N;;;;; +2ECB;CJK RADICAL C-SIMPLIFIED CART;So;0;ON;;;;;N;;;;; +2ECC;CJK RADICAL SIMPLIFIED WALK;So;0;ON;;;;;N;;;;; +2ECD;CJK RADICAL WALK ONE;So;0;ON;;;;;N;;;;; +2ECE;CJK RADICAL WALK TWO;So;0;ON;;;;;N;;;;; +2ECF;CJK RADICAL CITY;So;0;ON;;;;;N;;;;; +2ED0;CJK RADICAL C-SIMPLIFIED GOLD;So;0;ON;;;;;N;;;;; +2ED1;CJK RADICAL LONG ONE;So;0;ON;;;;;N;;;;; +2ED2;CJK RADICAL LONG TWO;So;0;ON;;;;;N;;;;; +2ED3;CJK RADICAL C-SIMPLIFIED LONG;So;0;ON;;;;;N;;;;; +2ED4;CJK RADICAL C-SIMPLIFIED GATE;So;0;ON;;;;;N;;;;; +2ED5;CJK RADICAL MOUND ONE;So;0;ON;;;;;N;;;;; +2ED6;CJK RADICAL MOUND TWO;So;0;ON;;;;;N;;;;; +2ED7;CJK RADICAL RAIN;So;0;ON;;;;;N;;;;; +2ED8;CJK RADICAL BLUE;So;0;ON;;;;;N;;;;; +2ED9;CJK RADICAL C-SIMPLIFIED TANNED LEATHER;So;0;ON;;;;;N;;;;; +2EDA;CJK RADICAL C-SIMPLIFIED LEAF;So;0;ON;;;;;N;;;;; +2EDB;CJK RADICAL C-SIMPLIFIED WIND;So;0;ON;;;;;N;;;;; +2EDC;CJK RADICAL C-SIMPLIFIED FLY;So;0;ON;;;;;N;;;;; +2EDD;CJK RADICAL EAT ONE;So;0;ON;;;;;N;;;;; +2EDE;CJK RADICAL EAT TWO;So;0;ON;;;;;N;;;;; +2EDF;CJK RADICAL EAT THREE;So;0;ON;;;;;N;;;;; +2EE0;CJK RADICAL C-SIMPLIFIED EAT;So;0;ON;;;;;N;;;;; +2EE1;CJK RADICAL HEAD;So;0;ON;;;;;N;;;;; +2EE2;CJK RADICAL C-SIMPLIFIED HORSE;So;0;ON;;;;;N;;;;; +2EE3;CJK RADICAL BONE;So;0;ON;;;;;N;;;;; +2EE4;CJK RADICAL GHOST;So;0;ON;;;;;N;;;;; +2EE5;CJK RADICAL C-SIMPLIFIED FISH;So;0;ON;;;;;N;;;;; +2EE6;CJK RADICAL C-SIMPLIFIED BIRD;So;0;ON;;;;;N;;;;; +2EE7;CJK RADICAL C-SIMPLIFIED SALT;So;0;ON;;;;;N;;;;; +2EE8;CJK RADICAL SIMPLIFIED WHEAT;So;0;ON;;;;;N;;;;; +2EE9;CJK RADICAL SIMPLIFIED YELLOW;So;0;ON;;;;;N;;;;; +2EEA;CJK RADICAL C-SIMPLIFIED FROG;So;0;ON;;;;;N;;;;; +2EEB;CJK RADICAL J-SIMPLIFIED EVEN;So;0;ON;;;;;N;;;;; +2EEC;CJK RADICAL C-SIMPLIFIED EVEN;So;0;ON;;;;;N;;;;; +2EED;CJK RADICAL J-SIMPLIFIED TOOTH;So;0;ON;;;;;N;;;;; +2EEE;CJK RADICAL C-SIMPLIFIED TOOTH;So;0;ON;;;;;N;;;;; +2EEF;CJK RADICAL J-SIMPLIFIED DRAGON;So;0;ON;;;;;N;;;;; +2EF0;CJK RADICAL C-SIMPLIFIED DRAGON;So;0;ON;;;;;N;;;;; +2EF1;CJK RADICAL TURTLE;So;0;ON;;;;;N;;;;; +2EF2;CJK RADICAL J-SIMPLIFIED TURTLE;So;0;ON;;;;;N;;;;; +2EF3;CJK RADICAL C-SIMPLIFIED TURTLE;So;0;ON; 9F9F;;;;N;;;;; +2F00;KANGXI RADICAL ONE;So;0;ON; 4E00;;;;N;;;;; +2F01;KANGXI RADICAL LINE;So;0;ON; 4E28;;;;N;;;;; +2F02;KANGXI RADICAL DOT;So;0;ON; 4E36;;;;N;;;;; +2F03;KANGXI RADICAL SLASH;So;0;ON; 4E3F;;;;N;;;;; +2F04;KANGXI RADICAL SECOND;So;0;ON; 4E59;;;;N;;;;; +2F05;KANGXI RADICAL HOOK;So;0;ON; 4E85;;;;N;;;;; +2F06;KANGXI RADICAL TWO;So;0;ON; 4E8C;;;;N;;;;; +2F07;KANGXI RADICAL LID;So;0;ON; 4EA0;;;;N;;;;; +2F08;KANGXI RADICAL MAN;So;0;ON; 4EBA;;;;N;;;;; +2F09;KANGXI RADICAL LEGS;So;0;ON; 513F;;;;N;;;;; +2F0A;KANGXI RADICAL ENTER;So;0;ON; 5165;;;;N;;;;; +2F0B;KANGXI RADICAL EIGHT;So;0;ON; 516B;;;;N;;;;; +2F0C;KANGXI RADICAL DOWN BOX;So;0;ON; 5182;;;;N;;;;; +2F0D;KANGXI RADICAL COVER;So;0;ON; 5196;;;;N;;;;; +2F0E;KANGXI RADICAL ICE;So;0;ON; 51AB;;;;N;;;;; +2F0F;KANGXI RADICAL TABLE;So;0;ON; 51E0;;;;N;;;;; +2F10;KANGXI RADICAL OPEN BOX;So;0;ON; 51F5;;;;N;;;;; +2F11;KANGXI RADICAL KNIFE;So;0;ON; 5200;;;;N;;;;; +2F12;KANGXI RADICAL POWER;So;0;ON; 529B;;;;N;;;;; +2F13;KANGXI RADICAL WRAP;So;0;ON; 52F9;;;;N;;;;; +2F14;KANGXI RADICAL SPOON;So;0;ON; 5315;;;;N;;;;; +2F15;KANGXI RADICAL RIGHT OPEN BOX;So;0;ON; 531A;;;;N;;;;; +2F16;KANGXI RADICAL HIDING ENCLOSURE;So;0;ON; 5338;;;;N;;;;; +2F17;KANGXI RADICAL TEN;So;0;ON; 5341;;;;N;;;;; +2F18;KANGXI RADICAL DIVINATION;So;0;ON; 535C;;;;N;;;;; +2F19;KANGXI RADICAL SEAL;So;0;ON; 5369;;;;N;;;;; +2F1A;KANGXI RADICAL CLIFF;So;0;ON; 5382;;;;N;;;;; +2F1B;KANGXI RADICAL PRIVATE;So;0;ON; 53B6;;;;N;;;;; +2F1C;KANGXI RADICAL AGAIN;So;0;ON; 53C8;;;;N;;;;; +2F1D;KANGXI RADICAL MOUTH;So;0;ON; 53E3;;;;N;;;;; +2F1E;KANGXI RADICAL ENCLOSURE;So;0;ON; 56D7;;;;N;;;;; +2F1F;KANGXI RADICAL EARTH;So;0;ON; 571F;;;;N;;;;; +2F20;KANGXI RADICAL SCHOLAR;So;0;ON; 58EB;;;;N;;;;; +2F21;KANGXI RADICAL GO;So;0;ON; 5902;;;;N;;;;; +2F22;KANGXI RADICAL GO SLOWLY;So;0;ON; 590A;;;;N;;;;; +2F23;KANGXI RADICAL EVENING;So;0;ON; 5915;;;;N;;;;; +2F24;KANGXI RADICAL BIG;So;0;ON; 5927;;;;N;;;;; +2F25;KANGXI RADICAL WOMAN;So;0;ON; 5973;;;;N;;;;; +2F26;KANGXI RADICAL CHILD;So;0;ON; 5B50;;;;N;;;;; +2F27;KANGXI RADICAL ROOF;So;0;ON; 5B80;;;;N;;;;; +2F28;KANGXI RADICAL INCH;So;0;ON; 5BF8;;;;N;;;;; +2F29;KANGXI RADICAL SMALL;So;0;ON; 5C0F;;;;N;;;;; +2F2A;KANGXI RADICAL LAME;So;0;ON; 5C22;;;;N;;;;; +2F2B;KANGXI RADICAL CORPSE;So;0;ON; 5C38;;;;N;;;;; +2F2C;KANGXI RADICAL SPROUT;So;0;ON; 5C6E;;;;N;;;;; +2F2D;KANGXI RADICAL MOUNTAIN;So;0;ON; 5C71;;;;N;;;;; +2F2E;KANGXI RADICAL RIVER;So;0;ON; 5DDB;;;;N;;;;; +2F2F;KANGXI RADICAL WORK;So;0;ON; 5DE5;;;;N;;;;; +2F30;KANGXI RADICAL ONESELF;So;0;ON; 5DF1;;;;N;;;;; +2F31;KANGXI RADICAL TURBAN;So;0;ON; 5DFE;;;;N;;;;; +2F32;KANGXI RADICAL DRY;So;0;ON; 5E72;;;;N;;;;; +2F33;KANGXI RADICAL SHORT THREAD;So;0;ON; 5E7A;;;;N;;;;; +2F34;KANGXI RADICAL DOTTED CLIFF;So;0;ON; 5E7F;;;;N;;;;; +2F35;KANGXI RADICAL LONG STRIDE;So;0;ON; 5EF4;;;;N;;;;; +2F36;KANGXI RADICAL TWO HANDS;So;0;ON; 5EFE;;;;N;;;;; +2F37;KANGXI RADICAL SHOOT;So;0;ON; 5F0B;;;;N;;;;; +2F38;KANGXI RADICAL BOW;So;0;ON; 5F13;;;;N;;;;; +2F39;KANGXI RADICAL SNOUT;So;0;ON; 5F50;;;;N;;;;; +2F3A;KANGXI RADICAL BRISTLE;So;0;ON; 5F61;;;;N;;;;; +2F3B;KANGXI RADICAL STEP;So;0;ON; 5F73;;;;N;;;;; +2F3C;KANGXI RADICAL HEART;So;0;ON; 5FC3;;;;N;;;;; +2F3D;KANGXI RADICAL HALBERD;So;0;ON; 6208;;;;N;;;;; +2F3E;KANGXI RADICAL DOOR;So;0;ON; 6236;;;;N;;;;; +2F3F;KANGXI RADICAL HAND;So;0;ON; 624B;;;;N;;;;; +2F40;KANGXI RADICAL BRANCH;So;0;ON; 652F;;;;N;;;;; +2F41;KANGXI RADICAL RAP;So;0;ON; 6534;;;;N;;;;; +2F42;KANGXI RADICAL SCRIPT;So;0;ON; 6587;;;;N;;;;; +2F43;KANGXI RADICAL DIPPER;So;0;ON; 6597;;;;N;;;;; +2F44;KANGXI RADICAL AXE;So;0;ON; 65A4;;;;N;;;;; +2F45;KANGXI RADICAL SQUARE;So;0;ON; 65B9;;;;N;;;;; +2F46;KANGXI RADICAL NOT;So;0;ON; 65E0;;;;N;;;;; +2F47;KANGXI RADICAL SUN;So;0;ON; 65E5;;;;N;;;;; +2F48;KANGXI RADICAL SAY;So;0;ON; 66F0;;;;N;;;;; +2F49;KANGXI RADICAL MOON;So;0;ON; 6708;;;;N;;;;; +2F4A;KANGXI RADICAL TREE;So;0;ON; 6728;;;;N;;;;; +2F4B;KANGXI RADICAL LACK;So;0;ON; 6B20;;;;N;;;;; +2F4C;KANGXI RADICAL STOP;So;0;ON; 6B62;;;;N;;;;; +2F4D;KANGXI RADICAL DEATH;So;0;ON; 6B79;;;;N;;;;; +2F4E;KANGXI RADICAL WEAPON;So;0;ON; 6BB3;;;;N;;;;; +2F4F;KANGXI RADICAL DO NOT;So;0;ON; 6BCB;;;;N;;;;; +2F50;KANGXI RADICAL COMPARE;So;0;ON; 6BD4;;;;N;;;;; +2F51;KANGXI RADICAL FUR;So;0;ON; 6BDB;;;;N;;;;; +2F52;KANGXI RADICAL CLAN;So;0;ON; 6C0F;;;;N;;;;; +2F53;KANGXI RADICAL STEAM;So;0;ON; 6C14;;;;N;;;;; +2F54;KANGXI RADICAL WATER;So;0;ON; 6C34;;;;N;;;;; +2F55;KANGXI RADICAL FIRE;So;0;ON; 706B;;;;N;;;;; +2F56;KANGXI RADICAL CLAW;So;0;ON; 722A;;;;N;;;;; +2F57;KANGXI RADICAL FATHER;So;0;ON; 7236;;;;N;;;;; +2F58;KANGXI RADICAL DOUBLE X;So;0;ON; 723B;;;;N;;;;; +2F59;KANGXI RADICAL HALF TREE TRUNK;So;0;ON; 723F;;;;N;;;;; +2F5A;KANGXI RADICAL SLICE;So;0;ON; 7247;;;;N;;;;; +2F5B;KANGXI RADICAL FANG;So;0;ON; 7259;;;;N;;;;; +2F5C;KANGXI RADICAL COW;So;0;ON; 725B;;;;N;;;;; +2F5D;KANGXI RADICAL DOG;So;0;ON; 72AC;;;;N;;;;; +2F5E;KANGXI RADICAL PROFOUND;So;0;ON; 7384;;;;N;;;;; +2F5F;KANGXI RADICAL JADE;So;0;ON; 7389;;;;N;;;;; +2F60;KANGXI RADICAL MELON;So;0;ON; 74DC;;;;N;;;;; +2F61;KANGXI RADICAL TILE;So;0;ON; 74E6;;;;N;;;;; +2F62;KANGXI RADICAL SWEET;So;0;ON; 7518;;;;N;;;;; +2F63;KANGXI RADICAL LIFE;So;0;ON; 751F;;;;N;;;;; +2F64;KANGXI RADICAL USE;So;0;ON; 7528;;;;N;;;;; +2F65;KANGXI RADICAL FIELD;So;0;ON; 7530;;;;N;;;;; +2F66;KANGXI RADICAL BOLT OF CLOTH;So;0;ON; 758B;;;;N;;;;; +2F67;KANGXI RADICAL SICKNESS;So;0;ON; 7592;;;;N;;;;; +2F68;KANGXI RADICAL DOTTED TENT;So;0;ON; 7676;;;;N;;;;; +2F69;KANGXI RADICAL WHITE;So;0;ON; 767D;;;;N;;;;; +2F6A;KANGXI RADICAL SKIN;So;0;ON; 76AE;;;;N;;;;; +2F6B;KANGXI RADICAL DISH;So;0;ON; 76BF;;;;N;;;;; +2F6C;KANGXI RADICAL EYE;So;0;ON; 76EE;;;;N;;;;; +2F6D;KANGXI RADICAL SPEAR;So;0;ON; 77DB;;;;N;;;;; +2F6E;KANGXI RADICAL ARROW;So;0;ON; 77E2;;;;N;;;;; +2F6F;KANGXI RADICAL STONE;So;0;ON; 77F3;;;;N;;;;; +2F70;KANGXI RADICAL SPIRIT;So;0;ON; 793A;;;;N;;;;; +2F71;KANGXI RADICAL TRACK;So;0;ON; 79B8;;;;N;;;;; +2F72;KANGXI RADICAL GRAIN;So;0;ON; 79BE;;;;N;;;;; +2F73;KANGXI RADICAL CAVE;So;0;ON; 7A74;;;;N;;;;; +2F74;KANGXI RADICAL STAND;So;0;ON; 7ACB;;;;N;;;;; +2F75;KANGXI RADICAL BAMBOO;So;0;ON; 7AF9;;;;N;;;;; +2F76;KANGXI RADICAL RICE;So;0;ON; 7C73;;;;N;;;;; +2F77;KANGXI RADICAL SILK;So;0;ON; 7CF8;;;;N;;;;; +2F78;KANGXI RADICAL JAR;So;0;ON; 7F36;;;;N;;;;; +2F79;KANGXI RADICAL NET;So;0;ON; 7F51;;;;N;;;;; +2F7A;KANGXI RADICAL SHEEP;So;0;ON; 7F8A;;;;N;;;;; +2F7B;KANGXI RADICAL FEATHER;So;0;ON; 7FBD;;;;N;;;;; +2F7C;KANGXI RADICAL OLD;So;0;ON; 8001;;;;N;;;;; +2F7D;KANGXI RADICAL AND;So;0;ON; 800C;;;;N;;;;; +2F7E;KANGXI RADICAL PLOW;So;0;ON; 8012;;;;N;;;;; +2F7F;KANGXI RADICAL EAR;So;0;ON; 8033;;;;N;;;;; +2F80;KANGXI RADICAL BRUSH;So;0;ON; 807F;;;;N;;;;; +2F81;KANGXI RADICAL MEAT;So;0;ON; 8089;;;;N;;;;; +2F82;KANGXI RADICAL MINISTER;So;0;ON; 81E3;;;;N;;;;; +2F83;KANGXI RADICAL SELF;So;0;ON; 81EA;;;;N;;;;; +2F84;KANGXI RADICAL ARRIVE;So;0;ON; 81F3;;;;N;;;;; +2F85;KANGXI RADICAL MORTAR;So;0;ON; 81FC;;;;N;;;;; +2F86;KANGXI RADICAL TONGUE;So;0;ON; 820C;;;;N;;;;; +2F87;KANGXI RADICAL OPPOSE;So;0;ON; 821B;;;;N;;;;; +2F88;KANGXI RADICAL BOAT;So;0;ON; 821F;;;;N;;;;; +2F89;KANGXI RADICAL STOPPING;So;0;ON; 826E;;;;N;;;;; +2F8A;KANGXI RADICAL COLOR;So;0;ON; 8272;;;;N;;;;; +2F8B;KANGXI RADICAL GRASS;So;0;ON; 8278;;;;N;;;;; +2F8C;KANGXI RADICAL TIGER;So;0;ON; 864D;;;;N;;;;; +2F8D;KANGXI RADICAL INSECT;So;0;ON; 866B;;;;N;;;;; +2F8E;KANGXI RADICAL BLOOD;So;0;ON; 8840;;;;N;;;;; +2F8F;KANGXI RADICAL WALK ENCLOSURE;So;0;ON; 884C;;;;N;;;;; +2F90;KANGXI RADICAL CLOTHES;So;0;ON; 8863;;;;N;;;;; +2F91;KANGXI RADICAL WEST;So;0;ON; 897E;;;;N;;;;; +2F92;KANGXI RADICAL SEE;So;0;ON; 898B;;;;N;;;;; +2F93;KANGXI RADICAL HORN;So;0;ON; 89D2;;;;N;;;;; +2F94;KANGXI RADICAL SPEECH;So;0;ON; 8A00;;;;N;;;;; +2F95;KANGXI RADICAL VALLEY;So;0;ON; 8C37;;;;N;;;;; +2F96;KANGXI RADICAL BEAN;So;0;ON; 8C46;;;;N;;;;; +2F97;KANGXI RADICAL PIG;So;0;ON; 8C55;;;;N;;;;; +2F98;KANGXI RADICAL BADGER;So;0;ON; 8C78;;;;N;;;;; +2F99;KANGXI RADICAL SHELL;So;0;ON; 8C9D;;;;N;;;;; +2F9A;KANGXI RADICAL RED;So;0;ON; 8D64;;;;N;;;;; +2F9B;KANGXI RADICAL RUN;So;0;ON; 8D70;;;;N;;;;; +2F9C;KANGXI RADICAL FOOT;So;0;ON; 8DB3;;;;N;;;;; +2F9D;KANGXI RADICAL BODY;So;0;ON; 8EAB;;;;N;;;;; +2F9E;KANGXI RADICAL CART;So;0;ON; 8ECA;;;;N;;;;; +2F9F;KANGXI RADICAL BITTER;So;0;ON; 8F9B;;;;N;;;;; +2FA0;KANGXI RADICAL MORNING;So;0;ON; 8FB0;;;;N;;;;; +2FA1;KANGXI RADICAL WALK;So;0;ON; 8FB5;;;;N;;;;; +2FA2;KANGXI RADICAL CITY;So;0;ON; 9091;;;;N;;;;; +2FA3;KANGXI RADICAL WINE;So;0;ON; 9149;;;;N;;;;; +2FA4;KANGXI RADICAL DISTINGUISH;So;0;ON; 91C6;;;;N;;;;; +2FA5;KANGXI RADICAL VILLAGE;So;0;ON; 91CC;;;;N;;;;; +2FA6;KANGXI RADICAL GOLD;So;0;ON; 91D1;;;;N;;;;; +2FA7;KANGXI RADICAL LONG;So;0;ON; 9577;;;;N;;;;; +2FA8;KANGXI RADICAL GATE;So;0;ON; 9580;;;;N;;;;; +2FA9;KANGXI RADICAL MOUND;So;0;ON; 961C;;;;N;;;;; +2FAA;KANGXI RADICAL SLAVE;So;0;ON; 96B6;;;;N;;;;; +2FAB;KANGXI RADICAL SHORT TAILED BIRD;So;0;ON; 96B9;;;;N;;;;; +2FAC;KANGXI RADICAL RAIN;So;0;ON; 96E8;;;;N;;;;; +2FAD;KANGXI RADICAL BLUE;So;0;ON; 9751;;;;N;;;;; +2FAE;KANGXI RADICAL WRONG;So;0;ON; 975E;;;;N;;;;; +2FAF;KANGXI RADICAL FACE;So;0;ON; 9762;;;;N;;;;; +2FB0;KANGXI RADICAL LEATHER;So;0;ON; 9769;;;;N;;;;; +2FB1;KANGXI RADICAL TANNED LEATHER;So;0;ON; 97CB;;;;N;;;;; +2FB2;KANGXI RADICAL LEEK;So;0;ON; 97ED;;;;N;;;;; +2FB3;KANGXI RADICAL SOUND;So;0;ON; 97F3;;;;N;;;;; +2FB4;KANGXI RADICAL LEAF;So;0;ON; 9801;;;;N;;;;; +2FB5;KANGXI RADICAL WIND;So;0;ON; 98A8;;;;N;;;;; +2FB6;KANGXI RADICAL FLY;So;0;ON; 98DB;;;;N;;;;; +2FB7;KANGXI RADICAL EAT;So;0;ON; 98DF;;;;N;;;;; +2FB8;KANGXI RADICAL HEAD;So;0;ON; 9996;;;;N;;;;; +2FB9;KANGXI RADICAL FRAGRANT;So;0;ON; 9999;;;;N;;;;; +2FBA;KANGXI RADICAL HORSE;So;0;ON; 99AC;;;;N;;;;; +2FBB;KANGXI RADICAL BONE;So;0;ON; 9AA8;;;;N;;;;; +2FBC;KANGXI RADICAL TALL;So;0;ON; 9AD8;;;;N;;;;; +2FBD;KANGXI RADICAL HAIR;So;0;ON; 9ADF;;;;N;;;;; +2FBE;KANGXI RADICAL FIGHT;So;0;ON; 9B25;;;;N;;;;; +2FBF;KANGXI RADICAL SACRIFICIAL WINE;So;0;ON; 9B2F;;;;N;;;;; +2FC0;KANGXI RADICAL CAULDRON;So;0;ON; 9B32;;;;N;;;;; +2FC1;KANGXI RADICAL GHOST;So;0;ON; 9B3C;;;;N;;;;; +2FC2;KANGXI RADICAL FISH;So;0;ON; 9B5A;;;;N;;;;; +2FC3;KANGXI RADICAL BIRD;So;0;ON; 9CE5;;;;N;;;;; +2FC4;KANGXI RADICAL SALT;So;0;ON; 9E75;;;;N;;;;; +2FC5;KANGXI RADICAL DEER;So;0;ON; 9E7F;;;;N;;;;; +2FC6;KANGXI RADICAL WHEAT;So;0;ON; 9EA5;;;;N;;;;; +2FC7;KANGXI RADICAL HEMP;So;0;ON; 9EBB;;;;N;;;;; +2FC8;KANGXI RADICAL YELLOW;So;0;ON; 9EC3;;;;N;;;;; +2FC9;KANGXI RADICAL MILLET;So;0;ON; 9ECD;;;;N;;;;; +2FCA;KANGXI RADICAL BLACK;So;0;ON; 9ED1;;;;N;;;;; +2FCB;KANGXI RADICAL EMBROIDERY;So;0;ON; 9EF9;;;;N;;;;; +2FCC;KANGXI RADICAL FROG;So;0;ON; 9EFD;;;;N;;;;; +2FCD;KANGXI RADICAL TRIPOD;So;0;ON; 9F0E;;;;N;;;;; +2FCE;KANGXI RADICAL DRUM;So;0;ON; 9F13;;;;N;;;;; +2FCF;KANGXI RADICAL RAT;So;0;ON; 9F20;;;;N;;;;; +2FD0;KANGXI RADICAL NOSE;So;0;ON; 9F3B;;;;N;;;;; +2FD1;KANGXI RADICAL EVEN;So;0;ON; 9F4A;;;;N;;;;; +2FD2;KANGXI RADICAL TOOTH;So;0;ON; 9F52;;;;N;;;;; +2FD3;KANGXI RADICAL DRAGON;So;0;ON; 9F8D;;;;N;;;;; +2FD4;KANGXI RADICAL TURTLE;So;0;ON; 9F9C;;;;N;;;;; +2FD5;KANGXI RADICAL FLUTE;So;0;ON; 9FA0;;;;N;;;;; +2FF0;IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT;So;0;ON;;;;;N;;;;; +2FF1;IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO BELOW;So;0;ON;;;;;N;;;;; +2FF2;IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO MIDDLE AND RIGHT;So;0;ON;;;;;N;;;;; +2FF3;IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO MIDDLE AND BELOW;So;0;ON;;;;;N;;;;; +2FF4;IDEOGRAPHIC DESCRIPTION CHARACTER FULL SURROUND;So;0;ON;;;;;N;;;;; +2FF5;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM ABOVE;So;0;ON;;;;;N;;;;; +2FF6;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM BELOW;So;0;ON;;;;;N;;;;; +2FF7;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LEFT;So;0;ON;;;;;N;;;;; +2FF8;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER LEFT;So;0;ON;;;;;N;;;;; +2FF9;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER RIGHT;So;0;ON;;;;;N;;;;; +2FFA;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LOWER LEFT;So;0;ON;;;;;N;;;;; +2FFB;IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID;So;0;ON;;;;;N;;;;; +3000;IDEOGRAPHIC SPACE;Zs;0;WS; 0020;;;;N;;;;; +3001;IDEOGRAPHIC COMMA;Po;0;ON;;;;;N;;;;; +3002;IDEOGRAPHIC FULL STOP;Po;0;ON;;;;;N;IDEOGRAPHIC PERIOD;;;; +3003;DITTO MARK;Po;0;ON;;;;;N;;;;; +3004;JAPANESE INDUSTRIAL STANDARD SYMBOL;So;0;ON;;;;;N;;;;; +3005;IDEOGRAPHIC ITERATION MARK;Lm;0;L;;;;;N;;;;; +3006;IDEOGRAPHIC CLOSING MARK;Lo;0;L;;;;;N;;;;; +3007;IDEOGRAPHIC NUMBER ZERO;Nl;0;L;;;;0;N;;;;; +3008;LEFT ANGLE BRACKET;Ps;0;ON;;;;;Y;OPENING ANGLE BRACKET;;;; +3009;RIGHT ANGLE BRACKET;Pe;0;ON;;;;;Y;CLOSING ANGLE BRACKET;;;; +300A;LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;;;;;Y;OPENING DOUBLE ANGLE BRACKET;;;; +300B;RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;;;;;Y;CLOSING DOUBLE ANGLE BRACKET;;;; +300C;LEFT CORNER BRACKET;Ps;0;ON;;;;;Y;OPENING CORNER BRACKET;;;; +300D;RIGHT CORNER BRACKET;Pe;0;ON;;;;;Y;CLOSING CORNER BRACKET;;;; +300E;LEFT WHITE CORNER BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE CORNER BRACKET;;;; +300F;RIGHT WHITE CORNER BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE CORNER BRACKET;;;; +3010;LEFT BLACK LENTICULAR BRACKET;Ps;0;ON;;;;;Y;OPENING BLACK LENTICULAR BRACKET;;;; +3011;RIGHT BLACK LENTICULAR BRACKET;Pe;0;ON;;;;;Y;CLOSING BLACK LENTICULAR BRACKET;;;; +3012;POSTAL MARK;So;0;ON;;;;;N;;;;; +3013;GETA MARK;So;0;ON;;;;;N;;;;; +3014;LEFT TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;OPENING TORTOISE SHELL BRACKET;;;; +3015;RIGHT TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;CLOSING TORTOISE SHELL BRACKET;;;; +3016;LEFT WHITE LENTICULAR BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE LENTICULAR BRACKET;;;; +3017;RIGHT WHITE LENTICULAR BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE LENTICULAR BRACKET;;;; +3018;LEFT WHITE TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE TORTOISE SHELL BRACKET;;;; +3019;RIGHT WHITE TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE TORTOISE SHELL BRACKET;;;; +301A;LEFT WHITE SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE SQUARE BRACKET;;;; +301B;RIGHT WHITE SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE SQUARE BRACKET;;;; +301C;WAVE DASH;Pd;0;ON;;;;;N;;;;; +301D;REVERSED DOUBLE PRIME QUOTATION MARK;Ps;0;ON;;;;;N;;;;; +301E;DOUBLE PRIME QUOTATION MARK;Pe;0;ON;;;;;N;;;;; +301F;LOW DOUBLE PRIME QUOTATION MARK;Pe;0;ON;;;;;N;;;;; +3020;POSTAL MARK FACE;So;0;ON;;;;;N;;;;; +3021;HANGZHOU NUMERAL ONE;Nl;0;L;;;;1;N;;;;; +3022;HANGZHOU NUMERAL TWO;Nl;0;L;;;;2;N;;;;; +3023;HANGZHOU NUMERAL THREE;Nl;0;L;;;;3;N;;;;; +3024;HANGZHOU NUMERAL FOUR;Nl;0;L;;;;4;N;;;;; +3025;HANGZHOU NUMERAL FIVE;Nl;0;L;;;;5;N;;;;; +3026;HANGZHOU NUMERAL SIX;Nl;0;L;;;;6;N;;;;; +3027;HANGZHOU NUMERAL SEVEN;Nl;0;L;;;;7;N;;;;; +3028;HANGZHOU NUMERAL EIGHT;Nl;0;L;;;;8;N;;;;; +3029;HANGZHOU NUMERAL NINE;Nl;0;L;;;;9;N;;;;; +302A;IDEOGRAPHIC LEVEL TONE MARK;Mn;218;NSM;;;;;N;;;;; +302B;IDEOGRAPHIC RISING TONE MARK;Mn;228;NSM;;;;;N;;;;; +302C;IDEOGRAPHIC DEPARTING TONE MARK;Mn;232;NSM;;;;;N;;;;; +302D;IDEOGRAPHIC ENTERING TONE MARK;Mn;222;NSM;;;;;N;;;;; +302E;HANGUL SINGLE DOT TONE MARK;Mn;224;NSM;;;;;N;;;;; +302F;HANGUL DOUBLE DOT TONE MARK;Mn;224;NSM;;;;;N;;;;; +3030;WAVY DASH;Pd;0;ON;;;;;N;;;;; +3031;VERTICAL KANA REPEAT MARK;Lm;0;L;;;;;N;;;;; +3032;VERTICAL KANA REPEAT WITH VOICED SOUND MARK;Lm;0;L;;;;;N;;;;; +3033;VERTICAL KANA REPEAT MARK UPPER HALF;Lm;0;L;;;;;N;;;;; +3034;VERTICAL KANA REPEAT WITH VOICED SOUND MARK UPPER HALF;Lm;0;L;;;;;N;;;;; +3035;VERTICAL KANA REPEAT MARK LOWER HALF;Lm;0;L;;;;;N;;;;; +3036;CIRCLED POSTAL MARK;So;0;ON; 3012;;;;N;;;;; +3037;IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL;So;0;ON;;;;;N;;;;; +3038;HANGZHOU NUMERAL TEN;Nl;0;L; 5341;;;10;N;;;;; +3039;HANGZHOU NUMERAL TWENTY;Nl;0;L; 5344;;;20;N;;;;; +303A;HANGZHOU NUMERAL THIRTY;Nl;0;L; 5345;;;30;N;;;;; +303B;VERTICAL IDEOGRAPHIC ITERATION MARK;Lm;0;L;;;;;N;;;;; +303C;MASU MARK;Lo;0;L;;;;;N;;;;; +303D;PART ALTERNATION MARK;Po;0;ON;;;;;N;;;;; +303E;IDEOGRAPHIC VARIATION INDICATOR;So;0;ON;;;;;N;;;;; +303F;IDEOGRAPHIC HALF FILL SPACE;So;0;ON;;;;;N;;;;; +3041;HIRAGANA LETTER SMALL A;Lo;0;L;;;;;N;;;;; +3042;HIRAGANA LETTER A;Lo;0;L;;;;;N;;;;; +3043;HIRAGANA LETTER SMALL I;Lo;0;L;;;;;N;;;;; +3044;HIRAGANA LETTER I;Lo;0;L;;;;;N;;;;; +3045;HIRAGANA LETTER SMALL U;Lo;0;L;;;;;N;;;;; +3046;HIRAGANA LETTER U;Lo;0;L;;;;;N;;;;; +3047;HIRAGANA LETTER SMALL E;Lo;0;L;;;;;N;;;;; +3048;HIRAGANA LETTER E;Lo;0;L;;;;;N;;;;; +3049;HIRAGANA LETTER SMALL O;Lo;0;L;;;;;N;;;;; +304A;HIRAGANA LETTER O;Lo;0;L;;;;;N;;;;; +304B;HIRAGANA LETTER KA;Lo;0;L;;;;;N;;;;; +304C;HIRAGANA LETTER GA;Lo;0;L;304B 3099;;;;N;;;;; +304D;HIRAGANA LETTER KI;Lo;0;L;;;;;N;;;;; +304E;HIRAGANA LETTER GI;Lo;0;L;304D 3099;;;;N;;;;; +304F;HIRAGANA LETTER KU;Lo;0;L;;;;;N;;;;; +3050;HIRAGANA LETTER GU;Lo;0;L;304F 3099;;;;N;;;;; +3051;HIRAGANA LETTER KE;Lo;0;L;;;;;N;;;;; +3052;HIRAGANA LETTER GE;Lo;0;L;3051 3099;;;;N;;;;; +3053;HIRAGANA LETTER KO;Lo;0;L;;;;;N;;;;; +3054;HIRAGANA LETTER GO;Lo;0;L;3053 3099;;;;N;;;;; +3055;HIRAGANA LETTER SA;Lo;0;L;;;;;N;;;;; +3056;HIRAGANA LETTER ZA;Lo;0;L;3055 3099;;;;N;;;;; +3057;HIRAGANA LETTER SI;Lo;0;L;;;;;N;;;;; +3058;HIRAGANA LETTER ZI;Lo;0;L;3057 3099;;;;N;;;;; +3059;HIRAGANA LETTER SU;Lo;0;L;;;;;N;;;;; +305A;HIRAGANA LETTER ZU;Lo;0;L;3059 3099;;;;N;;;;; +305B;HIRAGANA LETTER SE;Lo;0;L;;;;;N;;;;; +305C;HIRAGANA LETTER ZE;Lo;0;L;305B 3099;;;;N;;;;; +305D;HIRAGANA LETTER SO;Lo;0;L;;;;;N;;;;; +305E;HIRAGANA LETTER ZO;Lo;0;L;305D 3099;;;;N;;;;; +305F;HIRAGANA LETTER TA;Lo;0;L;;;;;N;;;;; +3060;HIRAGANA LETTER DA;Lo;0;L;305F 3099;;;;N;;;;; +3061;HIRAGANA LETTER TI;Lo;0;L;;;;;N;;;;; +3062;HIRAGANA LETTER DI;Lo;0;L;3061 3099;;;;N;;;;; +3063;HIRAGANA LETTER SMALL TU;Lo;0;L;;;;;N;;;;; +3064;HIRAGANA LETTER TU;Lo;0;L;;;;;N;;;;; +3065;HIRAGANA LETTER DU;Lo;0;L;3064 3099;;;;N;;;;; +3066;HIRAGANA LETTER TE;Lo;0;L;;;;;N;;;;; +3067;HIRAGANA LETTER DE;Lo;0;L;3066 3099;;;;N;;;;; +3068;HIRAGANA LETTER TO;Lo;0;L;;;;;N;;;;; +3069;HIRAGANA LETTER DO;Lo;0;L;3068 3099;;;;N;;;;; +306A;HIRAGANA LETTER NA;Lo;0;L;;;;;N;;;;; +306B;HIRAGANA LETTER NI;Lo;0;L;;;;;N;;;;; +306C;HIRAGANA LETTER NU;Lo;0;L;;;;;N;;;;; +306D;HIRAGANA LETTER NE;Lo;0;L;;;;;N;;;;; +306E;HIRAGANA LETTER NO;Lo;0;L;;;;;N;;;;; +306F;HIRAGANA LETTER HA;Lo;0;L;;;;;N;;;;; +3070;HIRAGANA LETTER BA;Lo;0;L;306F 3099;;;;N;;;;; +3071;HIRAGANA LETTER PA;Lo;0;L;306F 309A;;;;N;;;;; +3072;HIRAGANA LETTER HI;Lo;0;L;;;;;N;;;;; +3073;HIRAGANA LETTER BI;Lo;0;L;3072 3099;;;;N;;;;; +3074;HIRAGANA LETTER PI;Lo;0;L;3072 309A;;;;N;;;;; +3075;HIRAGANA LETTER HU;Lo;0;L;;;;;N;;;;; +3076;HIRAGANA LETTER BU;Lo;0;L;3075 3099;;;;N;;;;; +3077;HIRAGANA LETTER PU;Lo;0;L;3075 309A;;;;N;;;;; +3078;HIRAGANA LETTER HE;Lo;0;L;;;;;N;;;;; +3079;HIRAGANA LETTER BE;Lo;0;L;3078 3099;;;;N;;;;; +307A;HIRAGANA LETTER PE;Lo;0;L;3078 309A;;;;N;;;;; +307B;HIRAGANA LETTER HO;Lo;0;L;;;;;N;;;;; +307C;HIRAGANA LETTER BO;Lo;0;L;307B 3099;;;;N;;;;; +307D;HIRAGANA LETTER PO;Lo;0;L;307B 309A;;;;N;;;;; +307E;HIRAGANA LETTER MA;Lo;0;L;;;;;N;;;;; +307F;HIRAGANA LETTER MI;Lo;0;L;;;;;N;;;;; +3080;HIRAGANA LETTER MU;Lo;0;L;;;;;N;;;;; +3081;HIRAGANA LETTER ME;Lo;0;L;;;;;N;;;;; +3082;HIRAGANA LETTER MO;Lo;0;L;;;;;N;;;;; +3083;HIRAGANA LETTER SMALL YA;Lo;0;L;;;;;N;;;;; +3084;HIRAGANA LETTER YA;Lo;0;L;;;;;N;;;;; +3085;HIRAGANA LETTER SMALL YU;Lo;0;L;;;;;N;;;;; +3086;HIRAGANA LETTER YU;Lo;0;L;;;;;N;;;;; +3087;HIRAGANA LETTER SMALL YO;Lo;0;L;;;;;N;;;;; +3088;HIRAGANA LETTER YO;Lo;0;L;;;;;N;;;;; +3089;HIRAGANA LETTER RA;Lo;0;L;;;;;N;;;;; +308A;HIRAGANA LETTER RI;Lo;0;L;;;;;N;;;;; +308B;HIRAGANA LETTER RU;Lo;0;L;;;;;N;;;;; +308C;HIRAGANA LETTER RE;Lo;0;L;;;;;N;;;;; +308D;HIRAGANA LETTER RO;Lo;0;L;;;;;N;;;;; +308E;HIRAGANA LETTER SMALL WA;Lo;0;L;;;;;N;;;;; +308F;HIRAGANA LETTER WA;Lo;0;L;;;;;N;;;;; +3090;HIRAGANA LETTER WI;Lo;0;L;;;;;N;;;;; +3091;HIRAGANA LETTER WE;Lo;0;L;;;;;N;;;;; +3092;HIRAGANA LETTER WO;Lo;0;L;;;;;N;;;;; +3093;HIRAGANA LETTER N;Lo;0;L;;;;;N;;;;; +3094;HIRAGANA LETTER VU;Lo;0;L;3046 3099;;;;N;;;;; +3095;HIRAGANA LETTER SMALL KA;Lo;0;L;;;;;N;;;;; +3096;HIRAGANA LETTER SMALL KE;Lo;0;L;;;;;N;;;;; +3099;COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK;Mn;8;NSM;;;;;N;NON-SPACING KATAKANA-HIRAGANA VOICED SOUND MARK;;;; +309A;COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;Mn;8;NSM;;;;;N;NON-SPACING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;;;; +309B;KATAKANA-HIRAGANA VOICED SOUND MARK;Sk;0;ON; 0020 3099;;;;N;;;;; +309C;KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;Sk;0;ON; 0020 309A;;;;N;;;;; +309D;HIRAGANA ITERATION MARK;Lm;0;L;;;;;N;;;;; +309E;HIRAGANA VOICED ITERATION MARK;Lm;0;L;309D 3099;;;;N;;;;; +309F;HIRAGANA DIGRAPH YORI;Lo;0;L; 3088 308A;;;;N;;;;; +30A0;KATAKANA-HIRAGANA DOUBLE HYPHEN;Pd;0;ON;;;;;N;;;;; +30A1;KATAKANA LETTER SMALL A;Lo;0;L;;;;;N;;;;; +30A2;KATAKANA LETTER A;Lo;0;L;;;;;N;;;;; +30A3;KATAKANA LETTER SMALL I;Lo;0;L;;;;;N;;;;; +30A4;KATAKANA LETTER I;Lo;0;L;;;;;N;;;;; +30A5;KATAKANA LETTER SMALL U;Lo;0;L;;;;;N;;;;; +30A6;KATAKANA LETTER U;Lo;0;L;;;;;N;;;;; +30A7;KATAKANA LETTER SMALL E;Lo;0;L;;;;;N;;;;; +30A8;KATAKANA LETTER E;Lo;0;L;;;;;N;;;;; +30A9;KATAKANA LETTER SMALL O;Lo;0;L;;;;;N;;;;; +30AA;KATAKANA LETTER O;Lo;0;L;;;;;N;;;;; +30AB;KATAKANA LETTER KA;Lo;0;L;;;;;N;;;;; +30AC;KATAKANA LETTER GA;Lo;0;L;30AB 3099;;;;N;;;;; +30AD;KATAKANA LETTER KI;Lo;0;L;;;;;N;;;;; +30AE;KATAKANA LETTER GI;Lo;0;L;30AD 3099;;;;N;;;;; +30AF;KATAKANA LETTER KU;Lo;0;L;;;;;N;;;;; +30B0;KATAKANA LETTER GU;Lo;0;L;30AF 3099;;;;N;;;;; +30B1;KATAKANA LETTER KE;Lo;0;L;;;;;N;;;;; +30B2;KATAKANA LETTER GE;Lo;0;L;30B1 3099;;;;N;;;;; +30B3;KATAKANA LETTER KO;Lo;0;L;;;;;N;;;;; +30B4;KATAKANA LETTER GO;Lo;0;L;30B3 3099;;;;N;;;;; +30B5;KATAKANA LETTER SA;Lo;0;L;;;;;N;;;;; +30B6;KATAKANA LETTER ZA;Lo;0;L;30B5 3099;;;;N;;;;; +30B7;KATAKANA LETTER SI;Lo;0;L;;;;;N;;;;; +30B8;KATAKANA LETTER ZI;Lo;0;L;30B7 3099;;;;N;;;;; +30B9;KATAKANA LETTER SU;Lo;0;L;;;;;N;;;;; +30BA;KATAKANA LETTER ZU;Lo;0;L;30B9 3099;;;;N;;;;; +30BB;KATAKANA LETTER SE;Lo;0;L;;;;;N;;;;; +30BC;KATAKANA LETTER ZE;Lo;0;L;30BB 3099;;;;N;;;;; +30BD;KATAKANA LETTER SO;Lo;0;L;;;;;N;;;;; +30BE;KATAKANA LETTER ZO;Lo;0;L;30BD 3099;;;;N;;;;; +30BF;KATAKANA LETTER TA;Lo;0;L;;;;;N;;;;; +30C0;KATAKANA LETTER DA;Lo;0;L;30BF 3099;;;;N;;;;; +30C1;KATAKANA LETTER TI;Lo;0;L;;;;;N;;;;; +30C2;KATAKANA LETTER DI;Lo;0;L;30C1 3099;;;;N;;;;; +30C3;KATAKANA LETTER SMALL TU;Lo;0;L;;;;;N;;;;; +30C4;KATAKANA LETTER TU;Lo;0;L;;;;;N;;;;; +30C5;KATAKANA LETTER DU;Lo;0;L;30C4 3099;;;;N;;;;; +30C6;KATAKANA LETTER TE;Lo;0;L;;;;;N;;;;; +30C7;KATAKANA LETTER DE;Lo;0;L;30C6 3099;;;;N;;;;; +30C8;KATAKANA LETTER TO;Lo;0;L;;;;;N;;;;; +30C9;KATAKANA LETTER DO;Lo;0;L;30C8 3099;;;;N;;;;; +30CA;KATAKANA LETTER NA;Lo;0;L;;;;;N;;;;; +30CB;KATAKANA LETTER NI;Lo;0;L;;;;;N;;;;; +30CC;KATAKANA LETTER NU;Lo;0;L;;;;;N;;;;; +30CD;KATAKANA LETTER NE;Lo;0;L;;;;;N;;;;; +30CE;KATAKANA LETTER NO;Lo;0;L;;;;;N;;;;; +30CF;KATAKANA LETTER HA;Lo;0;L;;;;;N;;;;; +30D0;KATAKANA LETTER BA;Lo;0;L;30CF 3099;;;;N;;;;; +30D1;KATAKANA LETTER PA;Lo;0;L;30CF 309A;;;;N;;;;; +30D2;KATAKANA LETTER HI;Lo;0;L;;;;;N;;;;; +30D3;KATAKANA LETTER BI;Lo;0;L;30D2 3099;;;;N;;;;; +30D4;KATAKANA LETTER PI;Lo;0;L;30D2 309A;;;;N;;;;; +30D5;KATAKANA LETTER HU;Lo;0;L;;;;;N;;;;; +30D6;KATAKANA LETTER BU;Lo;0;L;30D5 3099;;;;N;;;;; +30D7;KATAKANA LETTER PU;Lo;0;L;30D5 309A;;;;N;;;;; +30D8;KATAKANA LETTER HE;Lo;0;L;;;;;N;;;;; +30D9;KATAKANA LETTER BE;Lo;0;L;30D8 3099;;;;N;;;;; +30DA;KATAKANA LETTER PE;Lo;0;L;30D8 309A;;;;N;;;;; +30DB;KATAKANA LETTER HO;Lo;0;L;;;;;N;;;;; +30DC;KATAKANA LETTER BO;Lo;0;L;30DB 3099;;;;N;;;;; +30DD;KATAKANA LETTER PO;Lo;0;L;30DB 309A;;;;N;;;;; +30DE;KATAKANA LETTER MA;Lo;0;L;;;;;N;;;;; +30DF;KATAKANA LETTER MI;Lo;0;L;;;;;N;;;;; +30E0;KATAKANA LETTER MU;Lo;0;L;;;;;N;;;;; +30E1;KATAKANA LETTER ME;Lo;0;L;;;;;N;;;;; +30E2;KATAKANA LETTER MO;Lo;0;L;;;;;N;;;;; +30E3;KATAKANA LETTER SMALL YA;Lo;0;L;;;;;N;;;;; +30E4;KATAKANA LETTER YA;Lo;0;L;;;;;N;;;;; +30E5;KATAKANA LETTER SMALL YU;Lo;0;L;;;;;N;;;;; +30E6;KATAKANA LETTER YU;Lo;0;L;;;;;N;;;;; +30E7;KATAKANA LETTER SMALL YO;Lo;0;L;;;;;N;;;;; +30E8;KATAKANA LETTER YO;Lo;0;L;;;;;N;;;;; +30E9;KATAKANA LETTER RA;Lo;0;L;;;;;N;;;;; +30EA;KATAKANA LETTER RI;Lo;0;L;;;;;N;;;;; +30EB;KATAKANA LETTER RU;Lo;0;L;;;;;N;;;;; +30EC;KATAKANA LETTER RE;Lo;0;L;;;;;N;;;;; +30ED;KATAKANA LETTER RO;Lo;0;L;;;;;N;;;;; +30EE;KATAKANA LETTER SMALL WA;Lo;0;L;;;;;N;;;;; +30EF;KATAKANA LETTER WA;Lo;0;L;;;;;N;;;;; +30F0;KATAKANA LETTER WI;Lo;0;L;;;;;N;;;;; +30F1;KATAKANA LETTER WE;Lo;0;L;;;;;N;;;;; +30F2;KATAKANA LETTER WO;Lo;0;L;;;;;N;;;;; +30F3;KATAKANA LETTER N;Lo;0;L;;;;;N;;;;; +30F4;KATAKANA LETTER VU;Lo;0;L;30A6 3099;;;;N;;;;; +30F5;KATAKANA LETTER SMALL KA;Lo;0;L;;;;;N;;;;; +30F6;KATAKANA LETTER SMALL KE;Lo;0;L;;;;;N;;;;; +30F7;KATAKANA LETTER VA;Lo;0;L;30EF 3099;;;;N;;;;; +30F8;KATAKANA LETTER VI;Lo;0;L;30F0 3099;;;;N;;;;; +30F9;KATAKANA LETTER VE;Lo;0;L;30F1 3099;;;;N;;;;; +30FA;KATAKANA LETTER VO;Lo;0;L;30F2 3099;;;;N;;;;; +30FB;KATAKANA MIDDLE DOT;Pc;0;ON;;;;;N;;;;; +30FC;KATAKANA-HIRAGANA PROLONGED SOUND MARK;Lm;0;L;;;;;N;;;;; +30FD;KATAKANA ITERATION MARK;Lm;0;L;;;;;N;;;;; +30FE;KATAKANA VOICED ITERATION MARK;Lm;0;L;30FD 3099;;;;N;;;;; +30FF;KATAKANA DIGRAPH KOTO;Lo;0;L; 30B3 30C8;;;;N;;;;; +3105;BOPOMOFO LETTER B;Lo;0;L;;;;;N;;;;; +3106;BOPOMOFO LETTER P;Lo;0;L;;;;;N;;;;; +3107;BOPOMOFO LETTER M;Lo;0;L;;;;;N;;;;; +3108;BOPOMOFO LETTER F;Lo;0;L;;;;;N;;;;; +3109;BOPOMOFO LETTER D;Lo;0;L;;;;;N;;;;; +310A;BOPOMOFO LETTER T;Lo;0;L;;;;;N;;;;; +310B;BOPOMOFO LETTER N;Lo;0;L;;;;;N;;;;; +310C;BOPOMOFO LETTER L;Lo;0;L;;;;;N;;;;; +310D;BOPOMOFO LETTER G;Lo;0;L;;;;;N;;;;; +310E;BOPOMOFO LETTER K;Lo;0;L;;;;;N;;;;; +310F;BOPOMOFO LETTER H;Lo;0;L;;;;;N;;;;; +3110;BOPOMOFO LETTER J;Lo;0;L;;;;;N;;;;; +3111;BOPOMOFO LETTER Q;Lo;0;L;;;;;N;;;;; +3112;BOPOMOFO LETTER X;Lo;0;L;;;;;N;;;;; +3113;BOPOMOFO LETTER ZH;Lo;0;L;;;;;N;;;;; +3114;BOPOMOFO LETTER CH;Lo;0;L;;;;;N;;;;; +3115;BOPOMOFO LETTER SH;Lo;0;L;;;;;N;;;;; +3116;BOPOMOFO LETTER R;Lo;0;L;;;;;N;;;;; +3117;BOPOMOFO LETTER Z;Lo;0;L;;;;;N;;;;; +3118;BOPOMOFO LETTER C;Lo;0;L;;;;;N;;;;; +3119;BOPOMOFO LETTER S;Lo;0;L;;;;;N;;;;; +311A;BOPOMOFO LETTER A;Lo;0;L;;;;;N;;;;; +311B;BOPOMOFO LETTER O;Lo;0;L;;;;;N;;;;; +311C;BOPOMOFO LETTER E;Lo;0;L;;;;;N;;;;; +311D;BOPOMOFO LETTER EH;Lo;0;L;;;;;N;;;;; +311E;BOPOMOFO LETTER AI;Lo;0;L;;;;;N;;;;; +311F;BOPOMOFO LETTER EI;Lo;0;L;;;;;N;;;;; +3120;BOPOMOFO LETTER AU;Lo;0;L;;;;;N;;;;; +3121;BOPOMOFO LETTER OU;Lo;0;L;;;;;N;;;;; +3122;BOPOMOFO LETTER AN;Lo;0;L;;;;;N;;;;; +3123;BOPOMOFO LETTER EN;Lo;0;L;;;;;N;;;;; +3124;BOPOMOFO LETTER ANG;Lo;0;L;;;;;N;;;;; +3125;BOPOMOFO LETTER ENG;Lo;0;L;;;;;N;;;;; +3126;BOPOMOFO LETTER ER;Lo;0;L;;;;;N;;;;; +3127;BOPOMOFO LETTER I;Lo;0;L;;;;;N;;;;; +3128;BOPOMOFO LETTER U;Lo;0;L;;;;;N;;;;; +3129;BOPOMOFO LETTER IU;Lo;0;L;;;;;N;;;;; +312A;BOPOMOFO LETTER V;Lo;0;L;;;;;N;;;;; +312B;BOPOMOFO LETTER NG;Lo;0;L;;;;;N;;;;; +312C;BOPOMOFO LETTER GN;Lo;0;L;;;;;N;;;;; +3131;HANGUL LETTER KIYEOK;Lo;0;L; 1100;;;;N;HANGUL LETTER GIYEOG;;;; +3132;HANGUL LETTER SSANGKIYEOK;Lo;0;L; 1101;;;;N;HANGUL LETTER SSANG GIYEOG;;;; +3133;HANGUL LETTER KIYEOK-SIOS;Lo;0;L; 11AA;;;;N;HANGUL LETTER GIYEOG SIOS;;;; +3134;HANGUL LETTER NIEUN;Lo;0;L; 1102;;;;N;;;;; +3135;HANGUL LETTER NIEUN-CIEUC;Lo;0;L; 11AC;;;;N;HANGUL LETTER NIEUN JIEUJ;;;; +3136;HANGUL LETTER NIEUN-HIEUH;Lo;0;L; 11AD;;;;N;HANGUL LETTER NIEUN HIEUH;;;; +3137;HANGUL LETTER TIKEUT;Lo;0;L; 1103;;;;N;HANGUL LETTER DIGEUD;;;; +3138;HANGUL LETTER SSANGTIKEUT;Lo;0;L; 1104;;;;N;HANGUL LETTER SSANG DIGEUD;;;; +3139;HANGUL LETTER RIEUL;Lo;0;L; 1105;;;;N;HANGUL LETTER LIEUL;;;; +313A;HANGUL LETTER RIEUL-KIYEOK;Lo;0;L; 11B0;;;;N;HANGUL LETTER LIEUL GIYEOG;;;; +313B;HANGUL LETTER RIEUL-MIEUM;Lo;0;L; 11B1;;;;N;HANGUL LETTER LIEUL MIEUM;;;; +313C;HANGUL LETTER RIEUL-PIEUP;Lo;0;L; 11B2;;;;N;HANGUL LETTER LIEUL BIEUB;;;; +313D;HANGUL LETTER RIEUL-SIOS;Lo;0;L; 11B3;;;;N;HANGUL LETTER LIEUL SIOS;;;; +313E;HANGUL LETTER RIEUL-THIEUTH;Lo;0;L; 11B4;;;;N;HANGUL LETTER LIEUL TIEUT;;;; +313F;HANGUL LETTER RIEUL-PHIEUPH;Lo;0;L; 11B5;;;;N;HANGUL LETTER LIEUL PIEUP;;;; +3140;HANGUL LETTER RIEUL-HIEUH;Lo;0;L; 111A;;;;N;HANGUL LETTER LIEUL HIEUH;;;; +3141;HANGUL LETTER MIEUM;Lo;0;L; 1106;;;;N;;;;; +3142;HANGUL LETTER PIEUP;Lo;0;L; 1107;;;;N;HANGUL LETTER BIEUB;;;; +3143;HANGUL LETTER SSANGPIEUP;Lo;0;L; 1108;;;;N;HANGUL LETTER SSANG BIEUB;;;; +3144;HANGUL LETTER PIEUP-SIOS;Lo;0;L; 1121;;;;N;HANGUL LETTER BIEUB SIOS;;;; +3145;HANGUL LETTER SIOS;Lo;0;L; 1109;;;;N;;;;; +3146;HANGUL LETTER SSANGSIOS;Lo;0;L; 110A;;;;N;HANGUL LETTER SSANG SIOS;;;; +3147;HANGUL LETTER IEUNG;Lo;0;L; 110B;;;;N;;;;; +3148;HANGUL LETTER CIEUC;Lo;0;L; 110C;;;;N;HANGUL LETTER JIEUJ;;;; +3149;HANGUL LETTER SSANGCIEUC;Lo;0;L; 110D;;;;N;HANGUL LETTER SSANG JIEUJ;;;; +314A;HANGUL LETTER CHIEUCH;Lo;0;L; 110E;;;;N;HANGUL LETTER CIEUC;;;; +314B;HANGUL LETTER KHIEUKH;Lo;0;L; 110F;;;;N;HANGUL LETTER KIYEOK;;;; +314C;HANGUL LETTER THIEUTH;Lo;0;L; 1110;;;;N;HANGUL LETTER TIEUT;;;; +314D;HANGUL LETTER PHIEUPH;Lo;0;L; 1111;;;;N;HANGUL LETTER PIEUP;;;; +314E;HANGUL LETTER HIEUH;Lo;0;L; 1112;;;;N;;;;; +314F;HANGUL LETTER A;Lo;0;L; 1161;;;;N;;;;; +3150;HANGUL LETTER AE;Lo;0;L; 1162;;;;N;;;;; +3151;HANGUL LETTER YA;Lo;0;L; 1163;;;;N;;;;; +3152;HANGUL LETTER YAE;Lo;0;L; 1164;;;;N;;;;; +3153;HANGUL LETTER EO;Lo;0;L; 1165;;;;N;;;;; +3154;HANGUL LETTER E;Lo;0;L; 1166;;;;N;;;;; +3155;HANGUL LETTER YEO;Lo;0;L; 1167;;;;N;;;;; +3156;HANGUL LETTER YE;Lo;0;L; 1168;;;;N;;;;; +3157;HANGUL LETTER O;Lo;0;L; 1169;;;;N;;;;; +3158;HANGUL LETTER WA;Lo;0;L; 116A;;;;N;;;;; +3159;HANGUL LETTER WAE;Lo;0;L; 116B;;;;N;;;;; +315A;HANGUL LETTER OE;Lo;0;L; 116C;;;;N;;;;; +315B;HANGUL LETTER YO;Lo;0;L; 116D;;;;N;;;;; +315C;HANGUL LETTER U;Lo;0;L; 116E;;;;N;;;;; +315D;HANGUL LETTER WEO;Lo;0;L; 116F;;;;N;;;;; +315E;HANGUL LETTER WE;Lo;0;L; 1170;;;;N;;;;; +315F;HANGUL LETTER WI;Lo;0;L; 1171;;;;N;;;;; +3160;HANGUL LETTER YU;Lo;0;L; 1172;;;;N;;;;; +3161;HANGUL LETTER EU;Lo;0;L; 1173;;;;N;;;;; +3162;HANGUL LETTER YI;Lo;0;L; 1174;;;;N;;;;; +3163;HANGUL LETTER I;Lo;0;L; 1175;;;;N;;;;; +3164;HANGUL FILLER;Lo;0;L; 1160;;;;N;HANGUL CAE OM;;;; +3165;HANGUL LETTER SSANGNIEUN;Lo;0;L; 1114;;;;N;HANGUL LETTER SSANG NIEUN;;;; +3166;HANGUL LETTER NIEUN-TIKEUT;Lo;0;L; 1115;;;;N;HANGUL LETTER NIEUN DIGEUD;;;; +3167;HANGUL LETTER NIEUN-SIOS;Lo;0;L; 11C7;;;;N;HANGUL LETTER NIEUN SIOS;;;; +3168;HANGUL LETTER NIEUN-PANSIOS;Lo;0;L; 11C8;;;;N;HANGUL LETTER NIEUN BAN CHI EUM;;;; +3169;HANGUL LETTER RIEUL-KIYEOK-SIOS;Lo;0;L; 11CC;;;;N;HANGUL LETTER LIEUL GIYEOG SIOS;;;; +316A;HANGUL LETTER RIEUL-TIKEUT;Lo;0;L; 11CE;;;;N;HANGUL LETTER LIEUL DIGEUD;;;; +316B;HANGUL LETTER RIEUL-PIEUP-SIOS;Lo;0;L; 11D3;;;;N;HANGUL LETTER LIEUL BIEUB SIOS;;;; +316C;HANGUL LETTER RIEUL-PANSIOS;Lo;0;L; 11D7;;;;N;HANGUL LETTER LIEUL BAN CHI EUM;;;; +316D;HANGUL LETTER RIEUL-YEORINHIEUH;Lo;0;L; 11D9;;;;N;HANGUL LETTER LIEUL YEOLIN HIEUH;;;; +316E;HANGUL LETTER MIEUM-PIEUP;Lo;0;L; 111C;;;;N;HANGUL LETTER MIEUM BIEUB;;;; +316F;HANGUL LETTER MIEUM-SIOS;Lo;0;L; 11DD;;;;N;HANGUL LETTER MIEUM SIOS;;;; +3170;HANGUL LETTER MIEUM-PANSIOS;Lo;0;L; 11DF;;;;N;HANGUL LETTER BIEUB BAN CHI EUM;;;; +3171;HANGUL LETTER KAPYEOUNMIEUM;Lo;0;L; 111D;;;;N;HANGUL LETTER MIEUM SUN GYEONG EUM;;;; +3172;HANGUL LETTER PIEUP-KIYEOK;Lo;0;L; 111E;;;;N;HANGUL LETTER BIEUB GIYEOG;;;; +3173;HANGUL LETTER PIEUP-TIKEUT;Lo;0;L; 1120;;;;N;HANGUL LETTER BIEUB DIGEUD;;;; +3174;HANGUL LETTER PIEUP-SIOS-KIYEOK;Lo;0;L; 1122;;;;N;HANGUL LETTER BIEUB SIOS GIYEOG;;;; +3175;HANGUL LETTER PIEUP-SIOS-TIKEUT;Lo;0;L; 1123;;;;N;HANGUL LETTER BIEUB SIOS DIGEUD;;;; +3176;HANGUL LETTER PIEUP-CIEUC;Lo;0;L; 1127;;;;N;HANGUL LETTER BIEUB JIEUJ;;;; +3177;HANGUL LETTER PIEUP-THIEUTH;Lo;0;L; 1129;;;;N;HANGUL LETTER BIEUB TIEUT;;;; +3178;HANGUL LETTER KAPYEOUNPIEUP;Lo;0;L; 112B;;;;N;HANGUL LETTER BIEUB SUN GYEONG EUM;;;; +3179;HANGUL LETTER KAPYEOUNSSANGPIEUP;Lo;0;L; 112C;;;;N;HANGUL LETTER SSANG BIEUB SUN GYEONG EUM;;;; +317A;HANGUL LETTER SIOS-KIYEOK;Lo;0;L; 112D;;;;N;HANGUL LETTER SIOS GIYEOG;;;; +317B;HANGUL LETTER SIOS-NIEUN;Lo;0;L; 112E;;;;N;HANGUL LETTER SIOS NIEUN;;;; +317C;HANGUL LETTER SIOS-TIKEUT;Lo;0;L; 112F;;;;N;HANGUL LETTER SIOS DIGEUD;;;; +317D;HANGUL LETTER SIOS-PIEUP;Lo;0;L; 1132;;;;N;HANGUL LETTER SIOS BIEUB;;;; +317E;HANGUL LETTER SIOS-CIEUC;Lo;0;L; 1136;;;;N;HANGUL LETTER SIOS JIEUJ;;;; +317F;HANGUL LETTER PANSIOS;Lo;0;L; 1140;;;;N;HANGUL LETTER BAN CHI EUM;;;; +3180;HANGUL LETTER SSANGIEUNG;Lo;0;L; 1147;;;;N;HANGUL LETTER SSANG IEUNG;;;; +3181;HANGUL LETTER YESIEUNG;Lo;0;L; 114C;;;;N;HANGUL LETTER NGIEUNG;;;; +3182;HANGUL LETTER YESIEUNG-SIOS;Lo;0;L; 11F1;;;;N;HANGUL LETTER NGIEUNG SIOS;;;; +3183;HANGUL LETTER YESIEUNG-PANSIOS;Lo;0;L; 11F2;;;;N;HANGUL LETTER NGIEUNG BAN CHI EUM;;;; +3184;HANGUL LETTER KAPYEOUNPHIEUPH;Lo;0;L; 1157;;;;N;HANGUL LETTER PIEUP SUN GYEONG EUM;;;; +3185;HANGUL LETTER SSANGHIEUH;Lo;0;L; 1158;;;;N;HANGUL LETTER SSANG HIEUH;;;; +3186;HANGUL LETTER YEORINHIEUH;Lo;0;L; 1159;;;;N;HANGUL LETTER YEOLIN HIEUH;;;; +3187;HANGUL LETTER YO-YA;Lo;0;L; 1184;;;;N;HANGUL LETTER YOYA;;;; +3188;HANGUL LETTER YO-YAE;Lo;0;L; 1185;;;;N;HANGUL LETTER YOYAE;;;; +3189;HANGUL LETTER YO-I;Lo;0;L; 1188;;;;N;HANGUL LETTER YOI;;;; +318A;HANGUL LETTER YU-YEO;Lo;0;L; 1191;;;;N;HANGUL LETTER YUYEO;;;; +318B;HANGUL LETTER YU-YE;Lo;0;L; 1192;;;;N;HANGUL LETTER YUYE;;;; +318C;HANGUL LETTER YU-I;Lo;0;L; 1194;;;;N;HANGUL LETTER YUI;;;; +318D;HANGUL LETTER ARAEA;Lo;0;L; 119E;;;;N;HANGUL LETTER ALAE A;;;; +318E;HANGUL LETTER ARAEAE;Lo;0;L; 11A1;;;;N;HANGUL LETTER ALAE AE;;;; +3190;IDEOGRAPHIC ANNOTATION LINKING MARK;So;0;L;;;;;N;KANBUN TATETEN;Kanbun Tateten;;; +3191;IDEOGRAPHIC ANNOTATION REVERSE MARK;So;0;L;;;;;N;KAERITEN RE;Kaeriten;;; +3192;IDEOGRAPHIC ANNOTATION ONE MARK;No;0;L; 4E00;;;1;N;KAERITEN ITI;Kaeriten;;; +3193;IDEOGRAPHIC ANNOTATION TWO MARK;No;0;L; 4E8C;;;2;N;KAERITEN NI;Kaeriten;;; +3194;IDEOGRAPHIC ANNOTATION THREE MARK;No;0;L; 4E09;;;3;N;KAERITEN SAN;Kaeriten;;; +3195;IDEOGRAPHIC ANNOTATION FOUR MARK;No;0;L; 56DB;;;4;N;KAERITEN SI;Kaeriten;;; +3196;IDEOGRAPHIC ANNOTATION TOP MARK;So;0;L; 4E0A;;;;N;KAERITEN ZYOU;Kaeriten;;; +3197;IDEOGRAPHIC ANNOTATION MIDDLE MARK;So;0;L; 4E2D;;;;N;KAERITEN TYUU;Kaeriten;;; +3198;IDEOGRAPHIC ANNOTATION BOTTOM MARK;So;0;L; 4E0B;;;;N;KAERITEN GE;Kaeriten;;; +3199;IDEOGRAPHIC ANNOTATION FIRST MARK;So;0;L; 7532;;;;N;KAERITEN KOU;Kaeriten;;; +319A;IDEOGRAPHIC ANNOTATION SECOND MARK;So;0;L; 4E59;;;;N;KAERITEN OTU;Kaeriten;;; +319B;IDEOGRAPHIC ANNOTATION THIRD MARK;So;0;L; 4E19;;;;N;KAERITEN HEI;Kaeriten;;; +319C;IDEOGRAPHIC ANNOTATION FOURTH MARK;So;0;L; 4E01;;;;N;KAERITEN TEI;Kaeriten;;; +319D;IDEOGRAPHIC ANNOTATION HEAVEN MARK;So;0;L; 5929;;;;N;KAERITEN TEN;Kaeriten;;; +319E;IDEOGRAPHIC ANNOTATION EARTH MARK;So;0;L; 5730;;;;N;KAERITEN TI;Kaeriten;;; +319F;IDEOGRAPHIC ANNOTATION MAN MARK;So;0;L; 4EBA;;;;N;KAERITEN ZIN;Kaeriten;;; +31A0;BOPOMOFO LETTER BU;Lo;0;L;;;;;N;;;;; +31A1;BOPOMOFO LETTER ZI;Lo;0;L;;;;;N;;;;; +31A2;BOPOMOFO LETTER JI;Lo;0;L;;;;;N;;;;; +31A3;BOPOMOFO LETTER GU;Lo;0;L;;;;;N;;;;; +31A4;BOPOMOFO LETTER EE;Lo;0;L;;;;;N;;;;; +31A5;BOPOMOFO LETTER ENN;Lo;0;L;;;;;N;;;;; +31A6;BOPOMOFO LETTER OO;Lo;0;L;;;;;N;;;;; +31A7;BOPOMOFO LETTER ONN;Lo;0;L;;;;;N;;;;; +31A8;BOPOMOFO LETTER IR;Lo;0;L;;;;;N;;;;; +31A9;BOPOMOFO LETTER ANN;Lo;0;L;;;;;N;;;;; +31AA;BOPOMOFO LETTER INN;Lo;0;L;;;;;N;;;;; +31AB;BOPOMOFO LETTER UNN;Lo;0;L;;;;;N;;;;; +31AC;BOPOMOFO LETTER IM;Lo;0;L;;;;;N;;;;; +31AD;BOPOMOFO LETTER NGG;Lo;0;L;;;;;N;;;;; +31AE;BOPOMOFO LETTER AINN;Lo;0;L;;;;;N;;;;; +31AF;BOPOMOFO LETTER AUNN;Lo;0;L;;;;;N;;;;; +31B0;BOPOMOFO LETTER AM;Lo;0;L;;;;;N;;;;; +31B1;BOPOMOFO LETTER OM;Lo;0;L;;;;;N;;;;; +31B2;BOPOMOFO LETTER ONG;Lo;0;L;;;;;N;;;;; +31B3;BOPOMOFO LETTER INNN;Lo;0;L;;;;;N;;;;; +31B4;BOPOMOFO FINAL LETTER P;Lo;0;L;;;;;N;;;;; +31B5;BOPOMOFO FINAL LETTER T;Lo;0;L;;;;;N;;;;; +31B6;BOPOMOFO FINAL LETTER K;Lo;0;L;;;;;N;;;;; +31B7;BOPOMOFO FINAL LETTER H;Lo;0;L;;;;;N;;;;; +31F0;KATAKANA LETTER SMALL KU;Lo;0;L;;;;;N;;;;; +31F1;KATAKANA LETTER SMALL SI;Lo;0;L;;;;;N;;;;; +31F2;KATAKANA LETTER SMALL SU;Lo;0;L;;;;;N;;;;; +31F3;KATAKANA LETTER SMALL TO;Lo;0;L;;;;;N;;;;; +31F4;KATAKANA LETTER SMALL NU;Lo;0;L;;;;;N;;;;; +31F5;KATAKANA LETTER SMALL HA;Lo;0;L;;;;;N;;;;; +31F6;KATAKANA LETTER SMALL HI;Lo;0;L;;;;;N;;;;; +31F7;KATAKANA LETTER SMALL HU;Lo;0;L;;;;;N;;;;; +31F8;KATAKANA LETTER SMALL HE;Lo;0;L;;;;;N;;;;; +31F9;KATAKANA LETTER SMALL HO;Lo;0;L;;;;;N;;;;; +31FA;KATAKANA LETTER SMALL MU;Lo;0;L;;;;;N;;;;; +31FB;KATAKANA LETTER SMALL RA;Lo;0;L;;;;;N;;;;; +31FC;KATAKANA LETTER SMALL RI;Lo;0;L;;;;;N;;;;; +31FD;KATAKANA LETTER SMALL RU;Lo;0;L;;;;;N;;;;; +31FE;KATAKANA LETTER SMALL RE;Lo;0;L;;;;;N;;;;; +31FF;KATAKANA LETTER SMALL RO;Lo;0;L;;;;;N;;;;; +3200;PARENTHESIZED HANGUL KIYEOK;So;0;L; 0028 1100 0029;;;;N;PARENTHESIZED HANGUL GIYEOG;;;; +3201;PARENTHESIZED HANGUL NIEUN;So;0;L; 0028 1102 0029;;;;N;;;;; +3202;PARENTHESIZED HANGUL TIKEUT;So;0;L; 0028 1103 0029;;;;N;PARENTHESIZED HANGUL DIGEUD;;;; +3203;PARENTHESIZED HANGUL RIEUL;So;0;L; 0028 1105 0029;;;;N;PARENTHESIZED HANGUL LIEUL;;;; +3204;PARENTHESIZED HANGUL MIEUM;So;0;L; 0028 1106 0029;;;;N;;;;; +3205;PARENTHESIZED HANGUL PIEUP;So;0;L; 0028 1107 0029;;;;N;PARENTHESIZED HANGUL BIEUB;;;; +3206;PARENTHESIZED HANGUL SIOS;So;0;L; 0028 1109 0029;;;;N;;;;; +3207;PARENTHESIZED HANGUL IEUNG;So;0;L; 0028 110B 0029;;;;N;;;;; +3208;PARENTHESIZED HANGUL CIEUC;So;0;L; 0028 110C 0029;;;;N;PARENTHESIZED HANGUL JIEUJ;;;; +3209;PARENTHESIZED HANGUL CHIEUCH;So;0;L; 0028 110E 0029;;;;N;PARENTHESIZED HANGUL CIEUC;;;; +320A;PARENTHESIZED HANGUL KHIEUKH;So;0;L; 0028 110F 0029;;;;N;PARENTHESIZED HANGUL KIYEOK;;;; +320B;PARENTHESIZED HANGUL THIEUTH;So;0;L; 0028 1110 0029;;;;N;PARENTHESIZED HANGUL TIEUT;;;; +320C;PARENTHESIZED HANGUL PHIEUPH;So;0;L; 0028 1111 0029;;;;N;PARENTHESIZED HANGUL PIEUP;;;; +320D;PARENTHESIZED HANGUL HIEUH;So;0;L; 0028 1112 0029;;;;N;;;;; +320E;PARENTHESIZED HANGUL KIYEOK A;So;0;L; 0028 1100 1161 0029;;;;N;PARENTHESIZED HANGUL GA;;;; +320F;PARENTHESIZED HANGUL NIEUN A;So;0;L; 0028 1102 1161 0029;;;;N;PARENTHESIZED HANGUL NA;;;; +3210;PARENTHESIZED HANGUL TIKEUT A;So;0;L; 0028 1103 1161 0029;;;;N;PARENTHESIZED HANGUL DA;;;; +3211;PARENTHESIZED HANGUL RIEUL A;So;0;L; 0028 1105 1161 0029;;;;N;PARENTHESIZED HANGUL LA;;;; +3212;PARENTHESIZED HANGUL MIEUM A;So;0;L; 0028 1106 1161 0029;;;;N;PARENTHESIZED HANGUL MA;;;; +3213;PARENTHESIZED HANGUL PIEUP A;So;0;L; 0028 1107 1161 0029;;;;N;PARENTHESIZED HANGUL BA;;;; +3214;PARENTHESIZED HANGUL SIOS A;So;0;L; 0028 1109 1161 0029;;;;N;PARENTHESIZED HANGUL SA;;;; +3215;PARENTHESIZED HANGUL IEUNG A;So;0;L; 0028 110B 1161 0029;;;;N;PARENTHESIZED HANGUL A;;;; +3216;PARENTHESIZED HANGUL CIEUC A;So;0;L; 0028 110C 1161 0029;;;;N;PARENTHESIZED HANGUL JA;;;; +3217;PARENTHESIZED HANGUL CHIEUCH A;So;0;L; 0028 110E 1161 0029;;;;N;PARENTHESIZED HANGUL CA;;;; +3218;PARENTHESIZED HANGUL KHIEUKH A;So;0;L; 0028 110F 1161 0029;;;;N;PARENTHESIZED HANGUL KA;;;; +3219;PARENTHESIZED HANGUL THIEUTH A;So;0;L; 0028 1110 1161 0029;;;;N;PARENTHESIZED HANGUL TA;;;; +321A;PARENTHESIZED HANGUL PHIEUPH A;So;0;L; 0028 1111 1161 0029;;;;N;PARENTHESIZED HANGUL PA;;;; +321B;PARENTHESIZED HANGUL HIEUH A;So;0;L; 0028 1112 1161 0029;;;;N;PARENTHESIZED HANGUL HA;;;; +321C;PARENTHESIZED HANGUL CIEUC U;So;0;L; 0028 110C 116E 0029;;;;N;PARENTHESIZED HANGUL JU;;;; +3220;PARENTHESIZED IDEOGRAPH ONE;No;0;L; 0028 4E00 0029;;;1;N;;;;; +3221;PARENTHESIZED IDEOGRAPH TWO;No;0;L; 0028 4E8C 0029;;;2;N;;;;; +3222;PARENTHESIZED IDEOGRAPH THREE;No;0;L; 0028 4E09 0029;;;3;N;;;;; +3223;PARENTHESIZED IDEOGRAPH FOUR;No;0;L; 0028 56DB 0029;;;4;N;;;;; +3224;PARENTHESIZED IDEOGRAPH FIVE;No;0;L; 0028 4E94 0029;;;5;N;;;;; +3225;PARENTHESIZED IDEOGRAPH SIX;No;0;L; 0028 516D 0029;;;6;N;;;;; +3226;PARENTHESIZED IDEOGRAPH SEVEN;No;0;L; 0028 4E03 0029;;;7;N;;;;; +3227;PARENTHESIZED IDEOGRAPH EIGHT;No;0;L; 0028 516B 0029;;;8;N;;;;; +3228;PARENTHESIZED IDEOGRAPH NINE;No;0;L; 0028 4E5D 0029;;;9;N;;;;; +3229;PARENTHESIZED IDEOGRAPH TEN;No;0;L; 0028 5341 0029;;;10;N;;;;; +322A;PARENTHESIZED IDEOGRAPH MOON;So;0;L; 0028 6708 0029;;;;N;;;;; +322B;PARENTHESIZED IDEOGRAPH FIRE;So;0;L; 0028 706B 0029;;;;N;;;;; +322C;PARENTHESIZED IDEOGRAPH WATER;So;0;L; 0028 6C34 0029;;;;N;;;;; +322D;PARENTHESIZED IDEOGRAPH WOOD;So;0;L; 0028 6728 0029;;;;N;;;;; +322E;PARENTHESIZED IDEOGRAPH METAL;So;0;L; 0028 91D1 0029;;;;N;;;;; +322F;PARENTHESIZED IDEOGRAPH EARTH;So;0;L; 0028 571F 0029;;;;N;;;;; +3230;PARENTHESIZED IDEOGRAPH SUN;So;0;L; 0028 65E5 0029;;;;N;;;;; +3231;PARENTHESIZED IDEOGRAPH STOCK;So;0;L; 0028 682A 0029;;;;N;;;;; +3232;PARENTHESIZED IDEOGRAPH HAVE;So;0;L; 0028 6709 0029;;;;N;;;;; +3233;PARENTHESIZED IDEOGRAPH SOCIETY;So;0;L; 0028 793E 0029;;;;N;;;;; +3234;PARENTHESIZED IDEOGRAPH NAME;So;0;L; 0028 540D 0029;;;;N;;;;; +3235;PARENTHESIZED IDEOGRAPH SPECIAL;So;0;L; 0028 7279 0029;;;;N;;;;; +3236;PARENTHESIZED IDEOGRAPH FINANCIAL;So;0;L; 0028 8CA1 0029;;;;N;;;;; +3237;PARENTHESIZED IDEOGRAPH CONGRATULATION;So;0;L; 0028 795D 0029;;;;N;;;;; +3238;PARENTHESIZED IDEOGRAPH LABOR;So;0;L; 0028 52B4 0029;;;;N;;;;; +3239;PARENTHESIZED IDEOGRAPH REPRESENT;So;0;L; 0028 4EE3 0029;;;;N;;;;; +323A;PARENTHESIZED IDEOGRAPH CALL;So;0;L; 0028 547C 0029;;;;N;;;;; +323B;PARENTHESIZED IDEOGRAPH STUDY;So;0;L; 0028 5B66 0029;;;;N;;;;; +323C;PARENTHESIZED IDEOGRAPH SUPERVISE;So;0;L; 0028 76E3 0029;;;;N;;;;; +323D;PARENTHESIZED IDEOGRAPH ENTERPRISE;So;0;L; 0028 4F01 0029;;;;N;;;;; +323E;PARENTHESIZED IDEOGRAPH RESOURCE;So;0;L; 0028 8CC7 0029;;;;N;;;;; +323F;PARENTHESIZED IDEOGRAPH ALLIANCE;So;0;L; 0028 5354 0029;;;;N;;;;; +3240;PARENTHESIZED IDEOGRAPH FESTIVAL;So;0;L; 0028 796D 0029;;;;N;;;;; +3241;PARENTHESIZED IDEOGRAPH REST;So;0;L; 0028 4F11 0029;;;;N;;;;; +3242;PARENTHESIZED IDEOGRAPH SELF;So;0;L; 0028 81EA 0029;;;;N;;;;; +3243;PARENTHESIZED IDEOGRAPH REACH;So;0;L; 0028 81F3 0029;;;;N;;;;; +3251;CIRCLED NUMBER TWENTY ONE;No;0;ON; 0032 0031;;;21;N;;;;; +3252;CIRCLED NUMBER TWENTY TWO;No;0;ON; 0032 0032;;;22;N;;;;; +3253;CIRCLED NUMBER TWENTY THREE;No;0;ON; 0032 0033;;;23;N;;;;; +3254;CIRCLED NUMBER TWENTY FOUR;No;0;ON; 0032 0034;;;24;N;;;;; +3255;CIRCLED NUMBER TWENTY FIVE;No;0;ON; 0032 0035;;;25;N;;;;; +3256;CIRCLED NUMBER TWENTY SIX;No;0;ON; 0032 0036;;;26;N;;;;; +3257;CIRCLED NUMBER TWENTY SEVEN;No;0;ON; 0032 0037;;;27;N;;;;; +3258;CIRCLED NUMBER TWENTY EIGHT;No;0;ON; 0032 0038;;;28;N;;;;; +3259;CIRCLED NUMBER TWENTY NINE;No;0;ON; 0032 0039;;;29;N;;;;; +325A;CIRCLED NUMBER THIRTY;No;0;ON; 0033 0030;;;30;N;;;;; +325B;CIRCLED NUMBER THIRTY ONE;No;0;ON; 0033 0031;;;31;N;;;;; +325C;CIRCLED NUMBER THIRTY TWO;No;0;ON; 0033 0032;;;32;N;;;;; +325D;CIRCLED NUMBER THIRTY THREE;No;0;ON; 0033 0033;;;33;N;;;;; +325E;CIRCLED NUMBER THIRTY FOUR;No;0;ON; 0033 0034;;;34;N;;;;; +325F;CIRCLED NUMBER THIRTY FIVE;No;0;ON; 0033 0035;;;35;N;;;;; +3260;CIRCLED HANGUL KIYEOK;So;0;L; 1100;;;;N;CIRCLED HANGUL GIYEOG;;;; +3261;CIRCLED HANGUL NIEUN;So;0;L; 1102;;;;N;;;;; +3262;CIRCLED HANGUL TIKEUT;So;0;L; 1103;;;;N;CIRCLED HANGUL DIGEUD;;;; +3263;CIRCLED HANGUL RIEUL;So;0;L; 1105;;;;N;CIRCLED HANGUL LIEUL;;;; +3264;CIRCLED HANGUL MIEUM;So;0;L; 1106;;;;N;;;;; +3265;CIRCLED HANGUL PIEUP;So;0;L; 1107;;;;N;CIRCLED HANGUL BIEUB;;;; +3266;CIRCLED HANGUL SIOS;So;0;L; 1109;;;;N;;;;; +3267;CIRCLED HANGUL IEUNG;So;0;L; 110B;;;;N;;;;; +3268;CIRCLED HANGUL CIEUC;So;0;L; 110C;;;;N;CIRCLED HANGUL JIEUJ;;;; +3269;CIRCLED HANGUL CHIEUCH;So;0;L; 110E;;;;N;CIRCLED HANGUL CIEUC;;;; +326A;CIRCLED HANGUL KHIEUKH;So;0;L; 110F;;;;N;CIRCLED HANGUL KIYEOK;;;; +326B;CIRCLED HANGUL THIEUTH;So;0;L; 1110;;;;N;CIRCLED HANGUL TIEUT;;;; +326C;CIRCLED HANGUL PHIEUPH;So;0;L; 1111;;;;N;CIRCLED HANGUL PIEUP;;;; +326D;CIRCLED HANGUL HIEUH;So;0;L; 1112;;;;N;;;;; +326E;CIRCLED HANGUL KIYEOK A;So;0;L; 1100 1161;;;;N;CIRCLED HANGUL GA;;;; +326F;CIRCLED HANGUL NIEUN A;So;0;L; 1102 1161;;;;N;CIRCLED HANGUL NA;;;; +3270;CIRCLED HANGUL TIKEUT A;So;0;L; 1103 1161;;;;N;CIRCLED HANGUL DA;;;; +3271;CIRCLED HANGUL RIEUL A;So;0;L; 1105 1161;;;;N;CIRCLED HANGUL LA;;;; +3272;CIRCLED HANGUL MIEUM A;So;0;L; 1106 1161;;;;N;CIRCLED HANGUL MA;;;; +3273;CIRCLED HANGUL PIEUP A;So;0;L; 1107 1161;;;;N;CIRCLED HANGUL BA;;;; +3274;CIRCLED HANGUL SIOS A;So;0;L; 1109 1161;;;;N;CIRCLED HANGUL SA;;;; +3275;CIRCLED HANGUL IEUNG A;So;0;L; 110B 1161;;;;N;CIRCLED HANGUL A;;;; +3276;CIRCLED HANGUL CIEUC A;So;0;L; 110C 1161;;;;N;CIRCLED HANGUL JA;;;; +3277;CIRCLED HANGUL CHIEUCH A;So;0;L; 110E 1161;;;;N;CIRCLED HANGUL CA;;;; +3278;CIRCLED HANGUL KHIEUKH A;So;0;L; 110F 1161;;;;N;CIRCLED HANGUL KA;;;; +3279;CIRCLED HANGUL THIEUTH A;So;0;L; 1110 1161;;;;N;CIRCLED HANGUL TA;;;; +327A;CIRCLED HANGUL PHIEUPH A;So;0;L; 1111 1161;;;;N;CIRCLED HANGUL PA;;;; +327B;CIRCLED HANGUL HIEUH A;So;0;L; 1112 1161;;;;N;CIRCLED HANGUL HA;;;; +327F;KOREAN STANDARD SYMBOL;So;0;L;;;;;N;;;;; +3280;CIRCLED IDEOGRAPH ONE;No;0;L; 4E00;;;1;N;;;;; +3281;CIRCLED IDEOGRAPH TWO;No;0;L; 4E8C;;;2;N;;;;; +3282;CIRCLED IDEOGRAPH THREE;No;0;L; 4E09;;;3;N;;;;; +3283;CIRCLED IDEOGRAPH FOUR;No;0;L; 56DB;;;4;N;;;;; +3284;CIRCLED IDEOGRAPH FIVE;No;0;L; 4E94;;;5;N;;;;; +3285;CIRCLED IDEOGRAPH SIX;No;0;L; 516D;;;6;N;;;;; +3286;CIRCLED IDEOGRAPH SEVEN;No;0;L; 4E03;;;7;N;;;;; +3287;CIRCLED IDEOGRAPH EIGHT;No;0;L; 516B;;;8;N;;;;; +3288;CIRCLED IDEOGRAPH NINE;No;0;L; 4E5D;;;9;N;;;;; +3289;CIRCLED IDEOGRAPH TEN;No;0;L; 5341;;;10;N;;;;; +328A;CIRCLED IDEOGRAPH MOON;So;0;L; 6708;;;;N;;;;; +328B;CIRCLED IDEOGRAPH FIRE;So;0;L; 706B;;;;N;;;;; +328C;CIRCLED IDEOGRAPH WATER;So;0;L; 6C34;;;;N;;;;; +328D;CIRCLED IDEOGRAPH WOOD;So;0;L; 6728;;;;N;;;;; +328E;CIRCLED IDEOGRAPH METAL;So;0;L; 91D1;;;;N;;;;; +328F;CIRCLED IDEOGRAPH EARTH;So;0;L; 571F;;;;N;;;;; +3290;CIRCLED IDEOGRAPH SUN;So;0;L; 65E5;;;;N;;;;; +3291;CIRCLED IDEOGRAPH STOCK;So;0;L; 682A;;;;N;;;;; +3292;CIRCLED IDEOGRAPH HAVE;So;0;L; 6709;;;;N;;;;; +3293;CIRCLED IDEOGRAPH SOCIETY;So;0;L; 793E;;;;N;;;;; +3294;CIRCLED IDEOGRAPH NAME;So;0;L; 540D;;;;N;;;;; +3295;CIRCLED IDEOGRAPH SPECIAL;So;0;L; 7279;;;;N;;;;; +3296;CIRCLED IDEOGRAPH FINANCIAL;So;0;L; 8CA1;;;;N;;;;; +3297;CIRCLED IDEOGRAPH CONGRATULATION;So;0;L; 795D;;;;N;;;;; +3298;CIRCLED IDEOGRAPH LABOR;So;0;L; 52B4;;;;N;;;;; +3299;CIRCLED IDEOGRAPH SECRET;So;0;L; 79D8;;;;N;;;;; +329A;CIRCLED IDEOGRAPH MALE;So;0;L; 7537;;;;N;;;;; +329B;CIRCLED IDEOGRAPH FEMALE;So;0;L; 5973;;;;N;;;;; +329C;CIRCLED IDEOGRAPH SUITABLE;So;0;L; 9069;;;;N;;;;; +329D;CIRCLED IDEOGRAPH EXCELLENT;So;0;L; 512A;;;;N;;;;; +329E;CIRCLED IDEOGRAPH PRINT;So;0;L; 5370;;;;N;;;;; +329F;CIRCLED IDEOGRAPH ATTENTION;So;0;L; 6CE8;;;;N;;;;; +32A0;CIRCLED IDEOGRAPH ITEM;So;0;L; 9805;;;;N;;;;; +32A1;CIRCLED IDEOGRAPH REST;So;0;L; 4F11;;;;N;;;;; +32A2;CIRCLED IDEOGRAPH COPY;So;0;L; 5199;;;;N;;;;; +32A3;CIRCLED IDEOGRAPH CORRECT;So;0;L; 6B63;;;;N;;;;; +32A4;CIRCLED IDEOGRAPH HIGH;So;0;L; 4E0A;;;;N;;;;; +32A5;CIRCLED IDEOGRAPH CENTRE;So;0;L; 4E2D;;;;N;CIRCLED IDEOGRAPH CENTER;;;; +32A6;CIRCLED IDEOGRAPH LOW;So;0;L; 4E0B;;;;N;;;;; +32A7;CIRCLED IDEOGRAPH LEFT;So;0;L; 5DE6;;;;N;;;;; +32A8;CIRCLED IDEOGRAPH RIGHT;So;0;L; 53F3;;;;N;;;;; +32A9;CIRCLED IDEOGRAPH MEDICINE;So;0;L; 533B;;;;N;;;;; +32AA;CIRCLED IDEOGRAPH RELIGION;So;0;L; 5B97;;;;N;;;;; +32AB;CIRCLED IDEOGRAPH STUDY;So;0;L; 5B66;;;;N;;;;; +32AC;CIRCLED IDEOGRAPH SUPERVISE;So;0;L; 76E3;;;;N;;;;; +32AD;CIRCLED IDEOGRAPH ENTERPRISE;So;0;L; 4F01;;;;N;;;;; +32AE;CIRCLED IDEOGRAPH RESOURCE;So;0;L; 8CC7;;;;N;;;;; +32AF;CIRCLED IDEOGRAPH ALLIANCE;So;0;L; 5354;;;;N;;;;; +32B0;CIRCLED IDEOGRAPH NIGHT;So;0;L; 591C;;;;N;;;;; +32B1;CIRCLED NUMBER THIRTY SIX;No;0;ON; 0033 0036;;;36;N;;;;; +32B2;CIRCLED NUMBER THIRTY SEVEN;No;0;ON; 0033 0037;;;37;N;;;;; +32B3;CIRCLED NUMBER THIRTY EIGHT;No;0;ON; 0033 0038;;;38;N;;;;; +32B4;CIRCLED NUMBER THIRTY NINE;No;0;ON; 0033 0039;;;39;N;;;;; +32B5;CIRCLED NUMBER FORTY;No;0;ON; 0034 0030;;;40;N;;;;; +32B6;CIRCLED NUMBER FORTY ONE;No;0;ON; 0034 0031;;;41;N;;;;; +32B7;CIRCLED NUMBER FORTY TWO;No;0;ON; 0034 0032;;;42;N;;;;; +32B8;CIRCLED NUMBER FORTY THREE;No;0;ON; 0034 0033;;;43;N;;;;; +32B9;CIRCLED NUMBER FORTY FOUR;No;0;ON; 0034 0034;;;44;N;;;;; +32BA;CIRCLED NUMBER FORTY FIVE;No;0;ON; 0034 0035;;;45;N;;;;; +32BB;CIRCLED NUMBER FORTY SIX;No;0;ON; 0034 0036;;;46;N;;;;; +32BC;CIRCLED NUMBER FORTY SEVEN;No;0;ON; 0034 0037;;;47;N;;;;; +32BD;CIRCLED NUMBER FORTY EIGHT;No;0;ON; 0034 0038;;;48;N;;;;; +32BE;CIRCLED NUMBER FORTY NINE;No;0;ON; 0034 0039;;;49;N;;;;; +32BF;CIRCLED NUMBER FIFTY;No;0;ON; 0035 0030;;;50;N;;;;; +32C0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY;So;0;L; 0031 6708;;;;N;;;;; +32C1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR FEBRUARY;So;0;L; 0032 6708;;;;N;;;;; +32C2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR MARCH;So;0;L; 0033 6708;;;;N;;;;; +32C3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR APRIL;So;0;L; 0034 6708;;;;N;;;;; +32C4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR MAY;So;0;L; 0035 6708;;;;N;;;;; +32C5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JUNE;So;0;L; 0036 6708;;;;N;;;;; +32C6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JULY;So;0;L; 0037 6708;;;;N;;;;; +32C7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR AUGUST;So;0;L; 0038 6708;;;;N;;;;; +32C8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR SEPTEMBER;So;0;L; 0039 6708;;;;N;;;;; +32C9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR OCTOBER;So;0;L; 0031 0030 6708;;;;N;;;;; +32CA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR NOVEMBER;So;0;L; 0031 0031 6708;;;;N;;;;; +32CB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DECEMBER;So;0;L; 0031 0032 6708;;;;N;;;;; +32D0;CIRCLED KATAKANA A;So;0;L; 30A2;;;;N;;;;; +32D1;CIRCLED KATAKANA I;So;0;L; 30A4;;;;N;;;;; +32D2;CIRCLED KATAKANA U;So;0;L; 30A6;;;;N;;;;; +32D3;CIRCLED KATAKANA E;So;0;L; 30A8;;;;N;;;;; +32D4;CIRCLED KATAKANA O;So;0;L; 30AA;;;;N;;;;; +32D5;CIRCLED KATAKANA KA;So;0;L; 30AB;;;;N;;;;; +32D6;CIRCLED KATAKANA KI;So;0;L; 30AD;;;;N;;;;; +32D7;CIRCLED KATAKANA KU;So;0;L; 30AF;;;;N;;;;; +32D8;CIRCLED KATAKANA KE;So;0;L; 30B1;;;;N;;;;; +32D9;CIRCLED KATAKANA KO;So;0;L; 30B3;;;;N;;;;; +32DA;CIRCLED KATAKANA SA;So;0;L; 30B5;;;;N;;;;; +32DB;CIRCLED KATAKANA SI;So;0;L; 30B7;;;;N;;;;; +32DC;CIRCLED KATAKANA SU;So;0;L; 30B9;;;;N;;;;; +32DD;CIRCLED KATAKANA SE;So;0;L; 30BB;;;;N;;;;; +32DE;CIRCLED KATAKANA SO;So;0;L; 30BD;;;;N;;;;; +32DF;CIRCLED KATAKANA TA;So;0;L; 30BF;;;;N;;;;; +32E0;CIRCLED KATAKANA TI;So;0;L; 30C1;;;;N;;;;; +32E1;CIRCLED KATAKANA TU;So;0;L; 30C4;;;;N;;;;; +32E2;CIRCLED KATAKANA TE;So;0;L; 30C6;;;;N;;;;; +32E3;CIRCLED KATAKANA TO;So;0;L; 30C8;;;;N;;;;; +32E4;CIRCLED KATAKANA NA;So;0;L; 30CA;;;;N;;;;; +32E5;CIRCLED KATAKANA NI;So;0;L; 30CB;;;;N;;;;; +32E6;CIRCLED KATAKANA NU;So;0;L; 30CC;;;;N;;;;; +32E7;CIRCLED KATAKANA NE;So;0;L; 30CD;;;;N;;;;; +32E8;CIRCLED KATAKANA NO;So;0;L; 30CE;;;;N;;;;; +32E9;CIRCLED KATAKANA HA;So;0;L; 30CF;;;;N;;;;; +32EA;CIRCLED KATAKANA HI;So;0;L; 30D2;;;;N;;;;; +32EB;CIRCLED KATAKANA HU;So;0;L; 30D5;;;;N;;;;; +32EC;CIRCLED KATAKANA HE;So;0;L; 30D8;;;;N;;;;; +32ED;CIRCLED KATAKANA HO;So;0;L; 30DB;;;;N;;;;; +32EE;CIRCLED KATAKANA MA;So;0;L; 30DE;;;;N;;;;; +32EF;CIRCLED KATAKANA MI;So;0;L; 30DF;;;;N;;;;; +32F0;CIRCLED KATAKANA MU;So;0;L; 30E0;;;;N;;;;; +32F1;CIRCLED KATAKANA ME;So;0;L; 30E1;;;;N;;;;; +32F2;CIRCLED KATAKANA MO;So;0;L; 30E2;;;;N;;;;; +32F3;CIRCLED KATAKANA YA;So;0;L; 30E4;;;;N;;;;; +32F4;CIRCLED KATAKANA YU;So;0;L; 30E6;;;;N;;;;; +32F5;CIRCLED KATAKANA YO;So;0;L; 30E8;;;;N;;;;; +32F6;CIRCLED KATAKANA RA;So;0;L; 30E9;;;;N;;;;; +32F7;CIRCLED KATAKANA RI;So;0;L; 30EA;;;;N;;;;; +32F8;CIRCLED KATAKANA RU;So;0;L; 30EB;;;;N;;;;; +32F9;CIRCLED KATAKANA RE;So;0;L; 30EC;;;;N;;;;; +32FA;CIRCLED KATAKANA RO;So;0;L; 30ED;;;;N;;;;; +32FB;CIRCLED KATAKANA WA;So;0;L; 30EF;;;;N;;;;; +32FC;CIRCLED KATAKANA WI;So;0;L; 30F0;;;;N;;;;; +32FD;CIRCLED KATAKANA WE;So;0;L; 30F1;;;;N;;;;; +32FE;CIRCLED KATAKANA WO;So;0;L; 30F2;;;;N;;;;; +3300;SQUARE APAATO;So;0;L; 30A2 30D1 30FC 30C8;;;;N;SQUARED APAATO;;;; +3301;SQUARE ARUHUA;So;0;L; 30A2 30EB 30D5 30A1;;;;N;SQUARED ARUHUA;;;; +3302;SQUARE ANPEA;So;0;L; 30A2 30F3 30DA 30A2;;;;N;SQUARED ANPEA;;;; +3303;SQUARE AARU;So;0;L; 30A2 30FC 30EB;;;;N;SQUARED AARU;;;; +3304;SQUARE ININGU;So;0;L; 30A4 30CB 30F3 30B0;;;;N;SQUARED ININGU;;;; +3305;SQUARE INTI;So;0;L; 30A4 30F3 30C1;;;;N;SQUARED INTI;;;; +3306;SQUARE UON;So;0;L; 30A6 30A9 30F3;;;;N;SQUARED UON;;;; +3307;SQUARE ESUKUUDO;So;0;L; 30A8 30B9 30AF 30FC 30C9;;;;N;SQUARED ESUKUUDO;;;; +3308;SQUARE EEKAA;So;0;L; 30A8 30FC 30AB 30FC;;;;N;SQUARED EEKAA;;;; +3309;SQUARE ONSU;So;0;L; 30AA 30F3 30B9;;;;N;SQUARED ONSU;;;; +330A;SQUARE OOMU;So;0;L; 30AA 30FC 30E0;;;;N;SQUARED OOMU;;;; +330B;SQUARE KAIRI;So;0;L; 30AB 30A4 30EA;;;;N;SQUARED KAIRI;;;; +330C;SQUARE KARATTO;So;0;L; 30AB 30E9 30C3 30C8;;;;N;SQUARED KARATTO;;;; +330D;SQUARE KARORII;So;0;L; 30AB 30ED 30EA 30FC;;;;N;SQUARED KARORII;;;; +330E;SQUARE GARON;So;0;L; 30AC 30ED 30F3;;;;N;SQUARED GARON;;;; +330F;SQUARE GANMA;So;0;L; 30AC 30F3 30DE;;;;N;SQUARED GANMA;;;; +3310;SQUARE GIGA;So;0;L; 30AE 30AC;;;;N;SQUARED GIGA;;;; +3311;SQUARE GINII;So;0;L; 30AE 30CB 30FC;;;;N;SQUARED GINII;;;; +3312;SQUARE KYURII;So;0;L; 30AD 30E5 30EA 30FC;;;;N;SQUARED KYURII;;;; +3313;SQUARE GIRUDAA;So;0;L; 30AE 30EB 30C0 30FC;;;;N;SQUARED GIRUDAA;;;; +3314;SQUARE KIRO;So;0;L; 30AD 30ED;;;;N;SQUARED KIRO;;;; +3315;SQUARE KIROGURAMU;So;0;L; 30AD 30ED 30B0 30E9 30E0;;;;N;SQUARED KIROGURAMU;;;; +3316;SQUARE KIROMEETORU;So;0;L; 30AD 30ED 30E1 30FC 30C8 30EB;;;;N;SQUARED KIROMEETORU;;;; +3317;SQUARE KIROWATTO;So;0;L; 30AD 30ED 30EF 30C3 30C8;;;;N;SQUARED KIROWATTO;;;; +3318;SQUARE GURAMU;So;0;L; 30B0 30E9 30E0;;;;N;SQUARED GURAMU;;;; +3319;SQUARE GURAMUTON;So;0;L; 30B0 30E9 30E0 30C8 30F3;;;;N;SQUARED GURAMUTON;;;; +331A;SQUARE KURUZEIRO;So;0;L; 30AF 30EB 30BC 30A4 30ED;;;;N;SQUARED KURUZEIRO;;;; +331B;SQUARE KUROONE;So;0;L; 30AF 30ED 30FC 30CD;;;;N;SQUARED KUROONE;;;; +331C;SQUARE KEESU;So;0;L; 30B1 30FC 30B9;;;;N;SQUARED KEESU;;;; +331D;SQUARE KORUNA;So;0;L; 30B3 30EB 30CA;;;;N;SQUARED KORUNA;;;; +331E;SQUARE KOOPO;So;0;L; 30B3 30FC 30DD;;;;N;SQUARED KOOPO;;;; +331F;SQUARE SAIKURU;So;0;L; 30B5 30A4 30AF 30EB;;;;N;SQUARED SAIKURU;;;; +3320;SQUARE SANTIIMU;So;0;L; 30B5 30F3 30C1 30FC 30E0;;;;N;SQUARED SANTIIMU;;;; +3321;SQUARE SIRINGU;So;0;L; 30B7 30EA 30F3 30B0;;;;N;SQUARED SIRINGU;;;; +3322;SQUARE SENTI;So;0;L; 30BB 30F3 30C1;;;;N;SQUARED SENTI;;;; +3323;SQUARE SENTO;So;0;L; 30BB 30F3 30C8;;;;N;SQUARED SENTO;;;; +3324;SQUARE DAASU;So;0;L; 30C0 30FC 30B9;;;;N;SQUARED DAASU;;;; +3325;SQUARE DESI;So;0;L; 30C7 30B7;;;;N;SQUARED DESI;;;; +3326;SQUARE DORU;So;0;L; 30C9 30EB;;;;N;SQUARED DORU;;;; +3327;SQUARE TON;So;0;L; 30C8 30F3;;;;N;SQUARED TON;;;; +3328;SQUARE NANO;So;0;L; 30CA 30CE;;;;N;SQUARED NANO;;;; +3329;SQUARE NOTTO;So;0;L; 30CE 30C3 30C8;;;;N;SQUARED NOTTO;;;; +332A;SQUARE HAITU;So;0;L; 30CF 30A4 30C4;;;;N;SQUARED HAITU;;;; +332B;SQUARE PAASENTO;So;0;L; 30D1 30FC 30BB 30F3 30C8;;;;N;SQUARED PAASENTO;;;; +332C;SQUARE PAATU;So;0;L; 30D1 30FC 30C4;;;;N;SQUARED PAATU;;;; +332D;SQUARE BAARERU;So;0;L; 30D0 30FC 30EC 30EB;;;;N;SQUARED BAARERU;;;; +332E;SQUARE PIASUTORU;So;0;L; 30D4 30A2 30B9 30C8 30EB;;;;N;SQUARED PIASUTORU;;;; +332F;SQUARE PIKURU;So;0;L; 30D4 30AF 30EB;;;;N;SQUARED PIKURU;;;; +3330;SQUARE PIKO;So;0;L; 30D4 30B3;;;;N;SQUARED PIKO;;;; +3331;SQUARE BIRU;So;0;L; 30D3 30EB;;;;N;SQUARED BIRU;;;; +3332;SQUARE HUARADDO;So;0;L; 30D5 30A1 30E9 30C3 30C9;;;;N;SQUARED HUARADDO;;;; +3333;SQUARE HUIITO;So;0;L; 30D5 30A3 30FC 30C8;;;;N;SQUARED HUIITO;;;; +3334;SQUARE BUSSYERU;So;0;L; 30D6 30C3 30B7 30A7 30EB;;;;N;SQUARED BUSSYERU;;;; +3335;SQUARE HURAN;So;0;L; 30D5 30E9 30F3;;;;N;SQUARED HURAN;;;; +3336;SQUARE HEKUTAARU;So;0;L; 30D8 30AF 30BF 30FC 30EB;;;;N;SQUARED HEKUTAARU;;;; +3337;SQUARE PESO;So;0;L; 30DA 30BD;;;;N;SQUARED PESO;;;; +3338;SQUARE PENIHI;So;0;L; 30DA 30CB 30D2;;;;N;SQUARED PENIHI;;;; +3339;SQUARE HERUTU;So;0;L; 30D8 30EB 30C4;;;;N;SQUARED HERUTU;;;; +333A;SQUARE PENSU;So;0;L; 30DA 30F3 30B9;;;;N;SQUARED PENSU;;;; +333B;SQUARE PEEZI;So;0;L; 30DA 30FC 30B8;;;;N;SQUARED PEEZI;;;; +333C;SQUARE BEETA;So;0;L; 30D9 30FC 30BF;;;;N;SQUARED BEETA;;;; +333D;SQUARE POINTO;So;0;L; 30DD 30A4 30F3 30C8;;;;N;SQUARED POINTO;;;; +333E;SQUARE BORUTO;So;0;L; 30DC 30EB 30C8;;;;N;SQUARED BORUTO;;;; +333F;SQUARE HON;So;0;L; 30DB 30F3;;;;N;SQUARED HON;;;; +3340;SQUARE PONDO;So;0;L; 30DD 30F3 30C9;;;;N;SQUARED PONDO;;;; +3341;SQUARE HOORU;So;0;L; 30DB 30FC 30EB;;;;N;SQUARED HOORU;;;; +3342;SQUARE HOON;So;0;L; 30DB 30FC 30F3;;;;N;SQUARED HOON;;;; +3343;SQUARE MAIKURO;So;0;L; 30DE 30A4 30AF 30ED;;;;N;SQUARED MAIKURO;;;; +3344;SQUARE MAIRU;So;0;L; 30DE 30A4 30EB;;;;N;SQUARED MAIRU;;;; +3345;SQUARE MAHHA;So;0;L; 30DE 30C3 30CF;;;;N;SQUARED MAHHA;;;; +3346;SQUARE MARUKU;So;0;L; 30DE 30EB 30AF;;;;N;SQUARED MARUKU;;;; +3347;SQUARE MANSYON;So;0;L; 30DE 30F3 30B7 30E7 30F3;;;;N;SQUARED MANSYON;;;; +3348;SQUARE MIKURON;So;0;L; 30DF 30AF 30ED 30F3;;;;N;SQUARED MIKURON;;;; +3349;SQUARE MIRI;So;0;L; 30DF 30EA;;;;N;SQUARED MIRI;;;; +334A;SQUARE MIRIBAARU;So;0;L; 30DF 30EA 30D0 30FC 30EB;;;;N;SQUARED MIRIBAARU;;;; +334B;SQUARE MEGA;So;0;L; 30E1 30AC;;;;N;SQUARED MEGA;;;; +334C;SQUARE MEGATON;So;0;L; 30E1 30AC 30C8 30F3;;;;N;SQUARED MEGATON;;;; +334D;SQUARE MEETORU;So;0;L; 30E1 30FC 30C8 30EB;;;;N;SQUARED MEETORU;;;; +334E;SQUARE YAADO;So;0;L; 30E4 30FC 30C9;;;;N;SQUARED YAADO;;;; +334F;SQUARE YAARU;So;0;L; 30E4 30FC 30EB;;;;N;SQUARED YAARU;;;; +3350;SQUARE YUAN;So;0;L; 30E6 30A2 30F3;;;;N;SQUARED YUAN;;;; +3351;SQUARE RITTORU;So;0;L; 30EA 30C3 30C8 30EB;;;;N;SQUARED RITTORU;;;; +3352;SQUARE RIRA;So;0;L; 30EA 30E9;;;;N;SQUARED RIRA;;;; +3353;SQUARE RUPII;So;0;L; 30EB 30D4 30FC;;;;N;SQUARED RUPII;;;; +3354;SQUARE RUUBURU;So;0;L; 30EB 30FC 30D6 30EB;;;;N;SQUARED RUUBURU;;;; +3355;SQUARE REMU;So;0;L; 30EC 30E0;;;;N;SQUARED REMU;;;; +3356;SQUARE RENTOGEN;So;0;L; 30EC 30F3 30C8 30B2 30F3;;;;N;SQUARED RENTOGEN;;;; +3357;SQUARE WATTO;So;0;L; 30EF 30C3 30C8;;;;N;SQUARED WATTO;;;; +3358;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ZERO;So;0;L; 0030 70B9;;;;N;;;;; +3359;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ONE;So;0;L; 0031 70B9;;;;N;;;;; +335A;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWO;So;0;L; 0032 70B9;;;;N;;;;; +335B;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THREE;So;0;L; 0033 70B9;;;;N;;;;; +335C;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOUR;So;0;L; 0034 70B9;;;;N;;;;; +335D;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIVE;So;0;L; 0035 70B9;;;;N;;;;; +335E;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIX;So;0;L; 0036 70B9;;;;N;;;;; +335F;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVEN;So;0;L; 0037 70B9;;;;N;;;;; +3360;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHT;So;0;L; 0038 70B9;;;;N;;;;; +3361;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINE;So;0;L; 0039 70B9;;;;N;;;;; +3362;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TEN;So;0;L; 0031 0030 70B9;;;;N;;;;; +3363;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ELEVEN;So;0;L; 0031 0031 70B9;;;;N;;;;; +3364;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWELVE;So;0;L; 0031 0032 70B9;;;;N;;;;; +3365;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THIRTEEN;So;0;L; 0031 0033 70B9;;;;N;;;;; +3366;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOURTEEN;So;0;L; 0031 0034 70B9;;;;N;;;;; +3367;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIFTEEN;So;0;L; 0031 0035 70B9;;;;N;;;;; +3368;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIXTEEN;So;0;L; 0031 0036 70B9;;;;N;;;;; +3369;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVENTEEN;So;0;L; 0031 0037 70B9;;;;N;;;;; +336A;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHTEEN;So;0;L; 0031 0038 70B9;;;;N;;;;; +336B;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINETEEN;So;0;L; 0031 0039 70B9;;;;N;;;;; +336C;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY;So;0;L; 0032 0030 70B9;;;;N;;;;; +336D;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-ONE;So;0;L; 0032 0031 70B9;;;;N;;;;; +336E;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-TWO;So;0;L; 0032 0032 70B9;;;;N;;;;; +336F;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-THREE;So;0;L; 0032 0033 70B9;;;;N;;;;; +3370;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-FOUR;So;0;L; 0032 0034 70B9;;;;N;;;;; +3371;SQUARE HPA;So;0;L; 0068 0050 0061;;;;N;;;;; +3372;SQUARE DA;So;0;L; 0064 0061;;;;N;;;;; +3373;SQUARE AU;So;0;L; 0041 0055;;;;N;;;;; +3374;SQUARE BAR;So;0;L; 0062 0061 0072;;;;N;;;;; +3375;SQUARE OV;So;0;L; 006F 0056;;;;N;;;;; +3376;SQUARE PC;So;0;L; 0070 0063;;;;N;;;;; +337B;SQUARE ERA NAME HEISEI;So;0;L; 5E73 6210;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME HEISEI;;;; +337C;SQUARE ERA NAME SYOUWA;So;0;L; 662D 548C;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME SYOUWA;;;; +337D;SQUARE ERA NAME TAISYOU;So;0;L; 5927 6B63;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME TAISYOU;;;; +337E;SQUARE ERA NAME MEIZI;So;0;L; 660E 6CBB;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME MEIZI;;;; +337F;SQUARE CORPORATION;So;0;L; 682A 5F0F 4F1A 793E;;;;N;SQUARED FOUR IDEOGRAPHS CORPORATION;;;; +3380;SQUARE PA AMPS;So;0;L; 0070 0041;;;;N;SQUARED PA AMPS;;;; +3381;SQUARE NA;So;0;L; 006E 0041;;;;N;SQUARED NA;;;; +3382;SQUARE MU A;So;0;L; 03BC 0041;;;;N;SQUARED MU A;;;; +3383;SQUARE MA;So;0;L; 006D 0041;;;;N;SQUARED MA;;;; +3384;SQUARE KA;So;0;L; 006B 0041;;;;N;SQUARED KA;;;; +3385;SQUARE KB;So;0;L; 004B 0042;;;;N;SQUARED KB;;;; +3386;SQUARE MB;So;0;L; 004D 0042;;;;N;SQUARED MB;;;; +3387;SQUARE GB;So;0;L; 0047 0042;;;;N;SQUARED GB;;;; +3388;SQUARE CAL;So;0;L; 0063 0061 006C;;;;N;SQUARED CAL;;;; +3389;SQUARE KCAL;So;0;L; 006B 0063 0061 006C;;;;N;SQUARED KCAL;;;; +338A;SQUARE PF;So;0;L; 0070 0046;;;;N;SQUARED PF;;;; +338B;SQUARE NF;So;0;L; 006E 0046;;;;N;SQUARED NF;;;; +338C;SQUARE MU F;So;0;L; 03BC 0046;;;;N;SQUARED MU F;;;; +338D;SQUARE MU G;So;0;L; 03BC 0067;;;;N;SQUARED MU G;;;; +338E;SQUARE MG;So;0;L; 006D 0067;;;;N;SQUARED MG;;;; +338F;SQUARE KG;So;0;L; 006B 0067;;;;N;SQUARED KG;;;; +3390;SQUARE HZ;So;0;L; 0048 007A;;;;N;SQUARED HZ;;;; +3391;SQUARE KHZ;So;0;L; 006B 0048 007A;;;;N;SQUARED KHZ;;;; +3392;SQUARE MHZ;So;0;L; 004D 0048 007A;;;;N;SQUARED MHZ;;;; +3393;SQUARE GHZ;So;0;L; 0047 0048 007A;;;;N;SQUARED GHZ;;;; +3394;SQUARE THZ;So;0;L; 0054 0048 007A;;;;N;SQUARED THZ;;;; +3395;SQUARE MU L;So;0;L; 03BC 2113;;;;N;SQUARED MU L;;;; +3396;SQUARE ML;So;0;L; 006D 2113;;;;N;SQUARED ML;;;; +3397;SQUARE DL;So;0;L; 0064 2113;;;;N;SQUARED DL;;;; +3398;SQUARE KL;So;0;L; 006B 2113;;;;N;SQUARED KL;;;; +3399;SQUARE FM;So;0;L; 0066 006D;;;;N;SQUARED FM;;;; +339A;SQUARE NM;So;0;L; 006E 006D;;;;N;SQUARED NM;;;; +339B;SQUARE MU M;So;0;L; 03BC 006D;;;;N;SQUARED MU M;;;; +339C;SQUARE MM;So;0;L; 006D 006D;;;;N;SQUARED MM;;;; +339D;SQUARE CM;So;0;L; 0063 006D;;;;N;SQUARED CM;;;; +339E;SQUARE KM;So;0;L; 006B 006D;;;;N;SQUARED KM;;;; +339F;SQUARE MM SQUARED;So;0;L; 006D 006D 00B2;;;;N;SQUARED MM SQUARED;;;; +33A0;SQUARE CM SQUARED;So;0;L; 0063 006D 00B2;;;;N;SQUARED CM SQUARED;;;; +33A1;SQUARE M SQUARED;So;0;L; 006D 00B2;;;;N;SQUARED M SQUARED;;;; +33A2;SQUARE KM SQUARED;So;0;L; 006B 006D 00B2;;;;N;SQUARED KM SQUARED;;;; +33A3;SQUARE MM CUBED;So;0;L; 006D 006D 00B3;;;;N;SQUARED MM CUBED;;;; +33A4;SQUARE CM CUBED;So;0;L; 0063 006D 00B3;;;;N;SQUARED CM CUBED;;;; +33A5;SQUARE M CUBED;So;0;L; 006D 00B3;;;;N;SQUARED M CUBED;;;; +33A6;SQUARE KM CUBED;So;0;L; 006B 006D 00B3;;;;N;SQUARED KM CUBED;;;; +33A7;SQUARE M OVER S;So;0;L; 006D 2215 0073;;;;N;SQUARED M OVER S;;;; +33A8;SQUARE M OVER S SQUARED;So;0;L; 006D 2215 0073 00B2;;;;N;SQUARED M OVER S SQUARED;;;; +33A9;SQUARE PA;So;0;L; 0050 0061;;;;N;SQUARED PA;;;; +33AA;SQUARE KPA;So;0;L; 006B 0050 0061;;;;N;SQUARED KPA;;;; +33AB;SQUARE MPA;So;0;L; 004D 0050 0061;;;;N;SQUARED MPA;;;; +33AC;SQUARE GPA;So;0;L; 0047 0050 0061;;;;N;SQUARED GPA;;;; +33AD;SQUARE RAD;So;0;L; 0072 0061 0064;;;;N;SQUARED RAD;;;; +33AE;SQUARE RAD OVER S;So;0;L; 0072 0061 0064 2215 0073;;;;N;SQUARED RAD OVER S;;;; +33AF;SQUARE RAD OVER S SQUARED;So;0;L; 0072 0061 0064 2215 0073 00B2;;;;N;SQUARED RAD OVER S SQUARED;;;; +33B0;SQUARE PS;So;0;L; 0070 0073;;;;N;SQUARED PS;;;; +33B1;SQUARE NS;So;0;L; 006E 0073;;;;N;SQUARED NS;;;; +33B2;SQUARE MU S;So;0;L; 03BC 0073;;;;N;SQUARED MU S;;;; +33B3;SQUARE MS;So;0;L; 006D 0073;;;;N;SQUARED MS;;;; +33B4;SQUARE PV;So;0;L; 0070 0056;;;;N;SQUARED PV;;;; +33B5;SQUARE NV;So;0;L; 006E 0056;;;;N;SQUARED NV;;;; +33B6;SQUARE MU V;So;0;L; 03BC 0056;;;;N;SQUARED MU V;;;; +33B7;SQUARE MV;So;0;L; 006D 0056;;;;N;SQUARED MV;;;; +33B8;SQUARE KV;So;0;L; 006B 0056;;;;N;SQUARED KV;;;; +33B9;SQUARE MV MEGA;So;0;L; 004D 0056;;;;N;SQUARED MV MEGA;;;; +33BA;SQUARE PW;So;0;L; 0070 0057;;;;N;SQUARED PW;;;; +33BB;SQUARE NW;So;0;L; 006E 0057;;;;N;SQUARED NW;;;; +33BC;SQUARE MU W;So;0;L; 03BC 0057;;;;N;SQUARED MU W;;;; +33BD;SQUARE MW;So;0;L; 006D 0057;;;;N;SQUARED MW;;;; +33BE;SQUARE KW;So;0;L; 006B 0057;;;;N;SQUARED KW;;;; +33BF;SQUARE MW MEGA;So;0;L; 004D 0057;;;;N;SQUARED MW MEGA;;;; +33C0;SQUARE K OHM;So;0;L; 006B 03A9;;;;N;SQUARED K OHM;;;; +33C1;SQUARE M OHM;So;0;L; 004D 03A9;;;;N;SQUARED M OHM;;;; +33C2;SQUARE AM;So;0;L; 0061 002E 006D 002E;;;;N;SQUARED AM;;;; +33C3;SQUARE BQ;So;0;L; 0042 0071;;;;N;SQUARED BQ;;;; +33C4;SQUARE CC;So;0;L; 0063 0063;;;;N;SQUARED CC;;;; +33C5;SQUARE CD;So;0;L; 0063 0064;;;;N;SQUARED CD;;;; +33C6;SQUARE C OVER KG;So;0;L; 0043 2215 006B 0067;;;;N;SQUARED C OVER KG;;;; +33C7;SQUARE CO;So;0;L; 0043 006F 002E;;;;N;SQUARED CO;;;; +33C8;SQUARE DB;So;0;L; 0064 0042;;;;N;SQUARED DB;;;; +33C9;SQUARE GY;So;0;L; 0047 0079;;;;N;SQUARED GY;;;; +33CA;SQUARE HA;So;0;L; 0068 0061;;;;N;SQUARED HA;;;; +33CB;SQUARE HP;So;0;L; 0048 0050;;;;N;SQUARED HP;;;; +33CC;SQUARE IN;So;0;L; 0069 006E;;;;N;SQUARED IN;;;; +33CD;SQUARE KK;So;0;L; 004B 004B;;;;N;SQUARED KK;;;; +33CE;SQUARE KM CAPITAL;So;0;L; 004B 004D;;;;N;SQUARED KM CAPITAL;;;; +33CF;SQUARE KT;So;0;L; 006B 0074;;;;N;SQUARED KT;;;; +33D0;SQUARE LM;So;0;L; 006C 006D;;;;N;SQUARED LM;;;; +33D1;SQUARE LN;So;0;L; 006C 006E;;;;N;SQUARED LN;;;; +33D2;SQUARE LOG;So;0;L; 006C 006F 0067;;;;N;SQUARED LOG;;;; +33D3;SQUARE LX;So;0;L; 006C 0078;;;;N;SQUARED LX;;;; +33D4;SQUARE MB SMALL;So;0;L; 006D 0062;;;;N;SQUARED MB SMALL;;;; +33D5;SQUARE MIL;So;0;L; 006D 0069 006C;;;;N;SQUARED MIL;;;; +33D6;SQUARE MOL;So;0;L; 006D 006F 006C;;;;N;SQUARED MOL;;;; +33D7;SQUARE PH;So;0;L; 0050 0048;;;;N;SQUARED PH;;;; +33D8;SQUARE PM;So;0;L; 0070 002E 006D 002E;;;;N;SQUARED PM;;;; +33D9;SQUARE PPM;So;0;L; 0050 0050 004D;;;;N;SQUARED PPM;;;; +33DA;SQUARE PR;So;0;L; 0050 0052;;;;N;SQUARED PR;;;; +33DB;SQUARE SR;So;0;L; 0073 0072;;;;N;SQUARED SR;;;; +33DC;SQUARE SV;So;0;L; 0053 0076;;;;N;SQUARED SV;;;; +33DD;SQUARE WB;So;0;L; 0057 0062;;;;N;SQUARED WB;;;; +33E0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ONE;So;0;L; 0031 65E5;;;;N;;;;; +33E1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWO;So;0;L; 0032 65E5;;;;N;;;;; +33E2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THREE;So;0;L; 0033 65E5;;;;N;;;;; +33E3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOUR;So;0;L; 0034 65E5;;;;N;;;;; +33E4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIVE;So;0;L; 0035 65E5;;;;N;;;;; +33E5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIX;So;0;L; 0036 65E5;;;;N;;;;; +33E6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVEN;So;0;L; 0037 65E5;;;;N;;;;; +33E7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHT;So;0;L; 0038 65E5;;;;N;;;;; +33E8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINE;So;0;L; 0039 65E5;;;;N;;;;; +33E9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TEN;So;0;L; 0031 0030 65E5;;;;N;;;;; +33EA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ELEVEN;So;0;L; 0031 0031 65E5;;;;N;;;;; +33EB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWELVE;So;0;L; 0031 0032 65E5;;;;N;;;;; +33EC;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTEEN;So;0;L; 0031 0033 65E5;;;;N;;;;; +33ED;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOURTEEN;So;0;L; 0031 0034 65E5;;;;N;;;;; +33EE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIFTEEN;So;0;L; 0031 0035 65E5;;;;N;;;;; +33EF;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIXTEEN;So;0;L; 0031 0036 65E5;;;;N;;;;; +33F0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVENTEEN;So;0;L; 0031 0037 65E5;;;;N;;;;; +33F1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHTEEN;So;0;L; 0031 0038 65E5;;;;N;;;;; +33F2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINETEEN;So;0;L; 0031 0039 65E5;;;;N;;;;; +33F3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY;So;0;L; 0032 0030 65E5;;;;N;;;;; +33F4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-ONE;So;0;L; 0032 0031 65E5;;;;N;;;;; +33F5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-TWO;So;0;L; 0032 0032 65E5;;;;N;;;;; +33F6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-THREE;So;0;L; 0032 0033 65E5;;;;N;;;;; +33F7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FOUR;So;0;L; 0032 0034 65E5;;;;N;;;;; +33F8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FIVE;So;0;L; 0032 0035 65E5;;;;N;;;;; +33F9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SIX;So;0;L; 0032 0036 65E5;;;;N;;;;; +33FA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SEVEN;So;0;L; 0032 0037 65E5;;;;N;;;;; +33FB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-EIGHT;So;0;L; 0032 0038 65E5;;;;N;;;;; +33FC;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-NINE;So;0;L; 0032 0039 65E5;;;;N;;;;; +33FD;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY;So;0;L; 0033 0030 65E5;;;;N;;;;; +33FE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE;So;0;L; 0033 0031 65E5;;;;N;;;;; +3400;;Lo;0;L;;;;;N;;;;; +4DB5;;Lo;0;L;;;;;N;;;;; +4E00;;Lo;0;L;;;;;N;;;;; +9FA5;;Lo;0;L;;;;;N;;;;; +A000;YI SYLLABLE IT;Lo;0;L;;;;;N;;;;; +A001;YI SYLLABLE IX;Lo;0;L;;;;;N;;;;; +A002;YI SYLLABLE I;Lo;0;L;;;;;N;;;;; +A003;YI SYLLABLE IP;Lo;0;L;;;;;N;;;;; +A004;YI SYLLABLE IET;Lo;0;L;;;;;N;;;;; +A005;YI SYLLABLE IEX;Lo;0;L;;;;;N;;;;; +A006;YI SYLLABLE IE;Lo;0;L;;;;;N;;;;; +A007;YI SYLLABLE IEP;Lo;0;L;;;;;N;;;;; +A008;YI SYLLABLE AT;Lo;0;L;;;;;N;;;;; +A009;YI SYLLABLE AX;Lo;0;L;;;;;N;;;;; +A00A;YI SYLLABLE A;Lo;0;L;;;;;N;;;;; +A00B;YI SYLLABLE AP;Lo;0;L;;;;;N;;;;; +A00C;YI SYLLABLE UOX;Lo;0;L;;;;;N;;;;; +A00D;YI SYLLABLE UO;Lo;0;L;;;;;N;;;;; +A00E;YI SYLLABLE UOP;Lo;0;L;;;;;N;;;;; +A00F;YI SYLLABLE OT;Lo;0;L;;;;;N;;;;; +A010;YI SYLLABLE OX;Lo;0;L;;;;;N;;;;; +A011;YI SYLLABLE O;Lo;0;L;;;;;N;;;;; +A012;YI SYLLABLE OP;Lo;0;L;;;;;N;;;;; +A013;YI SYLLABLE EX;Lo;0;L;;;;;N;;;;; +A014;YI SYLLABLE E;Lo;0;L;;;;;N;;;;; +A015;YI SYLLABLE WU;Lo;0;L;;;;;N;;;;; +A016;YI SYLLABLE BIT;Lo;0;L;;;;;N;;;;; +A017;YI SYLLABLE BIX;Lo;0;L;;;;;N;;;;; +A018;YI SYLLABLE BI;Lo;0;L;;;;;N;;;;; +A019;YI SYLLABLE BIP;Lo;0;L;;;;;N;;;;; +A01A;YI SYLLABLE BIET;Lo;0;L;;;;;N;;;;; +A01B;YI SYLLABLE BIEX;Lo;0;L;;;;;N;;;;; +A01C;YI SYLLABLE BIE;Lo;0;L;;;;;N;;;;; +A01D;YI SYLLABLE BIEP;Lo;0;L;;;;;N;;;;; +A01E;YI SYLLABLE BAT;Lo;0;L;;;;;N;;;;; +A01F;YI SYLLABLE BAX;Lo;0;L;;;;;N;;;;; +A020;YI SYLLABLE BA;Lo;0;L;;;;;N;;;;; +A021;YI SYLLABLE BAP;Lo;0;L;;;;;N;;;;; +A022;YI SYLLABLE BUOX;Lo;0;L;;;;;N;;;;; +A023;YI SYLLABLE BUO;Lo;0;L;;;;;N;;;;; +A024;YI SYLLABLE BUOP;Lo;0;L;;;;;N;;;;; +A025;YI SYLLABLE BOT;Lo;0;L;;;;;N;;;;; +A026;YI SYLLABLE BOX;Lo;0;L;;;;;N;;;;; +A027;YI SYLLABLE BO;Lo;0;L;;;;;N;;;;; +A028;YI SYLLABLE BOP;Lo;0;L;;;;;N;;;;; +A029;YI SYLLABLE BEX;Lo;0;L;;;;;N;;;;; +A02A;YI SYLLABLE BE;Lo;0;L;;;;;N;;;;; +A02B;YI SYLLABLE BEP;Lo;0;L;;;;;N;;;;; +A02C;YI SYLLABLE BUT;Lo;0;L;;;;;N;;;;; +A02D;YI SYLLABLE BUX;Lo;0;L;;;;;N;;;;; +A02E;YI SYLLABLE BU;Lo;0;L;;;;;N;;;;; +A02F;YI SYLLABLE BUP;Lo;0;L;;;;;N;;;;; +A030;YI SYLLABLE BURX;Lo;0;L;;;;;N;;;;; +A031;YI SYLLABLE BUR;Lo;0;L;;;;;N;;;;; +A032;YI SYLLABLE BYT;Lo;0;L;;;;;N;;;;; +A033;YI SYLLABLE BYX;Lo;0;L;;;;;N;;;;; +A034;YI SYLLABLE BY;Lo;0;L;;;;;N;;;;; +A035;YI SYLLABLE BYP;Lo;0;L;;;;;N;;;;; +A036;YI SYLLABLE BYRX;Lo;0;L;;;;;N;;;;; +A037;YI SYLLABLE BYR;Lo;0;L;;;;;N;;;;; +A038;YI SYLLABLE PIT;Lo;0;L;;;;;N;;;;; +A039;YI SYLLABLE PIX;Lo;0;L;;;;;N;;;;; +A03A;YI SYLLABLE PI;Lo;0;L;;;;;N;;;;; +A03B;YI SYLLABLE PIP;Lo;0;L;;;;;N;;;;; +A03C;YI SYLLABLE PIEX;Lo;0;L;;;;;N;;;;; +A03D;YI SYLLABLE PIE;Lo;0;L;;;;;N;;;;; +A03E;YI SYLLABLE PIEP;Lo;0;L;;;;;N;;;;; +A03F;YI SYLLABLE PAT;Lo;0;L;;;;;N;;;;; +A040;YI SYLLABLE PAX;Lo;0;L;;;;;N;;;;; +A041;YI SYLLABLE PA;Lo;0;L;;;;;N;;;;; +A042;YI SYLLABLE PAP;Lo;0;L;;;;;N;;;;; +A043;YI SYLLABLE PUOX;Lo;0;L;;;;;N;;;;; +A044;YI SYLLABLE PUO;Lo;0;L;;;;;N;;;;; +A045;YI SYLLABLE PUOP;Lo;0;L;;;;;N;;;;; +A046;YI SYLLABLE POT;Lo;0;L;;;;;N;;;;; +A047;YI SYLLABLE POX;Lo;0;L;;;;;N;;;;; +A048;YI SYLLABLE PO;Lo;0;L;;;;;N;;;;; +A049;YI SYLLABLE POP;Lo;0;L;;;;;N;;;;; +A04A;YI SYLLABLE PUT;Lo;0;L;;;;;N;;;;; +A04B;YI SYLLABLE PUX;Lo;0;L;;;;;N;;;;; +A04C;YI SYLLABLE PU;Lo;0;L;;;;;N;;;;; +A04D;YI SYLLABLE PUP;Lo;0;L;;;;;N;;;;; +A04E;YI SYLLABLE PURX;Lo;0;L;;;;;N;;;;; +A04F;YI SYLLABLE PUR;Lo;0;L;;;;;N;;;;; +A050;YI SYLLABLE PYT;Lo;0;L;;;;;N;;;;; +A051;YI SYLLABLE PYX;Lo;0;L;;;;;N;;;;; +A052;YI SYLLABLE PY;Lo;0;L;;;;;N;;;;; +A053;YI SYLLABLE PYP;Lo;0;L;;;;;N;;;;; +A054;YI SYLLABLE PYRX;Lo;0;L;;;;;N;;;;; +A055;YI SYLLABLE PYR;Lo;0;L;;;;;N;;;;; +A056;YI SYLLABLE BBIT;Lo;0;L;;;;;N;;;;; +A057;YI SYLLABLE BBIX;Lo;0;L;;;;;N;;;;; +A058;YI SYLLABLE BBI;Lo;0;L;;;;;N;;;;; +A059;YI SYLLABLE BBIP;Lo;0;L;;;;;N;;;;; +A05A;YI SYLLABLE BBIET;Lo;0;L;;;;;N;;;;; +A05B;YI SYLLABLE BBIEX;Lo;0;L;;;;;N;;;;; +A05C;YI SYLLABLE BBIE;Lo;0;L;;;;;N;;;;; +A05D;YI SYLLABLE BBIEP;Lo;0;L;;;;;N;;;;; +A05E;YI SYLLABLE BBAT;Lo;0;L;;;;;N;;;;; +A05F;YI SYLLABLE BBAX;Lo;0;L;;;;;N;;;;; +A060;YI SYLLABLE BBA;Lo;0;L;;;;;N;;;;; +A061;YI SYLLABLE BBAP;Lo;0;L;;;;;N;;;;; +A062;YI SYLLABLE BBUOX;Lo;0;L;;;;;N;;;;; +A063;YI SYLLABLE BBUO;Lo;0;L;;;;;N;;;;; +A064;YI SYLLABLE BBUOP;Lo;0;L;;;;;N;;;;; +A065;YI SYLLABLE BBOT;Lo;0;L;;;;;N;;;;; +A066;YI SYLLABLE BBOX;Lo;0;L;;;;;N;;;;; +A067;YI SYLLABLE BBO;Lo;0;L;;;;;N;;;;; +A068;YI SYLLABLE BBOP;Lo;0;L;;;;;N;;;;; +A069;YI SYLLABLE BBEX;Lo;0;L;;;;;N;;;;; +A06A;YI SYLLABLE BBE;Lo;0;L;;;;;N;;;;; +A06B;YI SYLLABLE BBEP;Lo;0;L;;;;;N;;;;; +A06C;YI SYLLABLE BBUT;Lo;0;L;;;;;N;;;;; +A06D;YI SYLLABLE BBUX;Lo;0;L;;;;;N;;;;; +A06E;YI SYLLABLE BBU;Lo;0;L;;;;;N;;;;; +A06F;YI SYLLABLE BBUP;Lo;0;L;;;;;N;;;;; +A070;YI SYLLABLE BBURX;Lo;0;L;;;;;N;;;;; +A071;YI SYLLABLE BBUR;Lo;0;L;;;;;N;;;;; +A072;YI SYLLABLE BBYT;Lo;0;L;;;;;N;;;;; +A073;YI SYLLABLE BBYX;Lo;0;L;;;;;N;;;;; +A074;YI SYLLABLE BBY;Lo;0;L;;;;;N;;;;; +A075;YI SYLLABLE BBYP;Lo;0;L;;;;;N;;;;; +A076;YI SYLLABLE NBIT;Lo;0;L;;;;;N;;;;; +A077;YI SYLLABLE NBIX;Lo;0;L;;;;;N;;;;; +A078;YI SYLLABLE NBI;Lo;0;L;;;;;N;;;;; +A079;YI SYLLABLE NBIP;Lo;0;L;;;;;N;;;;; +A07A;YI SYLLABLE NBIEX;Lo;0;L;;;;;N;;;;; +A07B;YI SYLLABLE NBIE;Lo;0;L;;;;;N;;;;; +A07C;YI SYLLABLE NBIEP;Lo;0;L;;;;;N;;;;; +A07D;YI SYLLABLE NBAT;Lo;0;L;;;;;N;;;;; +A07E;YI SYLLABLE NBAX;Lo;0;L;;;;;N;;;;; +A07F;YI SYLLABLE NBA;Lo;0;L;;;;;N;;;;; +A080;YI SYLLABLE NBAP;Lo;0;L;;;;;N;;;;; +A081;YI SYLLABLE NBOT;Lo;0;L;;;;;N;;;;; +A082;YI SYLLABLE NBOX;Lo;0;L;;;;;N;;;;; +A083;YI SYLLABLE NBO;Lo;0;L;;;;;N;;;;; +A084;YI SYLLABLE NBOP;Lo;0;L;;;;;N;;;;; +A085;YI SYLLABLE NBUT;Lo;0;L;;;;;N;;;;; +A086;YI SYLLABLE NBUX;Lo;0;L;;;;;N;;;;; +A087;YI SYLLABLE NBU;Lo;0;L;;;;;N;;;;; +A088;YI SYLLABLE NBUP;Lo;0;L;;;;;N;;;;; +A089;YI SYLLABLE NBURX;Lo;0;L;;;;;N;;;;; +A08A;YI SYLLABLE NBUR;Lo;0;L;;;;;N;;;;; +A08B;YI SYLLABLE NBYT;Lo;0;L;;;;;N;;;;; +A08C;YI SYLLABLE NBYX;Lo;0;L;;;;;N;;;;; +A08D;YI SYLLABLE NBY;Lo;0;L;;;;;N;;;;; +A08E;YI SYLLABLE NBYP;Lo;0;L;;;;;N;;;;; +A08F;YI SYLLABLE NBYRX;Lo;0;L;;;;;N;;;;; +A090;YI SYLLABLE NBYR;Lo;0;L;;;;;N;;;;; +A091;YI SYLLABLE HMIT;Lo;0;L;;;;;N;;;;; +A092;YI SYLLABLE HMIX;Lo;0;L;;;;;N;;;;; +A093;YI SYLLABLE HMI;Lo;0;L;;;;;N;;;;; +A094;YI SYLLABLE HMIP;Lo;0;L;;;;;N;;;;; +A095;YI SYLLABLE HMIEX;Lo;0;L;;;;;N;;;;; +A096;YI SYLLABLE HMIE;Lo;0;L;;;;;N;;;;; +A097;YI SYLLABLE HMIEP;Lo;0;L;;;;;N;;;;; +A098;YI SYLLABLE HMAT;Lo;0;L;;;;;N;;;;; +A099;YI SYLLABLE HMAX;Lo;0;L;;;;;N;;;;; +A09A;YI SYLLABLE HMA;Lo;0;L;;;;;N;;;;; +A09B;YI SYLLABLE HMAP;Lo;0;L;;;;;N;;;;; +A09C;YI SYLLABLE HMUOX;Lo;0;L;;;;;N;;;;; +A09D;YI SYLLABLE HMUO;Lo;0;L;;;;;N;;;;; +A09E;YI SYLLABLE HMUOP;Lo;0;L;;;;;N;;;;; +A09F;YI SYLLABLE HMOT;Lo;0;L;;;;;N;;;;; +A0A0;YI SYLLABLE HMOX;Lo;0;L;;;;;N;;;;; +A0A1;YI SYLLABLE HMO;Lo;0;L;;;;;N;;;;; +A0A2;YI SYLLABLE HMOP;Lo;0;L;;;;;N;;;;; +A0A3;YI SYLLABLE HMUT;Lo;0;L;;;;;N;;;;; +A0A4;YI SYLLABLE HMUX;Lo;0;L;;;;;N;;;;; +A0A5;YI SYLLABLE HMU;Lo;0;L;;;;;N;;;;; +A0A6;YI SYLLABLE HMUP;Lo;0;L;;;;;N;;;;; +A0A7;YI SYLLABLE HMURX;Lo;0;L;;;;;N;;;;; +A0A8;YI SYLLABLE HMUR;Lo;0;L;;;;;N;;;;; +A0A9;YI SYLLABLE HMYX;Lo;0;L;;;;;N;;;;; +A0AA;YI SYLLABLE HMY;Lo;0;L;;;;;N;;;;; +A0AB;YI SYLLABLE HMYP;Lo;0;L;;;;;N;;;;; +A0AC;YI SYLLABLE HMYRX;Lo;0;L;;;;;N;;;;; +A0AD;YI SYLLABLE HMYR;Lo;0;L;;;;;N;;;;; +A0AE;YI SYLLABLE MIT;Lo;0;L;;;;;N;;;;; +A0AF;YI SYLLABLE MIX;Lo;0;L;;;;;N;;;;; +A0B0;YI SYLLABLE MI;Lo;0;L;;;;;N;;;;; +A0B1;YI SYLLABLE MIP;Lo;0;L;;;;;N;;;;; +A0B2;YI SYLLABLE MIEX;Lo;0;L;;;;;N;;;;; +A0B3;YI SYLLABLE MIE;Lo;0;L;;;;;N;;;;; +A0B4;YI SYLLABLE MIEP;Lo;0;L;;;;;N;;;;; +A0B5;YI SYLLABLE MAT;Lo;0;L;;;;;N;;;;; +A0B6;YI SYLLABLE MAX;Lo;0;L;;;;;N;;;;; +A0B7;YI SYLLABLE MA;Lo;0;L;;;;;N;;;;; +A0B8;YI SYLLABLE MAP;Lo;0;L;;;;;N;;;;; +A0B9;YI SYLLABLE MUOT;Lo;0;L;;;;;N;;;;; +A0BA;YI SYLLABLE MUOX;Lo;0;L;;;;;N;;;;; +A0BB;YI SYLLABLE MUO;Lo;0;L;;;;;N;;;;; +A0BC;YI SYLLABLE MUOP;Lo;0;L;;;;;N;;;;; +A0BD;YI SYLLABLE MOT;Lo;0;L;;;;;N;;;;; +A0BE;YI SYLLABLE MOX;Lo;0;L;;;;;N;;;;; +A0BF;YI SYLLABLE MO;Lo;0;L;;;;;N;;;;; +A0C0;YI SYLLABLE MOP;Lo;0;L;;;;;N;;;;; +A0C1;YI SYLLABLE MEX;Lo;0;L;;;;;N;;;;; +A0C2;YI SYLLABLE ME;Lo;0;L;;;;;N;;;;; +A0C3;YI SYLLABLE MUT;Lo;0;L;;;;;N;;;;; +A0C4;YI SYLLABLE MUX;Lo;0;L;;;;;N;;;;; +A0C5;YI SYLLABLE MU;Lo;0;L;;;;;N;;;;; +A0C6;YI SYLLABLE MUP;Lo;0;L;;;;;N;;;;; +A0C7;YI SYLLABLE MURX;Lo;0;L;;;;;N;;;;; +A0C8;YI SYLLABLE MUR;Lo;0;L;;;;;N;;;;; +A0C9;YI SYLLABLE MYT;Lo;0;L;;;;;N;;;;; +A0CA;YI SYLLABLE MYX;Lo;0;L;;;;;N;;;;; +A0CB;YI SYLLABLE MY;Lo;0;L;;;;;N;;;;; +A0CC;YI SYLLABLE MYP;Lo;0;L;;;;;N;;;;; +A0CD;YI SYLLABLE FIT;Lo;0;L;;;;;N;;;;; +A0CE;YI SYLLABLE FIX;Lo;0;L;;;;;N;;;;; +A0CF;YI SYLLABLE FI;Lo;0;L;;;;;N;;;;; +A0D0;YI SYLLABLE FIP;Lo;0;L;;;;;N;;;;; +A0D1;YI SYLLABLE FAT;Lo;0;L;;;;;N;;;;; +A0D2;YI SYLLABLE FAX;Lo;0;L;;;;;N;;;;; +A0D3;YI SYLLABLE FA;Lo;0;L;;;;;N;;;;; +A0D4;YI SYLLABLE FAP;Lo;0;L;;;;;N;;;;; +A0D5;YI SYLLABLE FOX;Lo;0;L;;;;;N;;;;; +A0D6;YI SYLLABLE FO;Lo;0;L;;;;;N;;;;; +A0D7;YI SYLLABLE FOP;Lo;0;L;;;;;N;;;;; +A0D8;YI SYLLABLE FUT;Lo;0;L;;;;;N;;;;; +A0D9;YI SYLLABLE FUX;Lo;0;L;;;;;N;;;;; +A0DA;YI SYLLABLE FU;Lo;0;L;;;;;N;;;;; +A0DB;YI SYLLABLE FUP;Lo;0;L;;;;;N;;;;; +A0DC;YI SYLLABLE FURX;Lo;0;L;;;;;N;;;;; +A0DD;YI SYLLABLE FUR;Lo;0;L;;;;;N;;;;; +A0DE;YI SYLLABLE FYT;Lo;0;L;;;;;N;;;;; +A0DF;YI SYLLABLE FYX;Lo;0;L;;;;;N;;;;; +A0E0;YI SYLLABLE FY;Lo;0;L;;;;;N;;;;; +A0E1;YI SYLLABLE FYP;Lo;0;L;;;;;N;;;;; +A0E2;YI SYLLABLE VIT;Lo;0;L;;;;;N;;;;; +A0E3;YI SYLLABLE VIX;Lo;0;L;;;;;N;;;;; +A0E4;YI SYLLABLE VI;Lo;0;L;;;;;N;;;;; +A0E5;YI SYLLABLE VIP;Lo;0;L;;;;;N;;;;; +A0E6;YI SYLLABLE VIET;Lo;0;L;;;;;N;;;;; +A0E7;YI SYLLABLE VIEX;Lo;0;L;;;;;N;;;;; +A0E8;YI SYLLABLE VIE;Lo;0;L;;;;;N;;;;; +A0E9;YI SYLLABLE VIEP;Lo;0;L;;;;;N;;;;; +A0EA;YI SYLLABLE VAT;Lo;0;L;;;;;N;;;;; +A0EB;YI SYLLABLE VAX;Lo;0;L;;;;;N;;;;; +A0EC;YI SYLLABLE VA;Lo;0;L;;;;;N;;;;; +A0ED;YI SYLLABLE VAP;Lo;0;L;;;;;N;;;;; +A0EE;YI SYLLABLE VOT;Lo;0;L;;;;;N;;;;; +A0EF;YI SYLLABLE VOX;Lo;0;L;;;;;N;;;;; +A0F0;YI SYLLABLE VO;Lo;0;L;;;;;N;;;;; +A0F1;YI SYLLABLE VOP;Lo;0;L;;;;;N;;;;; +A0F2;YI SYLLABLE VEX;Lo;0;L;;;;;N;;;;; +A0F3;YI SYLLABLE VEP;Lo;0;L;;;;;N;;;;; +A0F4;YI SYLLABLE VUT;Lo;0;L;;;;;N;;;;; +A0F5;YI SYLLABLE VUX;Lo;0;L;;;;;N;;;;; +A0F6;YI SYLLABLE VU;Lo;0;L;;;;;N;;;;; +A0F7;YI SYLLABLE VUP;Lo;0;L;;;;;N;;;;; +A0F8;YI SYLLABLE VURX;Lo;0;L;;;;;N;;;;; +A0F9;YI SYLLABLE VUR;Lo;0;L;;;;;N;;;;; +A0FA;YI SYLLABLE VYT;Lo;0;L;;;;;N;;;;; +A0FB;YI SYLLABLE VYX;Lo;0;L;;;;;N;;;;; +A0FC;YI SYLLABLE VY;Lo;0;L;;;;;N;;;;; +A0FD;YI SYLLABLE VYP;Lo;0;L;;;;;N;;;;; +A0FE;YI SYLLABLE VYRX;Lo;0;L;;;;;N;;;;; +A0FF;YI SYLLABLE VYR;Lo;0;L;;;;;N;;;;; +A100;YI SYLLABLE DIT;Lo;0;L;;;;;N;;;;; +A101;YI SYLLABLE DIX;Lo;0;L;;;;;N;;;;; +A102;YI SYLLABLE DI;Lo;0;L;;;;;N;;;;; +A103;YI SYLLABLE DIP;Lo;0;L;;;;;N;;;;; +A104;YI SYLLABLE DIEX;Lo;0;L;;;;;N;;;;; +A105;YI SYLLABLE DIE;Lo;0;L;;;;;N;;;;; +A106;YI SYLLABLE DIEP;Lo;0;L;;;;;N;;;;; +A107;YI SYLLABLE DAT;Lo;0;L;;;;;N;;;;; +A108;YI SYLLABLE DAX;Lo;0;L;;;;;N;;;;; +A109;YI SYLLABLE DA;Lo;0;L;;;;;N;;;;; +A10A;YI SYLLABLE DAP;Lo;0;L;;;;;N;;;;; +A10B;YI SYLLABLE DUOX;Lo;0;L;;;;;N;;;;; +A10C;YI SYLLABLE DUO;Lo;0;L;;;;;N;;;;; +A10D;YI SYLLABLE DOT;Lo;0;L;;;;;N;;;;; +A10E;YI SYLLABLE DOX;Lo;0;L;;;;;N;;;;; +A10F;YI SYLLABLE DO;Lo;0;L;;;;;N;;;;; +A110;YI SYLLABLE DOP;Lo;0;L;;;;;N;;;;; +A111;YI SYLLABLE DEX;Lo;0;L;;;;;N;;;;; +A112;YI SYLLABLE DE;Lo;0;L;;;;;N;;;;; +A113;YI SYLLABLE DEP;Lo;0;L;;;;;N;;;;; +A114;YI SYLLABLE DUT;Lo;0;L;;;;;N;;;;; +A115;YI SYLLABLE DUX;Lo;0;L;;;;;N;;;;; +A116;YI SYLLABLE DU;Lo;0;L;;;;;N;;;;; +A117;YI SYLLABLE DUP;Lo;0;L;;;;;N;;;;; +A118;YI SYLLABLE DURX;Lo;0;L;;;;;N;;;;; +A119;YI SYLLABLE DUR;Lo;0;L;;;;;N;;;;; +A11A;YI SYLLABLE TIT;Lo;0;L;;;;;N;;;;; +A11B;YI SYLLABLE TIX;Lo;0;L;;;;;N;;;;; +A11C;YI SYLLABLE TI;Lo;0;L;;;;;N;;;;; +A11D;YI SYLLABLE TIP;Lo;0;L;;;;;N;;;;; +A11E;YI SYLLABLE TIEX;Lo;0;L;;;;;N;;;;; +A11F;YI SYLLABLE TIE;Lo;0;L;;;;;N;;;;; +A120;YI SYLLABLE TIEP;Lo;0;L;;;;;N;;;;; +A121;YI SYLLABLE TAT;Lo;0;L;;;;;N;;;;; +A122;YI SYLLABLE TAX;Lo;0;L;;;;;N;;;;; +A123;YI SYLLABLE TA;Lo;0;L;;;;;N;;;;; +A124;YI SYLLABLE TAP;Lo;0;L;;;;;N;;;;; +A125;YI SYLLABLE TUOT;Lo;0;L;;;;;N;;;;; +A126;YI SYLLABLE TUOX;Lo;0;L;;;;;N;;;;; +A127;YI SYLLABLE TUO;Lo;0;L;;;;;N;;;;; +A128;YI SYLLABLE TUOP;Lo;0;L;;;;;N;;;;; +A129;YI SYLLABLE TOT;Lo;0;L;;;;;N;;;;; +A12A;YI SYLLABLE TOX;Lo;0;L;;;;;N;;;;; +A12B;YI SYLLABLE TO;Lo;0;L;;;;;N;;;;; +A12C;YI SYLLABLE TOP;Lo;0;L;;;;;N;;;;; +A12D;YI SYLLABLE TEX;Lo;0;L;;;;;N;;;;; +A12E;YI SYLLABLE TE;Lo;0;L;;;;;N;;;;; +A12F;YI SYLLABLE TEP;Lo;0;L;;;;;N;;;;; +A130;YI SYLLABLE TUT;Lo;0;L;;;;;N;;;;; +A131;YI SYLLABLE TUX;Lo;0;L;;;;;N;;;;; +A132;YI SYLLABLE TU;Lo;0;L;;;;;N;;;;; +A133;YI SYLLABLE TUP;Lo;0;L;;;;;N;;;;; +A134;YI SYLLABLE TURX;Lo;0;L;;;;;N;;;;; +A135;YI SYLLABLE TUR;Lo;0;L;;;;;N;;;;; +A136;YI SYLLABLE DDIT;Lo;0;L;;;;;N;;;;; +A137;YI SYLLABLE DDIX;Lo;0;L;;;;;N;;;;; +A138;YI SYLLABLE DDI;Lo;0;L;;;;;N;;;;; +A139;YI SYLLABLE DDIP;Lo;0;L;;;;;N;;;;; +A13A;YI SYLLABLE DDIEX;Lo;0;L;;;;;N;;;;; +A13B;YI SYLLABLE DDIE;Lo;0;L;;;;;N;;;;; +A13C;YI SYLLABLE DDIEP;Lo;0;L;;;;;N;;;;; +A13D;YI SYLLABLE DDAT;Lo;0;L;;;;;N;;;;; +A13E;YI SYLLABLE DDAX;Lo;0;L;;;;;N;;;;; +A13F;YI SYLLABLE DDA;Lo;0;L;;;;;N;;;;; +A140;YI SYLLABLE DDAP;Lo;0;L;;;;;N;;;;; +A141;YI SYLLABLE DDUOX;Lo;0;L;;;;;N;;;;; +A142;YI SYLLABLE DDUO;Lo;0;L;;;;;N;;;;; +A143;YI SYLLABLE DDUOP;Lo;0;L;;;;;N;;;;; +A144;YI SYLLABLE DDOT;Lo;0;L;;;;;N;;;;; +A145;YI SYLLABLE DDOX;Lo;0;L;;;;;N;;;;; +A146;YI SYLLABLE DDO;Lo;0;L;;;;;N;;;;; +A147;YI SYLLABLE DDOP;Lo;0;L;;;;;N;;;;; +A148;YI SYLLABLE DDEX;Lo;0;L;;;;;N;;;;; +A149;YI SYLLABLE DDE;Lo;0;L;;;;;N;;;;; +A14A;YI SYLLABLE DDEP;Lo;0;L;;;;;N;;;;; +A14B;YI SYLLABLE DDUT;Lo;0;L;;;;;N;;;;; +A14C;YI SYLLABLE DDUX;Lo;0;L;;;;;N;;;;; +A14D;YI SYLLABLE DDU;Lo;0;L;;;;;N;;;;; +A14E;YI SYLLABLE DDUP;Lo;0;L;;;;;N;;;;; +A14F;YI SYLLABLE DDURX;Lo;0;L;;;;;N;;;;; +A150;YI SYLLABLE DDUR;Lo;0;L;;;;;N;;;;; +A151;YI SYLLABLE NDIT;Lo;0;L;;;;;N;;;;; +A152;YI SYLLABLE NDIX;Lo;0;L;;;;;N;;;;; +A153;YI SYLLABLE NDI;Lo;0;L;;;;;N;;;;; +A154;YI SYLLABLE NDIP;Lo;0;L;;;;;N;;;;; +A155;YI SYLLABLE NDIEX;Lo;0;L;;;;;N;;;;; +A156;YI SYLLABLE NDIE;Lo;0;L;;;;;N;;;;; +A157;YI SYLLABLE NDAT;Lo;0;L;;;;;N;;;;; +A158;YI SYLLABLE NDAX;Lo;0;L;;;;;N;;;;; +A159;YI SYLLABLE NDA;Lo;0;L;;;;;N;;;;; +A15A;YI SYLLABLE NDAP;Lo;0;L;;;;;N;;;;; +A15B;YI SYLLABLE NDOT;Lo;0;L;;;;;N;;;;; +A15C;YI SYLLABLE NDOX;Lo;0;L;;;;;N;;;;; +A15D;YI SYLLABLE NDO;Lo;0;L;;;;;N;;;;; +A15E;YI SYLLABLE NDOP;Lo;0;L;;;;;N;;;;; +A15F;YI SYLLABLE NDEX;Lo;0;L;;;;;N;;;;; +A160;YI SYLLABLE NDE;Lo;0;L;;;;;N;;;;; +A161;YI SYLLABLE NDEP;Lo;0;L;;;;;N;;;;; +A162;YI SYLLABLE NDUT;Lo;0;L;;;;;N;;;;; +A163;YI SYLLABLE NDUX;Lo;0;L;;;;;N;;;;; +A164;YI SYLLABLE NDU;Lo;0;L;;;;;N;;;;; +A165;YI SYLLABLE NDUP;Lo;0;L;;;;;N;;;;; +A166;YI SYLLABLE NDURX;Lo;0;L;;;;;N;;;;; +A167;YI SYLLABLE NDUR;Lo;0;L;;;;;N;;;;; +A168;YI SYLLABLE HNIT;Lo;0;L;;;;;N;;;;; +A169;YI SYLLABLE HNIX;Lo;0;L;;;;;N;;;;; +A16A;YI SYLLABLE HNI;Lo;0;L;;;;;N;;;;; +A16B;YI SYLLABLE HNIP;Lo;0;L;;;;;N;;;;; +A16C;YI SYLLABLE HNIET;Lo;0;L;;;;;N;;;;; +A16D;YI SYLLABLE HNIEX;Lo;0;L;;;;;N;;;;; +A16E;YI SYLLABLE HNIE;Lo;0;L;;;;;N;;;;; +A16F;YI SYLLABLE HNIEP;Lo;0;L;;;;;N;;;;; +A170;YI SYLLABLE HNAT;Lo;0;L;;;;;N;;;;; +A171;YI SYLLABLE HNAX;Lo;0;L;;;;;N;;;;; +A172;YI SYLLABLE HNA;Lo;0;L;;;;;N;;;;; +A173;YI SYLLABLE HNAP;Lo;0;L;;;;;N;;;;; +A174;YI SYLLABLE HNUOX;Lo;0;L;;;;;N;;;;; +A175;YI SYLLABLE HNUO;Lo;0;L;;;;;N;;;;; +A176;YI SYLLABLE HNOT;Lo;0;L;;;;;N;;;;; +A177;YI SYLLABLE HNOX;Lo;0;L;;;;;N;;;;; +A178;YI SYLLABLE HNOP;Lo;0;L;;;;;N;;;;; +A179;YI SYLLABLE HNEX;Lo;0;L;;;;;N;;;;; +A17A;YI SYLLABLE HNE;Lo;0;L;;;;;N;;;;; +A17B;YI SYLLABLE HNEP;Lo;0;L;;;;;N;;;;; +A17C;YI SYLLABLE HNUT;Lo;0;L;;;;;N;;;;; +A17D;YI SYLLABLE NIT;Lo;0;L;;;;;N;;;;; +A17E;YI SYLLABLE NIX;Lo;0;L;;;;;N;;;;; +A17F;YI SYLLABLE NI;Lo;0;L;;;;;N;;;;; +A180;YI SYLLABLE NIP;Lo;0;L;;;;;N;;;;; +A181;YI SYLLABLE NIEX;Lo;0;L;;;;;N;;;;; +A182;YI SYLLABLE NIE;Lo;0;L;;;;;N;;;;; +A183;YI SYLLABLE NIEP;Lo;0;L;;;;;N;;;;; +A184;YI SYLLABLE NAX;Lo;0;L;;;;;N;;;;; +A185;YI SYLLABLE NA;Lo;0;L;;;;;N;;;;; +A186;YI SYLLABLE NAP;Lo;0;L;;;;;N;;;;; +A187;YI SYLLABLE NUOX;Lo;0;L;;;;;N;;;;; +A188;YI SYLLABLE NUO;Lo;0;L;;;;;N;;;;; +A189;YI SYLLABLE NUOP;Lo;0;L;;;;;N;;;;; +A18A;YI SYLLABLE NOT;Lo;0;L;;;;;N;;;;; +A18B;YI SYLLABLE NOX;Lo;0;L;;;;;N;;;;; +A18C;YI SYLLABLE NO;Lo;0;L;;;;;N;;;;; +A18D;YI SYLLABLE NOP;Lo;0;L;;;;;N;;;;; +A18E;YI SYLLABLE NEX;Lo;0;L;;;;;N;;;;; +A18F;YI SYLLABLE NE;Lo;0;L;;;;;N;;;;; +A190;YI SYLLABLE NEP;Lo;0;L;;;;;N;;;;; +A191;YI SYLLABLE NUT;Lo;0;L;;;;;N;;;;; +A192;YI SYLLABLE NUX;Lo;0;L;;;;;N;;;;; +A193;YI SYLLABLE NU;Lo;0;L;;;;;N;;;;; +A194;YI SYLLABLE NUP;Lo;0;L;;;;;N;;;;; +A195;YI SYLLABLE NURX;Lo;0;L;;;;;N;;;;; +A196;YI SYLLABLE NUR;Lo;0;L;;;;;N;;;;; +A197;YI SYLLABLE HLIT;Lo;0;L;;;;;N;;;;; +A198;YI SYLLABLE HLIX;Lo;0;L;;;;;N;;;;; +A199;YI SYLLABLE HLI;Lo;0;L;;;;;N;;;;; +A19A;YI SYLLABLE HLIP;Lo;0;L;;;;;N;;;;; +A19B;YI SYLLABLE HLIEX;Lo;0;L;;;;;N;;;;; +A19C;YI SYLLABLE HLIE;Lo;0;L;;;;;N;;;;; +A19D;YI SYLLABLE HLIEP;Lo;0;L;;;;;N;;;;; +A19E;YI SYLLABLE HLAT;Lo;0;L;;;;;N;;;;; +A19F;YI SYLLABLE HLAX;Lo;0;L;;;;;N;;;;; +A1A0;YI SYLLABLE HLA;Lo;0;L;;;;;N;;;;; +A1A1;YI SYLLABLE HLAP;Lo;0;L;;;;;N;;;;; +A1A2;YI SYLLABLE HLUOX;Lo;0;L;;;;;N;;;;; +A1A3;YI SYLLABLE HLUO;Lo;0;L;;;;;N;;;;; +A1A4;YI SYLLABLE HLUOP;Lo;0;L;;;;;N;;;;; +A1A5;YI SYLLABLE HLOX;Lo;0;L;;;;;N;;;;; +A1A6;YI SYLLABLE HLO;Lo;0;L;;;;;N;;;;; +A1A7;YI SYLLABLE HLOP;Lo;0;L;;;;;N;;;;; +A1A8;YI SYLLABLE HLEX;Lo;0;L;;;;;N;;;;; +A1A9;YI SYLLABLE HLE;Lo;0;L;;;;;N;;;;; +A1AA;YI SYLLABLE HLEP;Lo;0;L;;;;;N;;;;; +A1AB;YI SYLLABLE HLUT;Lo;0;L;;;;;N;;;;; +A1AC;YI SYLLABLE HLUX;Lo;0;L;;;;;N;;;;; +A1AD;YI SYLLABLE HLU;Lo;0;L;;;;;N;;;;; +A1AE;YI SYLLABLE HLUP;Lo;0;L;;;;;N;;;;; +A1AF;YI SYLLABLE HLURX;Lo;0;L;;;;;N;;;;; +A1B0;YI SYLLABLE HLUR;Lo;0;L;;;;;N;;;;; +A1B1;YI SYLLABLE HLYT;Lo;0;L;;;;;N;;;;; +A1B2;YI SYLLABLE HLYX;Lo;0;L;;;;;N;;;;; +A1B3;YI SYLLABLE HLY;Lo;0;L;;;;;N;;;;; +A1B4;YI SYLLABLE HLYP;Lo;0;L;;;;;N;;;;; +A1B5;YI SYLLABLE HLYRX;Lo;0;L;;;;;N;;;;; +A1B6;YI SYLLABLE HLYR;Lo;0;L;;;;;N;;;;; +A1B7;YI SYLLABLE LIT;Lo;0;L;;;;;N;;;;; +A1B8;YI SYLLABLE LIX;Lo;0;L;;;;;N;;;;; +A1B9;YI SYLLABLE LI;Lo;0;L;;;;;N;;;;; +A1BA;YI SYLLABLE LIP;Lo;0;L;;;;;N;;;;; +A1BB;YI SYLLABLE LIET;Lo;0;L;;;;;N;;;;; +A1BC;YI SYLLABLE LIEX;Lo;0;L;;;;;N;;;;; +A1BD;YI SYLLABLE LIE;Lo;0;L;;;;;N;;;;; +A1BE;YI SYLLABLE LIEP;Lo;0;L;;;;;N;;;;; +A1BF;YI SYLLABLE LAT;Lo;0;L;;;;;N;;;;; +A1C0;YI SYLLABLE LAX;Lo;0;L;;;;;N;;;;; +A1C1;YI SYLLABLE LA;Lo;0;L;;;;;N;;;;; +A1C2;YI SYLLABLE LAP;Lo;0;L;;;;;N;;;;; +A1C3;YI SYLLABLE LUOT;Lo;0;L;;;;;N;;;;; +A1C4;YI SYLLABLE LUOX;Lo;0;L;;;;;N;;;;; +A1C5;YI SYLLABLE LUO;Lo;0;L;;;;;N;;;;; +A1C6;YI SYLLABLE LUOP;Lo;0;L;;;;;N;;;;; +A1C7;YI SYLLABLE LOT;Lo;0;L;;;;;N;;;;; +A1C8;YI SYLLABLE LOX;Lo;0;L;;;;;N;;;;; +A1C9;YI SYLLABLE LO;Lo;0;L;;;;;N;;;;; +A1CA;YI SYLLABLE LOP;Lo;0;L;;;;;N;;;;; +A1CB;YI SYLLABLE LEX;Lo;0;L;;;;;N;;;;; +A1CC;YI SYLLABLE LE;Lo;0;L;;;;;N;;;;; +A1CD;YI SYLLABLE LEP;Lo;0;L;;;;;N;;;;; +A1CE;YI SYLLABLE LUT;Lo;0;L;;;;;N;;;;; +A1CF;YI SYLLABLE LUX;Lo;0;L;;;;;N;;;;; +A1D0;YI SYLLABLE LU;Lo;0;L;;;;;N;;;;; +A1D1;YI SYLLABLE LUP;Lo;0;L;;;;;N;;;;; +A1D2;YI SYLLABLE LURX;Lo;0;L;;;;;N;;;;; +A1D3;YI SYLLABLE LUR;Lo;0;L;;;;;N;;;;; +A1D4;YI SYLLABLE LYT;Lo;0;L;;;;;N;;;;; +A1D5;YI SYLLABLE LYX;Lo;0;L;;;;;N;;;;; +A1D6;YI SYLLABLE LY;Lo;0;L;;;;;N;;;;; +A1D7;YI SYLLABLE LYP;Lo;0;L;;;;;N;;;;; +A1D8;YI SYLLABLE LYRX;Lo;0;L;;;;;N;;;;; +A1D9;YI SYLLABLE LYR;Lo;0;L;;;;;N;;;;; +A1DA;YI SYLLABLE GIT;Lo;0;L;;;;;N;;;;; +A1DB;YI SYLLABLE GIX;Lo;0;L;;;;;N;;;;; +A1DC;YI SYLLABLE GI;Lo;0;L;;;;;N;;;;; +A1DD;YI SYLLABLE GIP;Lo;0;L;;;;;N;;;;; +A1DE;YI SYLLABLE GIET;Lo;0;L;;;;;N;;;;; +A1DF;YI SYLLABLE GIEX;Lo;0;L;;;;;N;;;;; +A1E0;YI SYLLABLE GIE;Lo;0;L;;;;;N;;;;; +A1E1;YI SYLLABLE GIEP;Lo;0;L;;;;;N;;;;; +A1E2;YI SYLLABLE GAT;Lo;0;L;;;;;N;;;;; +A1E3;YI SYLLABLE GAX;Lo;0;L;;;;;N;;;;; +A1E4;YI SYLLABLE GA;Lo;0;L;;;;;N;;;;; +A1E5;YI SYLLABLE GAP;Lo;0;L;;;;;N;;;;; +A1E6;YI SYLLABLE GUOT;Lo;0;L;;;;;N;;;;; +A1E7;YI SYLLABLE GUOX;Lo;0;L;;;;;N;;;;; +A1E8;YI SYLLABLE GUO;Lo;0;L;;;;;N;;;;; +A1E9;YI SYLLABLE GUOP;Lo;0;L;;;;;N;;;;; +A1EA;YI SYLLABLE GOT;Lo;0;L;;;;;N;;;;; +A1EB;YI SYLLABLE GOX;Lo;0;L;;;;;N;;;;; +A1EC;YI SYLLABLE GO;Lo;0;L;;;;;N;;;;; +A1ED;YI SYLLABLE GOP;Lo;0;L;;;;;N;;;;; +A1EE;YI SYLLABLE GET;Lo;0;L;;;;;N;;;;; +A1EF;YI SYLLABLE GEX;Lo;0;L;;;;;N;;;;; +A1F0;YI SYLLABLE GE;Lo;0;L;;;;;N;;;;; +A1F1;YI SYLLABLE GEP;Lo;0;L;;;;;N;;;;; +A1F2;YI SYLLABLE GUT;Lo;0;L;;;;;N;;;;; +A1F3;YI SYLLABLE GUX;Lo;0;L;;;;;N;;;;; +A1F4;YI SYLLABLE GU;Lo;0;L;;;;;N;;;;; +A1F5;YI SYLLABLE GUP;Lo;0;L;;;;;N;;;;; +A1F6;YI SYLLABLE GURX;Lo;0;L;;;;;N;;;;; +A1F7;YI SYLLABLE GUR;Lo;0;L;;;;;N;;;;; +A1F8;YI SYLLABLE KIT;Lo;0;L;;;;;N;;;;; +A1F9;YI SYLLABLE KIX;Lo;0;L;;;;;N;;;;; +A1FA;YI SYLLABLE KI;Lo;0;L;;;;;N;;;;; +A1FB;YI SYLLABLE KIP;Lo;0;L;;;;;N;;;;; +A1FC;YI SYLLABLE KIEX;Lo;0;L;;;;;N;;;;; +A1FD;YI SYLLABLE KIE;Lo;0;L;;;;;N;;;;; +A1FE;YI SYLLABLE KIEP;Lo;0;L;;;;;N;;;;; +A1FF;YI SYLLABLE KAT;Lo;0;L;;;;;N;;;;; +A200;YI SYLLABLE KAX;Lo;0;L;;;;;N;;;;; +A201;YI SYLLABLE KA;Lo;0;L;;;;;N;;;;; +A202;YI SYLLABLE KAP;Lo;0;L;;;;;N;;;;; +A203;YI SYLLABLE KUOX;Lo;0;L;;;;;N;;;;; +A204;YI SYLLABLE KUO;Lo;0;L;;;;;N;;;;; +A205;YI SYLLABLE KUOP;Lo;0;L;;;;;N;;;;; +A206;YI SYLLABLE KOT;Lo;0;L;;;;;N;;;;; +A207;YI SYLLABLE KOX;Lo;0;L;;;;;N;;;;; +A208;YI SYLLABLE KO;Lo;0;L;;;;;N;;;;; +A209;YI SYLLABLE KOP;Lo;0;L;;;;;N;;;;; +A20A;YI SYLLABLE KET;Lo;0;L;;;;;N;;;;; +A20B;YI SYLLABLE KEX;Lo;0;L;;;;;N;;;;; +A20C;YI SYLLABLE KE;Lo;0;L;;;;;N;;;;; +A20D;YI SYLLABLE KEP;Lo;0;L;;;;;N;;;;; +A20E;YI SYLLABLE KUT;Lo;0;L;;;;;N;;;;; +A20F;YI SYLLABLE KUX;Lo;0;L;;;;;N;;;;; +A210;YI SYLLABLE KU;Lo;0;L;;;;;N;;;;; +A211;YI SYLLABLE KUP;Lo;0;L;;;;;N;;;;; +A212;YI SYLLABLE KURX;Lo;0;L;;;;;N;;;;; +A213;YI SYLLABLE KUR;Lo;0;L;;;;;N;;;;; +A214;YI SYLLABLE GGIT;Lo;0;L;;;;;N;;;;; +A215;YI SYLLABLE GGIX;Lo;0;L;;;;;N;;;;; +A216;YI SYLLABLE GGI;Lo;0;L;;;;;N;;;;; +A217;YI SYLLABLE GGIEX;Lo;0;L;;;;;N;;;;; +A218;YI SYLLABLE GGIE;Lo;0;L;;;;;N;;;;; +A219;YI SYLLABLE GGIEP;Lo;0;L;;;;;N;;;;; +A21A;YI SYLLABLE GGAT;Lo;0;L;;;;;N;;;;; +A21B;YI SYLLABLE GGAX;Lo;0;L;;;;;N;;;;; +A21C;YI SYLLABLE GGA;Lo;0;L;;;;;N;;;;; +A21D;YI SYLLABLE GGAP;Lo;0;L;;;;;N;;;;; +A21E;YI SYLLABLE GGUOT;Lo;0;L;;;;;N;;;;; +A21F;YI SYLLABLE GGUOX;Lo;0;L;;;;;N;;;;; +A220;YI SYLLABLE GGUO;Lo;0;L;;;;;N;;;;; +A221;YI SYLLABLE GGUOP;Lo;0;L;;;;;N;;;;; +A222;YI SYLLABLE GGOT;Lo;0;L;;;;;N;;;;; +A223;YI SYLLABLE GGOX;Lo;0;L;;;;;N;;;;; +A224;YI SYLLABLE GGO;Lo;0;L;;;;;N;;;;; +A225;YI SYLLABLE GGOP;Lo;0;L;;;;;N;;;;; +A226;YI SYLLABLE GGET;Lo;0;L;;;;;N;;;;; +A227;YI SYLLABLE GGEX;Lo;0;L;;;;;N;;;;; +A228;YI SYLLABLE GGE;Lo;0;L;;;;;N;;;;; +A229;YI SYLLABLE GGEP;Lo;0;L;;;;;N;;;;; +A22A;YI SYLLABLE GGUT;Lo;0;L;;;;;N;;;;; +A22B;YI SYLLABLE GGUX;Lo;0;L;;;;;N;;;;; +A22C;YI SYLLABLE GGU;Lo;0;L;;;;;N;;;;; +A22D;YI SYLLABLE GGUP;Lo;0;L;;;;;N;;;;; +A22E;YI SYLLABLE GGURX;Lo;0;L;;;;;N;;;;; +A22F;YI SYLLABLE GGUR;Lo;0;L;;;;;N;;;;; +A230;YI SYLLABLE MGIEX;Lo;0;L;;;;;N;;;;; +A231;YI SYLLABLE MGIE;Lo;0;L;;;;;N;;;;; +A232;YI SYLLABLE MGAT;Lo;0;L;;;;;N;;;;; +A233;YI SYLLABLE MGAX;Lo;0;L;;;;;N;;;;; +A234;YI SYLLABLE MGA;Lo;0;L;;;;;N;;;;; +A235;YI SYLLABLE MGAP;Lo;0;L;;;;;N;;;;; +A236;YI SYLLABLE MGUOX;Lo;0;L;;;;;N;;;;; +A237;YI SYLLABLE MGUO;Lo;0;L;;;;;N;;;;; +A238;YI SYLLABLE MGUOP;Lo;0;L;;;;;N;;;;; +A239;YI SYLLABLE MGOT;Lo;0;L;;;;;N;;;;; +A23A;YI SYLLABLE MGOX;Lo;0;L;;;;;N;;;;; +A23B;YI SYLLABLE MGO;Lo;0;L;;;;;N;;;;; +A23C;YI SYLLABLE MGOP;Lo;0;L;;;;;N;;;;; +A23D;YI SYLLABLE MGEX;Lo;0;L;;;;;N;;;;; +A23E;YI SYLLABLE MGE;Lo;0;L;;;;;N;;;;; +A23F;YI SYLLABLE MGEP;Lo;0;L;;;;;N;;;;; +A240;YI SYLLABLE MGUT;Lo;0;L;;;;;N;;;;; +A241;YI SYLLABLE MGUX;Lo;0;L;;;;;N;;;;; +A242;YI SYLLABLE MGU;Lo;0;L;;;;;N;;;;; +A243;YI SYLLABLE MGUP;Lo;0;L;;;;;N;;;;; +A244;YI SYLLABLE MGURX;Lo;0;L;;;;;N;;;;; +A245;YI SYLLABLE MGUR;Lo;0;L;;;;;N;;;;; +A246;YI SYLLABLE HXIT;Lo;0;L;;;;;N;;;;; +A247;YI SYLLABLE HXIX;Lo;0;L;;;;;N;;;;; +A248;YI SYLLABLE HXI;Lo;0;L;;;;;N;;;;; +A249;YI SYLLABLE HXIP;Lo;0;L;;;;;N;;;;; +A24A;YI SYLLABLE HXIET;Lo;0;L;;;;;N;;;;; +A24B;YI SYLLABLE HXIEX;Lo;0;L;;;;;N;;;;; +A24C;YI SYLLABLE HXIE;Lo;0;L;;;;;N;;;;; +A24D;YI SYLLABLE HXIEP;Lo;0;L;;;;;N;;;;; +A24E;YI SYLLABLE HXAT;Lo;0;L;;;;;N;;;;; +A24F;YI SYLLABLE HXAX;Lo;0;L;;;;;N;;;;; +A250;YI SYLLABLE HXA;Lo;0;L;;;;;N;;;;; +A251;YI SYLLABLE HXAP;Lo;0;L;;;;;N;;;;; +A252;YI SYLLABLE HXUOT;Lo;0;L;;;;;N;;;;; +A253;YI SYLLABLE HXUOX;Lo;0;L;;;;;N;;;;; +A254;YI SYLLABLE HXUO;Lo;0;L;;;;;N;;;;; +A255;YI SYLLABLE HXUOP;Lo;0;L;;;;;N;;;;; +A256;YI SYLLABLE HXOT;Lo;0;L;;;;;N;;;;; +A257;YI SYLLABLE HXOX;Lo;0;L;;;;;N;;;;; +A258;YI SYLLABLE HXO;Lo;0;L;;;;;N;;;;; +A259;YI SYLLABLE HXOP;Lo;0;L;;;;;N;;;;; +A25A;YI SYLLABLE HXEX;Lo;0;L;;;;;N;;;;; +A25B;YI SYLLABLE HXE;Lo;0;L;;;;;N;;;;; +A25C;YI SYLLABLE HXEP;Lo;0;L;;;;;N;;;;; +A25D;YI SYLLABLE NGIEX;Lo;0;L;;;;;N;;;;; +A25E;YI SYLLABLE NGIE;Lo;0;L;;;;;N;;;;; +A25F;YI SYLLABLE NGIEP;Lo;0;L;;;;;N;;;;; +A260;YI SYLLABLE NGAT;Lo;0;L;;;;;N;;;;; +A261;YI SYLLABLE NGAX;Lo;0;L;;;;;N;;;;; +A262;YI SYLLABLE NGA;Lo;0;L;;;;;N;;;;; +A263;YI SYLLABLE NGAP;Lo;0;L;;;;;N;;;;; +A264;YI SYLLABLE NGUOT;Lo;0;L;;;;;N;;;;; +A265;YI SYLLABLE NGUOX;Lo;0;L;;;;;N;;;;; +A266;YI SYLLABLE NGUO;Lo;0;L;;;;;N;;;;; +A267;YI SYLLABLE NGOT;Lo;0;L;;;;;N;;;;; +A268;YI SYLLABLE NGOX;Lo;0;L;;;;;N;;;;; +A269;YI SYLLABLE NGO;Lo;0;L;;;;;N;;;;; +A26A;YI SYLLABLE NGOP;Lo;0;L;;;;;N;;;;; +A26B;YI SYLLABLE NGEX;Lo;0;L;;;;;N;;;;; +A26C;YI SYLLABLE NGE;Lo;0;L;;;;;N;;;;; +A26D;YI SYLLABLE NGEP;Lo;0;L;;;;;N;;;;; +A26E;YI SYLLABLE HIT;Lo;0;L;;;;;N;;;;; +A26F;YI SYLLABLE HIEX;Lo;0;L;;;;;N;;;;; +A270;YI SYLLABLE HIE;Lo;0;L;;;;;N;;;;; +A271;YI SYLLABLE HAT;Lo;0;L;;;;;N;;;;; +A272;YI SYLLABLE HAX;Lo;0;L;;;;;N;;;;; +A273;YI SYLLABLE HA;Lo;0;L;;;;;N;;;;; +A274;YI SYLLABLE HAP;Lo;0;L;;;;;N;;;;; +A275;YI SYLLABLE HUOT;Lo;0;L;;;;;N;;;;; +A276;YI SYLLABLE HUOX;Lo;0;L;;;;;N;;;;; +A277;YI SYLLABLE HUO;Lo;0;L;;;;;N;;;;; +A278;YI SYLLABLE HUOP;Lo;0;L;;;;;N;;;;; +A279;YI SYLLABLE HOT;Lo;0;L;;;;;N;;;;; +A27A;YI SYLLABLE HOX;Lo;0;L;;;;;N;;;;; +A27B;YI SYLLABLE HO;Lo;0;L;;;;;N;;;;; +A27C;YI SYLLABLE HOP;Lo;0;L;;;;;N;;;;; +A27D;YI SYLLABLE HEX;Lo;0;L;;;;;N;;;;; +A27E;YI SYLLABLE HE;Lo;0;L;;;;;N;;;;; +A27F;YI SYLLABLE HEP;Lo;0;L;;;;;N;;;;; +A280;YI SYLLABLE WAT;Lo;0;L;;;;;N;;;;; +A281;YI SYLLABLE WAX;Lo;0;L;;;;;N;;;;; +A282;YI SYLLABLE WA;Lo;0;L;;;;;N;;;;; +A283;YI SYLLABLE WAP;Lo;0;L;;;;;N;;;;; +A284;YI SYLLABLE WUOX;Lo;0;L;;;;;N;;;;; +A285;YI SYLLABLE WUO;Lo;0;L;;;;;N;;;;; +A286;YI SYLLABLE WUOP;Lo;0;L;;;;;N;;;;; +A287;YI SYLLABLE WOX;Lo;0;L;;;;;N;;;;; +A288;YI SYLLABLE WO;Lo;0;L;;;;;N;;;;; +A289;YI SYLLABLE WOP;Lo;0;L;;;;;N;;;;; +A28A;YI SYLLABLE WEX;Lo;0;L;;;;;N;;;;; +A28B;YI SYLLABLE WE;Lo;0;L;;;;;N;;;;; +A28C;YI SYLLABLE WEP;Lo;0;L;;;;;N;;;;; +A28D;YI SYLLABLE ZIT;Lo;0;L;;;;;N;;;;; +A28E;YI SYLLABLE ZIX;Lo;0;L;;;;;N;;;;; +A28F;YI SYLLABLE ZI;Lo;0;L;;;;;N;;;;; +A290;YI SYLLABLE ZIP;Lo;0;L;;;;;N;;;;; +A291;YI SYLLABLE ZIEX;Lo;0;L;;;;;N;;;;; +A292;YI SYLLABLE ZIE;Lo;0;L;;;;;N;;;;; +A293;YI SYLLABLE ZIEP;Lo;0;L;;;;;N;;;;; +A294;YI SYLLABLE ZAT;Lo;0;L;;;;;N;;;;; +A295;YI SYLLABLE ZAX;Lo;0;L;;;;;N;;;;; +A296;YI SYLLABLE ZA;Lo;0;L;;;;;N;;;;; +A297;YI SYLLABLE ZAP;Lo;0;L;;;;;N;;;;; +A298;YI SYLLABLE ZUOX;Lo;0;L;;;;;N;;;;; +A299;YI SYLLABLE ZUO;Lo;0;L;;;;;N;;;;; +A29A;YI SYLLABLE ZUOP;Lo;0;L;;;;;N;;;;; +A29B;YI SYLLABLE ZOT;Lo;0;L;;;;;N;;;;; +A29C;YI SYLLABLE ZOX;Lo;0;L;;;;;N;;;;; +A29D;YI SYLLABLE ZO;Lo;0;L;;;;;N;;;;; +A29E;YI SYLLABLE ZOP;Lo;0;L;;;;;N;;;;; +A29F;YI SYLLABLE ZEX;Lo;0;L;;;;;N;;;;; +A2A0;YI SYLLABLE ZE;Lo;0;L;;;;;N;;;;; +A2A1;YI SYLLABLE ZEP;Lo;0;L;;;;;N;;;;; +A2A2;YI SYLLABLE ZUT;Lo;0;L;;;;;N;;;;; +A2A3;YI SYLLABLE ZUX;Lo;0;L;;;;;N;;;;; +A2A4;YI SYLLABLE ZU;Lo;0;L;;;;;N;;;;; +A2A5;YI SYLLABLE ZUP;Lo;0;L;;;;;N;;;;; +A2A6;YI SYLLABLE ZURX;Lo;0;L;;;;;N;;;;; +A2A7;YI SYLLABLE ZUR;Lo;0;L;;;;;N;;;;; +A2A8;YI SYLLABLE ZYT;Lo;0;L;;;;;N;;;;; +A2A9;YI SYLLABLE ZYX;Lo;0;L;;;;;N;;;;; +A2AA;YI SYLLABLE ZY;Lo;0;L;;;;;N;;;;; +A2AB;YI SYLLABLE ZYP;Lo;0;L;;;;;N;;;;; +A2AC;YI SYLLABLE ZYRX;Lo;0;L;;;;;N;;;;; +A2AD;YI SYLLABLE ZYR;Lo;0;L;;;;;N;;;;; +A2AE;YI SYLLABLE CIT;Lo;0;L;;;;;N;;;;; +A2AF;YI SYLLABLE CIX;Lo;0;L;;;;;N;;;;; +A2B0;YI SYLLABLE CI;Lo;0;L;;;;;N;;;;; +A2B1;YI SYLLABLE CIP;Lo;0;L;;;;;N;;;;; +A2B2;YI SYLLABLE CIET;Lo;0;L;;;;;N;;;;; +A2B3;YI SYLLABLE CIEX;Lo;0;L;;;;;N;;;;; +A2B4;YI SYLLABLE CIE;Lo;0;L;;;;;N;;;;; +A2B5;YI SYLLABLE CIEP;Lo;0;L;;;;;N;;;;; +A2B6;YI SYLLABLE CAT;Lo;0;L;;;;;N;;;;; +A2B7;YI SYLLABLE CAX;Lo;0;L;;;;;N;;;;; +A2B8;YI SYLLABLE CA;Lo;0;L;;;;;N;;;;; +A2B9;YI SYLLABLE CAP;Lo;0;L;;;;;N;;;;; +A2BA;YI SYLLABLE CUOX;Lo;0;L;;;;;N;;;;; +A2BB;YI SYLLABLE CUO;Lo;0;L;;;;;N;;;;; +A2BC;YI SYLLABLE CUOP;Lo;0;L;;;;;N;;;;; +A2BD;YI SYLLABLE COT;Lo;0;L;;;;;N;;;;; +A2BE;YI SYLLABLE COX;Lo;0;L;;;;;N;;;;; +A2BF;YI SYLLABLE CO;Lo;0;L;;;;;N;;;;; +A2C0;YI SYLLABLE COP;Lo;0;L;;;;;N;;;;; +A2C1;YI SYLLABLE CEX;Lo;0;L;;;;;N;;;;; +A2C2;YI SYLLABLE CE;Lo;0;L;;;;;N;;;;; +A2C3;YI SYLLABLE CEP;Lo;0;L;;;;;N;;;;; +A2C4;YI SYLLABLE CUT;Lo;0;L;;;;;N;;;;; +A2C5;YI SYLLABLE CUX;Lo;0;L;;;;;N;;;;; +A2C6;YI SYLLABLE CU;Lo;0;L;;;;;N;;;;; +A2C7;YI SYLLABLE CUP;Lo;0;L;;;;;N;;;;; +A2C8;YI SYLLABLE CURX;Lo;0;L;;;;;N;;;;; +A2C9;YI SYLLABLE CUR;Lo;0;L;;;;;N;;;;; +A2CA;YI SYLLABLE CYT;Lo;0;L;;;;;N;;;;; +A2CB;YI SYLLABLE CYX;Lo;0;L;;;;;N;;;;; +A2CC;YI SYLLABLE CY;Lo;0;L;;;;;N;;;;; +A2CD;YI SYLLABLE CYP;Lo;0;L;;;;;N;;;;; +A2CE;YI SYLLABLE CYRX;Lo;0;L;;;;;N;;;;; +A2CF;YI SYLLABLE CYR;Lo;0;L;;;;;N;;;;; +A2D0;YI SYLLABLE ZZIT;Lo;0;L;;;;;N;;;;; +A2D1;YI SYLLABLE ZZIX;Lo;0;L;;;;;N;;;;; +A2D2;YI SYLLABLE ZZI;Lo;0;L;;;;;N;;;;; +A2D3;YI SYLLABLE ZZIP;Lo;0;L;;;;;N;;;;; +A2D4;YI SYLLABLE ZZIET;Lo;0;L;;;;;N;;;;; +A2D5;YI SYLLABLE ZZIEX;Lo;0;L;;;;;N;;;;; +A2D6;YI SYLLABLE ZZIE;Lo;0;L;;;;;N;;;;; +A2D7;YI SYLLABLE ZZIEP;Lo;0;L;;;;;N;;;;; +A2D8;YI SYLLABLE ZZAT;Lo;0;L;;;;;N;;;;; +A2D9;YI SYLLABLE ZZAX;Lo;0;L;;;;;N;;;;; +A2DA;YI SYLLABLE ZZA;Lo;0;L;;;;;N;;;;; +A2DB;YI SYLLABLE ZZAP;Lo;0;L;;;;;N;;;;; +A2DC;YI SYLLABLE ZZOX;Lo;0;L;;;;;N;;;;; +A2DD;YI SYLLABLE ZZO;Lo;0;L;;;;;N;;;;; +A2DE;YI SYLLABLE ZZOP;Lo;0;L;;;;;N;;;;; +A2DF;YI SYLLABLE ZZEX;Lo;0;L;;;;;N;;;;; +A2E0;YI SYLLABLE ZZE;Lo;0;L;;;;;N;;;;; +A2E1;YI SYLLABLE ZZEP;Lo;0;L;;;;;N;;;;; +A2E2;YI SYLLABLE ZZUX;Lo;0;L;;;;;N;;;;; +A2E3;YI SYLLABLE ZZU;Lo;0;L;;;;;N;;;;; +A2E4;YI SYLLABLE ZZUP;Lo;0;L;;;;;N;;;;; +A2E5;YI SYLLABLE ZZURX;Lo;0;L;;;;;N;;;;; +A2E6;YI SYLLABLE ZZUR;Lo;0;L;;;;;N;;;;; +A2E7;YI SYLLABLE ZZYT;Lo;0;L;;;;;N;;;;; +A2E8;YI SYLLABLE ZZYX;Lo;0;L;;;;;N;;;;; +A2E9;YI SYLLABLE ZZY;Lo;0;L;;;;;N;;;;; +A2EA;YI SYLLABLE ZZYP;Lo;0;L;;;;;N;;;;; +A2EB;YI SYLLABLE ZZYRX;Lo;0;L;;;;;N;;;;; +A2EC;YI SYLLABLE ZZYR;Lo;0;L;;;;;N;;;;; +A2ED;YI SYLLABLE NZIT;Lo;0;L;;;;;N;;;;; +A2EE;YI SYLLABLE NZIX;Lo;0;L;;;;;N;;;;; +A2EF;YI SYLLABLE NZI;Lo;0;L;;;;;N;;;;; +A2F0;YI SYLLABLE NZIP;Lo;0;L;;;;;N;;;;; +A2F1;YI SYLLABLE NZIEX;Lo;0;L;;;;;N;;;;; +A2F2;YI SYLLABLE NZIE;Lo;0;L;;;;;N;;;;; +A2F3;YI SYLLABLE NZIEP;Lo;0;L;;;;;N;;;;; +A2F4;YI SYLLABLE NZAT;Lo;0;L;;;;;N;;;;; +A2F5;YI SYLLABLE NZAX;Lo;0;L;;;;;N;;;;; +A2F6;YI SYLLABLE NZA;Lo;0;L;;;;;N;;;;; +A2F7;YI SYLLABLE NZAP;Lo;0;L;;;;;N;;;;; +A2F8;YI SYLLABLE NZUOX;Lo;0;L;;;;;N;;;;; +A2F9;YI SYLLABLE NZUO;Lo;0;L;;;;;N;;;;; +A2FA;YI SYLLABLE NZOX;Lo;0;L;;;;;N;;;;; +A2FB;YI SYLLABLE NZOP;Lo;0;L;;;;;N;;;;; +A2FC;YI SYLLABLE NZEX;Lo;0;L;;;;;N;;;;; +A2FD;YI SYLLABLE NZE;Lo;0;L;;;;;N;;;;; +A2FE;YI SYLLABLE NZUX;Lo;0;L;;;;;N;;;;; +A2FF;YI SYLLABLE NZU;Lo;0;L;;;;;N;;;;; +A300;YI SYLLABLE NZUP;Lo;0;L;;;;;N;;;;; +A301;YI SYLLABLE NZURX;Lo;0;L;;;;;N;;;;; +A302;YI SYLLABLE NZUR;Lo;0;L;;;;;N;;;;; +A303;YI SYLLABLE NZYT;Lo;0;L;;;;;N;;;;; +A304;YI SYLLABLE NZYX;Lo;0;L;;;;;N;;;;; +A305;YI SYLLABLE NZY;Lo;0;L;;;;;N;;;;; +A306;YI SYLLABLE NZYP;Lo;0;L;;;;;N;;;;; +A307;YI SYLLABLE NZYRX;Lo;0;L;;;;;N;;;;; +A308;YI SYLLABLE NZYR;Lo;0;L;;;;;N;;;;; +A309;YI SYLLABLE SIT;Lo;0;L;;;;;N;;;;; +A30A;YI SYLLABLE SIX;Lo;0;L;;;;;N;;;;; +A30B;YI SYLLABLE SI;Lo;0;L;;;;;N;;;;; +A30C;YI SYLLABLE SIP;Lo;0;L;;;;;N;;;;; +A30D;YI SYLLABLE SIEX;Lo;0;L;;;;;N;;;;; +A30E;YI SYLLABLE SIE;Lo;0;L;;;;;N;;;;; +A30F;YI SYLLABLE SIEP;Lo;0;L;;;;;N;;;;; +A310;YI SYLLABLE SAT;Lo;0;L;;;;;N;;;;; +A311;YI SYLLABLE SAX;Lo;0;L;;;;;N;;;;; +A312;YI SYLLABLE SA;Lo;0;L;;;;;N;;;;; +A313;YI SYLLABLE SAP;Lo;0;L;;;;;N;;;;; +A314;YI SYLLABLE SUOX;Lo;0;L;;;;;N;;;;; +A315;YI SYLLABLE SUO;Lo;0;L;;;;;N;;;;; +A316;YI SYLLABLE SUOP;Lo;0;L;;;;;N;;;;; +A317;YI SYLLABLE SOT;Lo;0;L;;;;;N;;;;; +A318;YI SYLLABLE SOX;Lo;0;L;;;;;N;;;;; +A319;YI SYLLABLE SO;Lo;0;L;;;;;N;;;;; +A31A;YI SYLLABLE SOP;Lo;0;L;;;;;N;;;;; +A31B;YI SYLLABLE SEX;Lo;0;L;;;;;N;;;;; +A31C;YI SYLLABLE SE;Lo;0;L;;;;;N;;;;; +A31D;YI SYLLABLE SEP;Lo;0;L;;;;;N;;;;; +A31E;YI SYLLABLE SUT;Lo;0;L;;;;;N;;;;; +A31F;YI SYLLABLE SUX;Lo;0;L;;;;;N;;;;; +A320;YI SYLLABLE SU;Lo;0;L;;;;;N;;;;; +A321;YI SYLLABLE SUP;Lo;0;L;;;;;N;;;;; +A322;YI SYLLABLE SURX;Lo;0;L;;;;;N;;;;; +A323;YI SYLLABLE SUR;Lo;0;L;;;;;N;;;;; +A324;YI SYLLABLE SYT;Lo;0;L;;;;;N;;;;; +A325;YI SYLLABLE SYX;Lo;0;L;;;;;N;;;;; +A326;YI SYLLABLE SY;Lo;0;L;;;;;N;;;;; +A327;YI SYLLABLE SYP;Lo;0;L;;;;;N;;;;; +A328;YI SYLLABLE SYRX;Lo;0;L;;;;;N;;;;; +A329;YI SYLLABLE SYR;Lo;0;L;;;;;N;;;;; +A32A;YI SYLLABLE SSIT;Lo;0;L;;;;;N;;;;; +A32B;YI SYLLABLE SSIX;Lo;0;L;;;;;N;;;;; +A32C;YI SYLLABLE SSI;Lo;0;L;;;;;N;;;;; +A32D;YI SYLLABLE SSIP;Lo;0;L;;;;;N;;;;; +A32E;YI SYLLABLE SSIEX;Lo;0;L;;;;;N;;;;; +A32F;YI SYLLABLE SSIE;Lo;0;L;;;;;N;;;;; +A330;YI SYLLABLE SSIEP;Lo;0;L;;;;;N;;;;; +A331;YI SYLLABLE SSAT;Lo;0;L;;;;;N;;;;; +A332;YI SYLLABLE SSAX;Lo;0;L;;;;;N;;;;; +A333;YI SYLLABLE SSA;Lo;0;L;;;;;N;;;;; +A334;YI SYLLABLE SSAP;Lo;0;L;;;;;N;;;;; +A335;YI SYLLABLE SSOT;Lo;0;L;;;;;N;;;;; +A336;YI SYLLABLE SSOX;Lo;0;L;;;;;N;;;;; +A337;YI SYLLABLE SSO;Lo;0;L;;;;;N;;;;; +A338;YI SYLLABLE SSOP;Lo;0;L;;;;;N;;;;; +A339;YI SYLLABLE SSEX;Lo;0;L;;;;;N;;;;; +A33A;YI SYLLABLE SSE;Lo;0;L;;;;;N;;;;; +A33B;YI SYLLABLE SSEP;Lo;0;L;;;;;N;;;;; +A33C;YI SYLLABLE SSUT;Lo;0;L;;;;;N;;;;; +A33D;YI SYLLABLE SSUX;Lo;0;L;;;;;N;;;;; +A33E;YI SYLLABLE SSU;Lo;0;L;;;;;N;;;;; +A33F;YI SYLLABLE SSUP;Lo;0;L;;;;;N;;;;; +A340;YI SYLLABLE SSYT;Lo;0;L;;;;;N;;;;; +A341;YI SYLLABLE SSYX;Lo;0;L;;;;;N;;;;; +A342;YI SYLLABLE SSY;Lo;0;L;;;;;N;;;;; +A343;YI SYLLABLE SSYP;Lo;0;L;;;;;N;;;;; +A344;YI SYLLABLE SSYRX;Lo;0;L;;;;;N;;;;; +A345;YI SYLLABLE SSYR;Lo;0;L;;;;;N;;;;; +A346;YI SYLLABLE ZHAT;Lo;0;L;;;;;N;;;;; +A347;YI SYLLABLE ZHAX;Lo;0;L;;;;;N;;;;; +A348;YI SYLLABLE ZHA;Lo;0;L;;;;;N;;;;; +A349;YI SYLLABLE ZHAP;Lo;0;L;;;;;N;;;;; +A34A;YI SYLLABLE ZHUOX;Lo;0;L;;;;;N;;;;; +A34B;YI SYLLABLE ZHUO;Lo;0;L;;;;;N;;;;; +A34C;YI SYLLABLE ZHUOP;Lo;0;L;;;;;N;;;;; +A34D;YI SYLLABLE ZHOT;Lo;0;L;;;;;N;;;;; +A34E;YI SYLLABLE ZHOX;Lo;0;L;;;;;N;;;;; +A34F;YI SYLLABLE ZHO;Lo;0;L;;;;;N;;;;; +A350;YI SYLLABLE ZHOP;Lo;0;L;;;;;N;;;;; +A351;YI SYLLABLE ZHET;Lo;0;L;;;;;N;;;;; +A352;YI SYLLABLE ZHEX;Lo;0;L;;;;;N;;;;; +A353;YI SYLLABLE ZHE;Lo;0;L;;;;;N;;;;; +A354;YI SYLLABLE ZHEP;Lo;0;L;;;;;N;;;;; +A355;YI SYLLABLE ZHUT;Lo;0;L;;;;;N;;;;; +A356;YI SYLLABLE ZHUX;Lo;0;L;;;;;N;;;;; +A357;YI SYLLABLE ZHU;Lo;0;L;;;;;N;;;;; +A358;YI SYLLABLE ZHUP;Lo;0;L;;;;;N;;;;; +A359;YI SYLLABLE ZHURX;Lo;0;L;;;;;N;;;;; +A35A;YI SYLLABLE ZHUR;Lo;0;L;;;;;N;;;;; +A35B;YI SYLLABLE ZHYT;Lo;0;L;;;;;N;;;;; +A35C;YI SYLLABLE ZHYX;Lo;0;L;;;;;N;;;;; +A35D;YI SYLLABLE ZHY;Lo;0;L;;;;;N;;;;; +A35E;YI SYLLABLE ZHYP;Lo;0;L;;;;;N;;;;; +A35F;YI SYLLABLE ZHYRX;Lo;0;L;;;;;N;;;;; +A360;YI SYLLABLE ZHYR;Lo;0;L;;;;;N;;;;; +A361;YI SYLLABLE CHAT;Lo;0;L;;;;;N;;;;; +A362;YI SYLLABLE CHAX;Lo;0;L;;;;;N;;;;; +A363;YI SYLLABLE CHA;Lo;0;L;;;;;N;;;;; +A364;YI SYLLABLE CHAP;Lo;0;L;;;;;N;;;;; +A365;YI SYLLABLE CHUOT;Lo;0;L;;;;;N;;;;; +A366;YI SYLLABLE CHUOX;Lo;0;L;;;;;N;;;;; +A367;YI SYLLABLE CHUO;Lo;0;L;;;;;N;;;;; +A368;YI SYLLABLE CHUOP;Lo;0;L;;;;;N;;;;; +A369;YI SYLLABLE CHOT;Lo;0;L;;;;;N;;;;; +A36A;YI SYLLABLE CHOX;Lo;0;L;;;;;N;;;;; +A36B;YI SYLLABLE CHO;Lo;0;L;;;;;N;;;;; +A36C;YI SYLLABLE CHOP;Lo;0;L;;;;;N;;;;; +A36D;YI SYLLABLE CHET;Lo;0;L;;;;;N;;;;; +A36E;YI SYLLABLE CHEX;Lo;0;L;;;;;N;;;;; +A36F;YI SYLLABLE CHE;Lo;0;L;;;;;N;;;;; +A370;YI SYLLABLE CHEP;Lo;0;L;;;;;N;;;;; +A371;YI SYLLABLE CHUX;Lo;0;L;;;;;N;;;;; +A372;YI SYLLABLE CHU;Lo;0;L;;;;;N;;;;; +A373;YI SYLLABLE CHUP;Lo;0;L;;;;;N;;;;; +A374;YI SYLLABLE CHURX;Lo;0;L;;;;;N;;;;; +A375;YI SYLLABLE CHUR;Lo;0;L;;;;;N;;;;; +A376;YI SYLLABLE CHYT;Lo;0;L;;;;;N;;;;; +A377;YI SYLLABLE CHYX;Lo;0;L;;;;;N;;;;; +A378;YI SYLLABLE CHY;Lo;0;L;;;;;N;;;;; +A379;YI SYLLABLE CHYP;Lo;0;L;;;;;N;;;;; +A37A;YI SYLLABLE CHYRX;Lo;0;L;;;;;N;;;;; +A37B;YI SYLLABLE CHYR;Lo;0;L;;;;;N;;;;; +A37C;YI SYLLABLE RRAX;Lo;0;L;;;;;N;;;;; +A37D;YI SYLLABLE RRA;Lo;0;L;;;;;N;;;;; +A37E;YI SYLLABLE RRUOX;Lo;0;L;;;;;N;;;;; +A37F;YI SYLLABLE RRUO;Lo;0;L;;;;;N;;;;; +A380;YI SYLLABLE RROT;Lo;0;L;;;;;N;;;;; +A381;YI SYLLABLE RROX;Lo;0;L;;;;;N;;;;; +A382;YI SYLLABLE RRO;Lo;0;L;;;;;N;;;;; +A383;YI SYLLABLE RROP;Lo;0;L;;;;;N;;;;; +A384;YI SYLLABLE RRET;Lo;0;L;;;;;N;;;;; +A385;YI SYLLABLE RREX;Lo;0;L;;;;;N;;;;; +A386;YI SYLLABLE RRE;Lo;0;L;;;;;N;;;;; +A387;YI SYLLABLE RREP;Lo;0;L;;;;;N;;;;; +A388;YI SYLLABLE RRUT;Lo;0;L;;;;;N;;;;; +A389;YI SYLLABLE RRUX;Lo;0;L;;;;;N;;;;; +A38A;YI SYLLABLE RRU;Lo;0;L;;;;;N;;;;; +A38B;YI SYLLABLE RRUP;Lo;0;L;;;;;N;;;;; +A38C;YI SYLLABLE RRURX;Lo;0;L;;;;;N;;;;; +A38D;YI SYLLABLE RRUR;Lo;0;L;;;;;N;;;;; +A38E;YI SYLLABLE RRYT;Lo;0;L;;;;;N;;;;; +A38F;YI SYLLABLE RRYX;Lo;0;L;;;;;N;;;;; +A390;YI SYLLABLE RRY;Lo;0;L;;;;;N;;;;; +A391;YI SYLLABLE RRYP;Lo;0;L;;;;;N;;;;; +A392;YI SYLLABLE RRYRX;Lo;0;L;;;;;N;;;;; +A393;YI SYLLABLE RRYR;Lo;0;L;;;;;N;;;;; +A394;YI SYLLABLE NRAT;Lo;0;L;;;;;N;;;;; +A395;YI SYLLABLE NRAX;Lo;0;L;;;;;N;;;;; +A396;YI SYLLABLE NRA;Lo;0;L;;;;;N;;;;; +A397;YI SYLLABLE NRAP;Lo;0;L;;;;;N;;;;; +A398;YI SYLLABLE NROX;Lo;0;L;;;;;N;;;;; +A399;YI SYLLABLE NRO;Lo;0;L;;;;;N;;;;; +A39A;YI SYLLABLE NROP;Lo;0;L;;;;;N;;;;; +A39B;YI SYLLABLE NRET;Lo;0;L;;;;;N;;;;; +A39C;YI SYLLABLE NREX;Lo;0;L;;;;;N;;;;; +A39D;YI SYLLABLE NRE;Lo;0;L;;;;;N;;;;; +A39E;YI SYLLABLE NREP;Lo;0;L;;;;;N;;;;; +A39F;YI SYLLABLE NRUT;Lo;0;L;;;;;N;;;;; +A3A0;YI SYLLABLE NRUX;Lo;0;L;;;;;N;;;;; +A3A1;YI SYLLABLE NRU;Lo;0;L;;;;;N;;;;; +A3A2;YI SYLLABLE NRUP;Lo;0;L;;;;;N;;;;; +A3A3;YI SYLLABLE NRURX;Lo;0;L;;;;;N;;;;; +A3A4;YI SYLLABLE NRUR;Lo;0;L;;;;;N;;;;; +A3A5;YI SYLLABLE NRYT;Lo;0;L;;;;;N;;;;; +A3A6;YI SYLLABLE NRYX;Lo;0;L;;;;;N;;;;; +A3A7;YI SYLLABLE NRY;Lo;0;L;;;;;N;;;;; +A3A8;YI SYLLABLE NRYP;Lo;0;L;;;;;N;;;;; +A3A9;YI SYLLABLE NRYRX;Lo;0;L;;;;;N;;;;; +A3AA;YI SYLLABLE NRYR;Lo;0;L;;;;;N;;;;; +A3AB;YI SYLLABLE SHAT;Lo;0;L;;;;;N;;;;; +A3AC;YI SYLLABLE SHAX;Lo;0;L;;;;;N;;;;; +A3AD;YI SYLLABLE SHA;Lo;0;L;;;;;N;;;;; +A3AE;YI SYLLABLE SHAP;Lo;0;L;;;;;N;;;;; +A3AF;YI SYLLABLE SHUOX;Lo;0;L;;;;;N;;;;; +A3B0;YI SYLLABLE SHUO;Lo;0;L;;;;;N;;;;; +A3B1;YI SYLLABLE SHUOP;Lo;0;L;;;;;N;;;;; +A3B2;YI SYLLABLE SHOT;Lo;0;L;;;;;N;;;;; +A3B3;YI SYLLABLE SHOX;Lo;0;L;;;;;N;;;;; +A3B4;YI SYLLABLE SHO;Lo;0;L;;;;;N;;;;; +A3B5;YI SYLLABLE SHOP;Lo;0;L;;;;;N;;;;; +A3B6;YI SYLLABLE SHET;Lo;0;L;;;;;N;;;;; +A3B7;YI SYLLABLE SHEX;Lo;0;L;;;;;N;;;;; +A3B8;YI SYLLABLE SHE;Lo;0;L;;;;;N;;;;; +A3B9;YI SYLLABLE SHEP;Lo;0;L;;;;;N;;;;; +A3BA;YI SYLLABLE SHUT;Lo;0;L;;;;;N;;;;; +A3BB;YI SYLLABLE SHUX;Lo;0;L;;;;;N;;;;; +A3BC;YI SYLLABLE SHU;Lo;0;L;;;;;N;;;;; +A3BD;YI SYLLABLE SHUP;Lo;0;L;;;;;N;;;;; +A3BE;YI SYLLABLE SHURX;Lo;0;L;;;;;N;;;;; +A3BF;YI SYLLABLE SHUR;Lo;0;L;;;;;N;;;;; +A3C0;YI SYLLABLE SHYT;Lo;0;L;;;;;N;;;;; +A3C1;YI SYLLABLE SHYX;Lo;0;L;;;;;N;;;;; +A3C2;YI SYLLABLE SHY;Lo;0;L;;;;;N;;;;; +A3C3;YI SYLLABLE SHYP;Lo;0;L;;;;;N;;;;; +A3C4;YI SYLLABLE SHYRX;Lo;0;L;;;;;N;;;;; +A3C5;YI SYLLABLE SHYR;Lo;0;L;;;;;N;;;;; +A3C6;YI SYLLABLE RAT;Lo;0;L;;;;;N;;;;; +A3C7;YI SYLLABLE RAX;Lo;0;L;;;;;N;;;;; +A3C8;YI SYLLABLE RA;Lo;0;L;;;;;N;;;;; +A3C9;YI SYLLABLE RAP;Lo;0;L;;;;;N;;;;; +A3CA;YI SYLLABLE RUOX;Lo;0;L;;;;;N;;;;; +A3CB;YI SYLLABLE RUO;Lo;0;L;;;;;N;;;;; +A3CC;YI SYLLABLE RUOP;Lo;0;L;;;;;N;;;;; +A3CD;YI SYLLABLE ROT;Lo;0;L;;;;;N;;;;; +A3CE;YI SYLLABLE ROX;Lo;0;L;;;;;N;;;;; +A3CF;YI SYLLABLE RO;Lo;0;L;;;;;N;;;;; +A3D0;YI SYLLABLE ROP;Lo;0;L;;;;;N;;;;; +A3D1;YI SYLLABLE REX;Lo;0;L;;;;;N;;;;; +A3D2;YI SYLLABLE RE;Lo;0;L;;;;;N;;;;; +A3D3;YI SYLLABLE REP;Lo;0;L;;;;;N;;;;; +A3D4;YI SYLLABLE RUT;Lo;0;L;;;;;N;;;;; +A3D5;YI SYLLABLE RUX;Lo;0;L;;;;;N;;;;; +A3D6;YI SYLLABLE RU;Lo;0;L;;;;;N;;;;; +A3D7;YI SYLLABLE RUP;Lo;0;L;;;;;N;;;;; +A3D8;YI SYLLABLE RURX;Lo;0;L;;;;;N;;;;; +A3D9;YI SYLLABLE RUR;Lo;0;L;;;;;N;;;;; +A3DA;YI SYLLABLE RYT;Lo;0;L;;;;;N;;;;; +A3DB;YI SYLLABLE RYX;Lo;0;L;;;;;N;;;;; +A3DC;YI SYLLABLE RY;Lo;0;L;;;;;N;;;;; +A3DD;YI SYLLABLE RYP;Lo;0;L;;;;;N;;;;; +A3DE;YI SYLLABLE RYRX;Lo;0;L;;;;;N;;;;; +A3DF;YI SYLLABLE RYR;Lo;0;L;;;;;N;;;;; +A3E0;YI SYLLABLE JIT;Lo;0;L;;;;;N;;;;; +A3E1;YI SYLLABLE JIX;Lo;0;L;;;;;N;;;;; +A3E2;YI SYLLABLE JI;Lo;0;L;;;;;N;;;;; +A3E3;YI SYLLABLE JIP;Lo;0;L;;;;;N;;;;; +A3E4;YI SYLLABLE JIET;Lo;0;L;;;;;N;;;;; +A3E5;YI SYLLABLE JIEX;Lo;0;L;;;;;N;;;;; +A3E6;YI SYLLABLE JIE;Lo;0;L;;;;;N;;;;; +A3E7;YI SYLLABLE JIEP;Lo;0;L;;;;;N;;;;; +A3E8;YI SYLLABLE JUOT;Lo;0;L;;;;;N;;;;; +A3E9;YI SYLLABLE JUOX;Lo;0;L;;;;;N;;;;; +A3EA;YI SYLLABLE JUO;Lo;0;L;;;;;N;;;;; +A3EB;YI SYLLABLE JUOP;Lo;0;L;;;;;N;;;;; +A3EC;YI SYLLABLE JOT;Lo;0;L;;;;;N;;;;; +A3ED;YI SYLLABLE JOX;Lo;0;L;;;;;N;;;;; +A3EE;YI SYLLABLE JO;Lo;0;L;;;;;N;;;;; +A3EF;YI SYLLABLE JOP;Lo;0;L;;;;;N;;;;; +A3F0;YI SYLLABLE JUT;Lo;0;L;;;;;N;;;;; +A3F1;YI SYLLABLE JUX;Lo;0;L;;;;;N;;;;; +A3F2;YI SYLLABLE JU;Lo;0;L;;;;;N;;;;; +A3F3;YI SYLLABLE JUP;Lo;0;L;;;;;N;;;;; +A3F4;YI SYLLABLE JURX;Lo;0;L;;;;;N;;;;; +A3F5;YI SYLLABLE JUR;Lo;0;L;;;;;N;;;;; +A3F6;YI SYLLABLE JYT;Lo;0;L;;;;;N;;;;; +A3F7;YI SYLLABLE JYX;Lo;0;L;;;;;N;;;;; +A3F8;YI SYLLABLE JY;Lo;0;L;;;;;N;;;;; +A3F9;YI SYLLABLE JYP;Lo;0;L;;;;;N;;;;; +A3FA;YI SYLLABLE JYRX;Lo;0;L;;;;;N;;;;; +A3FB;YI SYLLABLE JYR;Lo;0;L;;;;;N;;;;; +A3FC;YI SYLLABLE QIT;Lo;0;L;;;;;N;;;;; +A3FD;YI SYLLABLE QIX;Lo;0;L;;;;;N;;;;; +A3FE;YI SYLLABLE QI;Lo;0;L;;;;;N;;;;; +A3FF;YI SYLLABLE QIP;Lo;0;L;;;;;N;;;;; +A400;YI SYLLABLE QIET;Lo;0;L;;;;;N;;;;; +A401;YI SYLLABLE QIEX;Lo;0;L;;;;;N;;;;; +A402;YI SYLLABLE QIE;Lo;0;L;;;;;N;;;;; +A403;YI SYLLABLE QIEP;Lo;0;L;;;;;N;;;;; +A404;YI SYLLABLE QUOT;Lo;0;L;;;;;N;;;;; +A405;YI SYLLABLE QUOX;Lo;0;L;;;;;N;;;;; +A406;YI SYLLABLE QUO;Lo;0;L;;;;;N;;;;; +A407;YI SYLLABLE QUOP;Lo;0;L;;;;;N;;;;; +A408;YI SYLLABLE QOT;Lo;0;L;;;;;N;;;;; +A409;YI SYLLABLE QOX;Lo;0;L;;;;;N;;;;; +A40A;YI SYLLABLE QO;Lo;0;L;;;;;N;;;;; +A40B;YI SYLLABLE QOP;Lo;0;L;;;;;N;;;;; +A40C;YI SYLLABLE QUT;Lo;0;L;;;;;N;;;;; +A40D;YI SYLLABLE QUX;Lo;0;L;;;;;N;;;;; +A40E;YI SYLLABLE QU;Lo;0;L;;;;;N;;;;; +A40F;YI SYLLABLE QUP;Lo;0;L;;;;;N;;;;; +A410;YI SYLLABLE QURX;Lo;0;L;;;;;N;;;;; +A411;YI SYLLABLE QUR;Lo;0;L;;;;;N;;;;; +A412;YI SYLLABLE QYT;Lo;0;L;;;;;N;;;;; +A413;YI SYLLABLE QYX;Lo;0;L;;;;;N;;;;; +A414;YI SYLLABLE QY;Lo;0;L;;;;;N;;;;; +A415;YI SYLLABLE QYP;Lo;0;L;;;;;N;;;;; +A416;YI SYLLABLE QYRX;Lo;0;L;;;;;N;;;;; +A417;YI SYLLABLE QYR;Lo;0;L;;;;;N;;;;; +A418;YI SYLLABLE JJIT;Lo;0;L;;;;;N;;;;; +A419;YI SYLLABLE JJIX;Lo;0;L;;;;;N;;;;; +A41A;YI SYLLABLE JJI;Lo;0;L;;;;;N;;;;; +A41B;YI SYLLABLE JJIP;Lo;0;L;;;;;N;;;;; +A41C;YI SYLLABLE JJIET;Lo;0;L;;;;;N;;;;; +A41D;YI SYLLABLE JJIEX;Lo;0;L;;;;;N;;;;; +A41E;YI SYLLABLE JJIE;Lo;0;L;;;;;N;;;;; +A41F;YI SYLLABLE JJIEP;Lo;0;L;;;;;N;;;;; +A420;YI SYLLABLE JJUOX;Lo;0;L;;;;;N;;;;; +A421;YI SYLLABLE JJUO;Lo;0;L;;;;;N;;;;; +A422;YI SYLLABLE JJUOP;Lo;0;L;;;;;N;;;;; +A423;YI SYLLABLE JJOT;Lo;0;L;;;;;N;;;;; +A424;YI SYLLABLE JJOX;Lo;0;L;;;;;N;;;;; +A425;YI SYLLABLE JJO;Lo;0;L;;;;;N;;;;; +A426;YI SYLLABLE JJOP;Lo;0;L;;;;;N;;;;; +A427;YI SYLLABLE JJUT;Lo;0;L;;;;;N;;;;; +A428;YI SYLLABLE JJUX;Lo;0;L;;;;;N;;;;; +A429;YI SYLLABLE JJU;Lo;0;L;;;;;N;;;;; +A42A;YI SYLLABLE JJUP;Lo;0;L;;;;;N;;;;; +A42B;YI SYLLABLE JJURX;Lo;0;L;;;;;N;;;;; +A42C;YI SYLLABLE JJUR;Lo;0;L;;;;;N;;;;; +A42D;YI SYLLABLE JJYT;Lo;0;L;;;;;N;;;;; +A42E;YI SYLLABLE JJYX;Lo;0;L;;;;;N;;;;; +A42F;YI SYLLABLE JJY;Lo;0;L;;;;;N;;;;; +A430;YI SYLLABLE JJYP;Lo;0;L;;;;;N;;;;; +A431;YI SYLLABLE NJIT;Lo;0;L;;;;;N;;;;; +A432;YI SYLLABLE NJIX;Lo;0;L;;;;;N;;;;; +A433;YI SYLLABLE NJI;Lo;0;L;;;;;N;;;;; +A434;YI SYLLABLE NJIP;Lo;0;L;;;;;N;;;;; +A435;YI SYLLABLE NJIET;Lo;0;L;;;;;N;;;;; +A436;YI SYLLABLE NJIEX;Lo;0;L;;;;;N;;;;; +A437;YI SYLLABLE NJIE;Lo;0;L;;;;;N;;;;; +A438;YI SYLLABLE NJIEP;Lo;0;L;;;;;N;;;;; +A439;YI SYLLABLE NJUOX;Lo;0;L;;;;;N;;;;; +A43A;YI SYLLABLE NJUO;Lo;0;L;;;;;N;;;;; +A43B;YI SYLLABLE NJOT;Lo;0;L;;;;;N;;;;; +A43C;YI SYLLABLE NJOX;Lo;0;L;;;;;N;;;;; +A43D;YI SYLLABLE NJO;Lo;0;L;;;;;N;;;;; +A43E;YI SYLLABLE NJOP;Lo;0;L;;;;;N;;;;; +A43F;YI SYLLABLE NJUX;Lo;0;L;;;;;N;;;;; +A440;YI SYLLABLE NJU;Lo;0;L;;;;;N;;;;; +A441;YI SYLLABLE NJUP;Lo;0;L;;;;;N;;;;; +A442;YI SYLLABLE NJURX;Lo;0;L;;;;;N;;;;; +A443;YI SYLLABLE NJUR;Lo;0;L;;;;;N;;;;; +A444;YI SYLLABLE NJYT;Lo;0;L;;;;;N;;;;; +A445;YI SYLLABLE NJYX;Lo;0;L;;;;;N;;;;; +A446;YI SYLLABLE NJY;Lo;0;L;;;;;N;;;;; +A447;YI SYLLABLE NJYP;Lo;0;L;;;;;N;;;;; +A448;YI SYLLABLE NJYRX;Lo;0;L;;;;;N;;;;; +A449;YI SYLLABLE NJYR;Lo;0;L;;;;;N;;;;; +A44A;YI SYLLABLE NYIT;Lo;0;L;;;;;N;;;;; +A44B;YI SYLLABLE NYIX;Lo;0;L;;;;;N;;;;; +A44C;YI SYLLABLE NYI;Lo;0;L;;;;;N;;;;; +A44D;YI SYLLABLE NYIP;Lo;0;L;;;;;N;;;;; +A44E;YI SYLLABLE NYIET;Lo;0;L;;;;;N;;;;; +A44F;YI SYLLABLE NYIEX;Lo;0;L;;;;;N;;;;; +A450;YI SYLLABLE NYIE;Lo;0;L;;;;;N;;;;; +A451;YI SYLLABLE NYIEP;Lo;0;L;;;;;N;;;;; +A452;YI SYLLABLE NYUOX;Lo;0;L;;;;;N;;;;; +A453;YI SYLLABLE NYUO;Lo;0;L;;;;;N;;;;; +A454;YI SYLLABLE NYUOP;Lo;0;L;;;;;N;;;;; +A455;YI SYLLABLE NYOT;Lo;0;L;;;;;N;;;;; +A456;YI SYLLABLE NYOX;Lo;0;L;;;;;N;;;;; +A457;YI SYLLABLE NYO;Lo;0;L;;;;;N;;;;; +A458;YI SYLLABLE NYOP;Lo;0;L;;;;;N;;;;; +A459;YI SYLLABLE NYUT;Lo;0;L;;;;;N;;;;; +A45A;YI SYLLABLE NYUX;Lo;0;L;;;;;N;;;;; +A45B;YI SYLLABLE NYU;Lo;0;L;;;;;N;;;;; +A45C;YI SYLLABLE NYUP;Lo;0;L;;;;;N;;;;; +A45D;YI SYLLABLE XIT;Lo;0;L;;;;;N;;;;; +A45E;YI SYLLABLE XIX;Lo;0;L;;;;;N;;;;; +A45F;YI SYLLABLE XI;Lo;0;L;;;;;N;;;;; +A460;YI SYLLABLE XIP;Lo;0;L;;;;;N;;;;; +A461;YI SYLLABLE XIET;Lo;0;L;;;;;N;;;;; +A462;YI SYLLABLE XIEX;Lo;0;L;;;;;N;;;;; +A463;YI SYLLABLE XIE;Lo;0;L;;;;;N;;;;; +A464;YI SYLLABLE XIEP;Lo;0;L;;;;;N;;;;; +A465;YI SYLLABLE XUOX;Lo;0;L;;;;;N;;;;; +A466;YI SYLLABLE XUO;Lo;0;L;;;;;N;;;;; +A467;YI SYLLABLE XOT;Lo;0;L;;;;;N;;;;; +A468;YI SYLLABLE XOX;Lo;0;L;;;;;N;;;;; +A469;YI SYLLABLE XO;Lo;0;L;;;;;N;;;;; +A46A;YI SYLLABLE XOP;Lo;0;L;;;;;N;;;;; +A46B;YI SYLLABLE XYT;Lo;0;L;;;;;N;;;;; +A46C;YI SYLLABLE XYX;Lo;0;L;;;;;N;;;;; +A46D;YI SYLLABLE XY;Lo;0;L;;;;;N;;;;; +A46E;YI SYLLABLE XYP;Lo;0;L;;;;;N;;;;; +A46F;YI SYLLABLE XYRX;Lo;0;L;;;;;N;;;;; +A470;YI SYLLABLE XYR;Lo;0;L;;;;;N;;;;; +A471;YI SYLLABLE YIT;Lo;0;L;;;;;N;;;;; +A472;YI SYLLABLE YIX;Lo;0;L;;;;;N;;;;; +A473;YI SYLLABLE YI;Lo;0;L;;;;;N;;;;; +A474;YI SYLLABLE YIP;Lo;0;L;;;;;N;;;;; +A475;YI SYLLABLE YIET;Lo;0;L;;;;;N;;;;; +A476;YI SYLLABLE YIEX;Lo;0;L;;;;;N;;;;; +A477;YI SYLLABLE YIE;Lo;0;L;;;;;N;;;;; +A478;YI SYLLABLE YIEP;Lo;0;L;;;;;N;;;;; +A479;YI SYLLABLE YUOT;Lo;0;L;;;;;N;;;;; +A47A;YI SYLLABLE YUOX;Lo;0;L;;;;;N;;;;; +A47B;YI SYLLABLE YUO;Lo;0;L;;;;;N;;;;; +A47C;YI SYLLABLE YUOP;Lo;0;L;;;;;N;;;;; +A47D;YI SYLLABLE YOT;Lo;0;L;;;;;N;;;;; +A47E;YI SYLLABLE YOX;Lo;0;L;;;;;N;;;;; +A47F;YI SYLLABLE YO;Lo;0;L;;;;;N;;;;; +A480;YI SYLLABLE YOP;Lo;0;L;;;;;N;;;;; +A481;YI SYLLABLE YUT;Lo;0;L;;;;;N;;;;; +A482;YI SYLLABLE YUX;Lo;0;L;;;;;N;;;;; +A483;YI SYLLABLE YU;Lo;0;L;;;;;N;;;;; +A484;YI SYLLABLE YUP;Lo;0;L;;;;;N;;;;; +A485;YI SYLLABLE YURX;Lo;0;L;;;;;N;;;;; +A486;YI SYLLABLE YUR;Lo;0;L;;;;;N;;;;; +A487;YI SYLLABLE YYT;Lo;0;L;;;;;N;;;;; +A488;YI SYLLABLE YYX;Lo;0;L;;;;;N;;;;; +A489;YI SYLLABLE YY;Lo;0;L;;;;;N;;;;; +A48A;YI SYLLABLE YYP;Lo;0;L;;;;;N;;;;; +A48B;YI SYLLABLE YYRX;Lo;0;L;;;;;N;;;;; +A48C;YI SYLLABLE YYR;Lo;0;L;;;;;N;;;;; +A490;YI RADICAL QOT;So;0;ON;;;;;N;;;;; +A491;YI RADICAL LI;So;0;ON;;;;;N;;;;; +A492;YI RADICAL KIT;So;0;ON;;;;;N;;;;; +A493;YI RADICAL NYIP;So;0;ON;;;;;N;;;;; +A494;YI RADICAL CYP;So;0;ON;;;;;N;;;;; +A495;YI RADICAL SSI;So;0;ON;;;;;N;;;;; +A496;YI RADICAL GGOP;So;0;ON;;;;;N;;;;; +A497;YI RADICAL GEP;So;0;ON;;;;;N;;;;; +A498;YI RADICAL MI;So;0;ON;;;;;N;;;;; +A499;YI RADICAL HXIT;So;0;ON;;;;;N;;;;; +A49A;YI RADICAL LYR;So;0;ON;;;;;N;;;;; +A49B;YI RADICAL BBUT;So;0;ON;;;;;N;;;;; +A49C;YI RADICAL MOP;So;0;ON;;;;;N;;;;; +A49D;YI RADICAL YO;So;0;ON;;;;;N;;;;; +A49E;YI RADICAL PUT;So;0;ON;;;;;N;;;;; +A49F;YI RADICAL HXUO;So;0;ON;;;;;N;;;;; +A4A0;YI RADICAL TAT;So;0;ON;;;;;N;;;;; +A4A1;YI RADICAL GA;So;0;ON;;;;;N;;;;; +A4A2;YI RADICAL ZUP;So;0;ON;;;;;N;;;;; +A4A3;YI RADICAL CYT;So;0;ON;;;;;N;;;;; +A4A4;YI RADICAL DDUR;So;0;ON;;;;;N;;;;; +A4A5;YI RADICAL BUR;So;0;ON;;;;;N;;;;; +A4A6;YI RADICAL GGUO;So;0;ON;;;;;N;;;;; +A4A7;YI RADICAL NYOP;So;0;ON;;;;;N;;;;; +A4A8;YI RADICAL TU;So;0;ON;;;;;N;;;;; +A4A9;YI RADICAL OP;So;0;ON;;;;;N;;;;; +A4AA;YI RADICAL JJUT;So;0;ON;;;;;N;;;;; +A4AB;YI RADICAL ZOT;So;0;ON;;;;;N;;;;; +A4AC;YI RADICAL PYT;So;0;ON;;;;;N;;;;; +A4AD;YI RADICAL HMO;So;0;ON;;;;;N;;;;; +A4AE;YI RADICAL YIT;So;0;ON;;;;;N;;;;; +A4AF;YI RADICAL VUR;So;0;ON;;;;;N;;;;; +A4B0;YI RADICAL SHY;So;0;ON;;;;;N;;;;; +A4B1;YI RADICAL VEP;So;0;ON;;;;;N;;;;; +A4B2;YI RADICAL ZA;So;0;ON;;;;;N;;;;; +A4B3;YI RADICAL JO;So;0;ON;;;;;N;;;;; +A4B4;YI RADICAL NZUP;So;0;ON;;;;;N;;;;; +A4B5;YI RADICAL JJY;So;0;ON;;;;;N;;;;; +A4B6;YI RADICAL GOT;So;0;ON;;;;;N;;;;; +A4B7;YI RADICAL JJIE;So;0;ON;;;;;N;;;;; +A4B8;YI RADICAL WO;So;0;ON;;;;;N;;;;; +A4B9;YI RADICAL DU;So;0;ON;;;;;N;;;;; +A4BA;YI RADICAL SHUR;So;0;ON;;;;;N;;;;; +A4BB;YI RADICAL LIE;So;0;ON;;;;;N;;;;; +A4BC;YI RADICAL CY;So;0;ON;;;;;N;;;;; +A4BD;YI RADICAL CUOP;So;0;ON;;;;;N;;;;; +A4BE;YI RADICAL CIP;So;0;ON;;;;;N;;;;; +A4BF;YI RADICAL HXOP;So;0;ON;;;;;N;;;;; +A4C0;YI RADICAL SHAT;So;0;ON;;;;;N;;;;; +A4C1;YI RADICAL ZUR;So;0;ON;;;;;N;;;;; +A4C2;YI RADICAL SHOP;So;0;ON;;;;;N;;;;; +A4C3;YI RADICAL CHE;So;0;ON;;;;;N;;;;; +A4C4;YI RADICAL ZZIET;So;0;ON;;;;;N;;;;; +A4C5;YI RADICAL NBIE;So;0;ON;;;;;N;;;;; +A4C6;YI RADICAL KE;So;0;ON;;;;;N;;;;; +AC00;;Lo;0;L;;;;;N;;;;; +D7A3;;Lo;0;L;;;;;N;;;;; +D800;;Cs;0;L;;;;;N;;;;; +DB7F;;Cs;0;L;;;;;N;;;;; +DB80;;Cs;0;L;;;;;N;;;;; +DBFF;;Cs;0;L;;;;;N;;;;; +DC00;;Cs;0;L;;;;;N;;;;; +DFFF;;Cs;0;L;;;;;N;;;;; +E000;;Co;0;L;;;;;N;;;;; +F8FF;;Co;0;L;;;;;N;;;;; +F900;CJK COMPATIBILITY IDEOGRAPH-F900;Lo;0;L;8C48;;;;N;;;;; +F901;CJK COMPATIBILITY IDEOGRAPH-F901;Lo;0;L;66F4;;;;N;;;;; +F902;CJK COMPATIBILITY IDEOGRAPH-F902;Lo;0;L;8ECA;;;;N;;;;; +F903;CJK COMPATIBILITY IDEOGRAPH-F903;Lo;0;L;8CC8;;;;N;;;;; +F904;CJK COMPATIBILITY IDEOGRAPH-F904;Lo;0;L;6ED1;;;;N;;;;; +F905;CJK COMPATIBILITY IDEOGRAPH-F905;Lo;0;L;4E32;;;;N;;;;; +F906;CJK COMPATIBILITY IDEOGRAPH-F906;Lo;0;L;53E5;;;;N;;;;; +F907;CJK COMPATIBILITY IDEOGRAPH-F907;Lo;0;L;9F9C;;;;N;;;;; +F908;CJK COMPATIBILITY IDEOGRAPH-F908;Lo;0;L;9F9C;;;;N;;;;; +F909;CJK COMPATIBILITY IDEOGRAPH-F909;Lo;0;L;5951;;;;N;;;;; +F90A;CJK COMPATIBILITY IDEOGRAPH-F90A;Lo;0;L;91D1;;;;N;;;;; +F90B;CJK COMPATIBILITY IDEOGRAPH-F90B;Lo;0;L;5587;;;;N;;;;; +F90C;CJK COMPATIBILITY IDEOGRAPH-F90C;Lo;0;L;5948;;;;N;;;;; +F90D;CJK COMPATIBILITY IDEOGRAPH-F90D;Lo;0;L;61F6;;;;N;;;;; +F90E;CJK COMPATIBILITY IDEOGRAPH-F90E;Lo;0;L;7669;;;;N;;;;; +F90F;CJK COMPATIBILITY IDEOGRAPH-F90F;Lo;0;L;7F85;;;;N;;;;; +F910;CJK COMPATIBILITY IDEOGRAPH-F910;Lo;0;L;863F;;;;N;;;;; +F911;CJK COMPATIBILITY IDEOGRAPH-F911;Lo;0;L;87BA;;;;N;;;;; +F912;CJK COMPATIBILITY IDEOGRAPH-F912;Lo;0;L;88F8;;;;N;;;;; +F913;CJK COMPATIBILITY IDEOGRAPH-F913;Lo;0;L;908F;;;;N;;;;; +F914;CJK COMPATIBILITY IDEOGRAPH-F914;Lo;0;L;6A02;;;;N;;;;; +F915;CJK COMPATIBILITY IDEOGRAPH-F915;Lo;0;L;6D1B;;;;N;;;;; +F916;CJK COMPATIBILITY IDEOGRAPH-F916;Lo;0;L;70D9;;;;N;;;;; +F917;CJK COMPATIBILITY IDEOGRAPH-F917;Lo;0;L;73DE;;;;N;;;;; +F918;CJK COMPATIBILITY IDEOGRAPH-F918;Lo;0;L;843D;;;;N;;;;; +F919;CJK COMPATIBILITY IDEOGRAPH-F919;Lo;0;L;916A;;;;N;;;;; +F91A;CJK COMPATIBILITY IDEOGRAPH-F91A;Lo;0;L;99F1;;;;N;;;;; +F91B;CJK COMPATIBILITY IDEOGRAPH-F91B;Lo;0;L;4E82;;;;N;;;;; +F91C;CJK COMPATIBILITY IDEOGRAPH-F91C;Lo;0;L;5375;;;;N;;;;; +F91D;CJK COMPATIBILITY IDEOGRAPH-F91D;Lo;0;L;6B04;;;;N;;;;; +F91E;CJK COMPATIBILITY IDEOGRAPH-F91E;Lo;0;L;721B;;;;N;;;;; +F91F;CJK COMPATIBILITY IDEOGRAPH-F91F;Lo;0;L;862D;;;;N;;;;; +F920;CJK COMPATIBILITY IDEOGRAPH-F920;Lo;0;L;9E1E;;;;N;;;;; +F921;CJK COMPATIBILITY IDEOGRAPH-F921;Lo;0;L;5D50;;;;N;;;;; +F922;CJK COMPATIBILITY IDEOGRAPH-F922;Lo;0;L;6FEB;;;;N;;;;; +F923;CJK COMPATIBILITY IDEOGRAPH-F923;Lo;0;L;85CD;;;;N;;;;; +F924;CJK COMPATIBILITY IDEOGRAPH-F924;Lo;0;L;8964;;;;N;;;;; +F925;CJK COMPATIBILITY IDEOGRAPH-F925;Lo;0;L;62C9;;;;N;;;;; +F926;CJK COMPATIBILITY IDEOGRAPH-F926;Lo;0;L;81D8;;;;N;;;;; +F927;CJK COMPATIBILITY IDEOGRAPH-F927;Lo;0;L;881F;;;;N;;;;; +F928;CJK COMPATIBILITY IDEOGRAPH-F928;Lo;0;L;5ECA;;;;N;;;;; +F929;CJK COMPATIBILITY IDEOGRAPH-F929;Lo;0;L;6717;;;;N;;;;; +F92A;CJK COMPATIBILITY IDEOGRAPH-F92A;Lo;0;L;6D6A;;;;N;;;;; +F92B;CJK COMPATIBILITY IDEOGRAPH-F92B;Lo;0;L;72FC;;;;N;;;;; +F92C;CJK COMPATIBILITY IDEOGRAPH-F92C;Lo;0;L;90CE;;;;N;;;;; +F92D;CJK COMPATIBILITY IDEOGRAPH-F92D;Lo;0;L;4F86;;;;N;;;;; +F92E;CJK COMPATIBILITY IDEOGRAPH-F92E;Lo;0;L;51B7;;;;N;;;;; +F92F;CJK COMPATIBILITY IDEOGRAPH-F92F;Lo;0;L;52DE;;;;N;;;;; +F930;CJK COMPATIBILITY IDEOGRAPH-F930;Lo;0;L;64C4;;;;N;;;;; +F931;CJK COMPATIBILITY IDEOGRAPH-F931;Lo;0;L;6AD3;;;;N;;;;; +F932;CJK COMPATIBILITY IDEOGRAPH-F932;Lo;0;L;7210;;;;N;;;;; +F933;CJK COMPATIBILITY IDEOGRAPH-F933;Lo;0;L;76E7;;;;N;;;;; +F934;CJK COMPATIBILITY IDEOGRAPH-F934;Lo;0;L;8001;;;;N;;;;; +F935;CJK COMPATIBILITY IDEOGRAPH-F935;Lo;0;L;8606;;;;N;;;;; +F936;CJK COMPATIBILITY IDEOGRAPH-F936;Lo;0;L;865C;;;;N;;;;; +F937;CJK COMPATIBILITY IDEOGRAPH-F937;Lo;0;L;8DEF;;;;N;;;;; +F938;CJK COMPATIBILITY IDEOGRAPH-F938;Lo;0;L;9732;;;;N;;;;; +F939;CJK COMPATIBILITY IDEOGRAPH-F939;Lo;0;L;9B6F;;;;N;;;;; +F93A;CJK COMPATIBILITY IDEOGRAPH-F93A;Lo;0;L;9DFA;;;;N;;;;; +F93B;CJK COMPATIBILITY IDEOGRAPH-F93B;Lo;0;L;788C;;;;N;;;;; +F93C;CJK COMPATIBILITY IDEOGRAPH-F93C;Lo;0;L;797F;;;;N;;;;; +F93D;CJK COMPATIBILITY IDEOGRAPH-F93D;Lo;0;L;7DA0;;;;N;;;;; +F93E;CJK COMPATIBILITY IDEOGRAPH-F93E;Lo;0;L;83C9;;;;N;;;;; +F93F;CJK COMPATIBILITY IDEOGRAPH-F93F;Lo;0;L;9304;;;;N;;;;; +F940;CJK COMPATIBILITY IDEOGRAPH-F940;Lo;0;L;9E7F;;;;N;;;;; +F941;CJK COMPATIBILITY IDEOGRAPH-F941;Lo;0;L;8AD6;;;;N;;;;; +F942;CJK COMPATIBILITY IDEOGRAPH-F942;Lo;0;L;58DF;;;;N;;;;; +F943;CJK COMPATIBILITY IDEOGRAPH-F943;Lo;0;L;5F04;;;;N;;;;; +F944;CJK COMPATIBILITY IDEOGRAPH-F944;Lo;0;L;7C60;;;;N;;;;; +F945;CJK COMPATIBILITY IDEOGRAPH-F945;Lo;0;L;807E;;;;N;;;;; +F946;CJK COMPATIBILITY IDEOGRAPH-F946;Lo;0;L;7262;;;;N;;;;; +F947;CJK COMPATIBILITY IDEOGRAPH-F947;Lo;0;L;78CA;;;;N;;;;; +F948;CJK COMPATIBILITY IDEOGRAPH-F948;Lo;0;L;8CC2;;;;N;;;;; +F949;CJK COMPATIBILITY IDEOGRAPH-F949;Lo;0;L;96F7;;;;N;;;;; +F94A;CJK COMPATIBILITY IDEOGRAPH-F94A;Lo;0;L;58D8;;;;N;;;;; +F94B;CJK COMPATIBILITY IDEOGRAPH-F94B;Lo;0;L;5C62;;;;N;;;;; +F94C;CJK COMPATIBILITY IDEOGRAPH-F94C;Lo;0;L;6A13;;;;N;;;;; +F94D;CJK COMPATIBILITY IDEOGRAPH-F94D;Lo;0;L;6DDA;;;;N;;;;; +F94E;CJK COMPATIBILITY IDEOGRAPH-F94E;Lo;0;L;6F0F;;;;N;;;;; +F94F;CJK COMPATIBILITY IDEOGRAPH-F94F;Lo;0;L;7D2F;;;;N;;;;; +F950;CJK COMPATIBILITY IDEOGRAPH-F950;Lo;0;L;7E37;;;;N;;;;; +F951;CJK COMPATIBILITY IDEOGRAPH-F951;Lo;0;L;964B;;;;N;;;;; +F952;CJK COMPATIBILITY IDEOGRAPH-F952;Lo;0;L;52D2;;;;N;;;;; +F953;CJK COMPATIBILITY IDEOGRAPH-F953;Lo;0;L;808B;;;;N;;;;; +F954;CJK COMPATIBILITY IDEOGRAPH-F954;Lo;0;L;51DC;;;;N;;;;; +F955;CJK COMPATIBILITY IDEOGRAPH-F955;Lo;0;L;51CC;;;;N;;;;; +F956;CJK COMPATIBILITY IDEOGRAPH-F956;Lo;0;L;7A1C;;;;N;;;;; +F957;CJK COMPATIBILITY IDEOGRAPH-F957;Lo;0;L;7DBE;;;;N;;;;; +F958;CJK COMPATIBILITY IDEOGRAPH-F958;Lo;0;L;83F1;;;;N;;;;; +F959;CJK COMPATIBILITY IDEOGRAPH-F959;Lo;0;L;9675;;;;N;;;;; +F95A;CJK COMPATIBILITY IDEOGRAPH-F95A;Lo;0;L;8B80;;;;N;;;;; +F95B;CJK COMPATIBILITY IDEOGRAPH-F95B;Lo;0;L;62CF;;;;N;;;;; +F95C;CJK COMPATIBILITY IDEOGRAPH-F95C;Lo;0;L;6A02;;;;N;;;;; +F95D;CJK COMPATIBILITY IDEOGRAPH-F95D;Lo;0;L;8AFE;;;;N;;;;; +F95E;CJK COMPATIBILITY IDEOGRAPH-F95E;Lo;0;L;4E39;;;;N;;;;; +F95F;CJK COMPATIBILITY IDEOGRAPH-F95F;Lo;0;L;5BE7;;;;N;;;;; +F960;CJK COMPATIBILITY IDEOGRAPH-F960;Lo;0;L;6012;;;;N;;;;; +F961;CJK COMPATIBILITY IDEOGRAPH-F961;Lo;0;L;7387;;;;N;;;;; +F962;CJK COMPATIBILITY IDEOGRAPH-F962;Lo;0;L;7570;;;;N;;;;; +F963;CJK COMPATIBILITY IDEOGRAPH-F963;Lo;0;L;5317;;;;N;;;;; +F964;CJK COMPATIBILITY IDEOGRAPH-F964;Lo;0;L;78FB;;;;N;;;;; +F965;CJK COMPATIBILITY IDEOGRAPH-F965;Lo;0;L;4FBF;;;;N;;;;; +F966;CJK COMPATIBILITY IDEOGRAPH-F966;Lo;0;L;5FA9;;;;N;;;;; +F967;CJK COMPATIBILITY IDEOGRAPH-F967;Lo;0;L;4E0D;;;;N;;;;; +F968;CJK COMPATIBILITY IDEOGRAPH-F968;Lo;0;L;6CCC;;;;N;;;;; +F969;CJK COMPATIBILITY IDEOGRAPH-F969;Lo;0;L;6578;;;;N;;;;; +F96A;CJK COMPATIBILITY IDEOGRAPH-F96A;Lo;0;L;7D22;;;;N;;;;; +F96B;CJK COMPATIBILITY IDEOGRAPH-F96B;Lo;0;L;53C3;;;;N;;;;; +F96C;CJK COMPATIBILITY IDEOGRAPH-F96C;Lo;0;L;585E;;;;N;;;;; +F96D;CJK COMPATIBILITY IDEOGRAPH-F96D;Lo;0;L;7701;;;;N;;;;; +F96E;CJK COMPATIBILITY IDEOGRAPH-F96E;Lo;0;L;8449;;;;N;;;;; +F96F;CJK COMPATIBILITY IDEOGRAPH-F96F;Lo;0;L;8AAA;;;;N;;;;; +F970;CJK COMPATIBILITY IDEOGRAPH-F970;Lo;0;L;6BBA;;;;N;;;;; +F971;CJK COMPATIBILITY IDEOGRAPH-F971;Lo;0;L;8FB0;;;;N;;;;; +F972;CJK COMPATIBILITY IDEOGRAPH-F972;Lo;0;L;6C88;;;;N;;;;; +F973;CJK COMPATIBILITY IDEOGRAPH-F973;Lo;0;L;62FE;;;;N;;;;; +F974;CJK COMPATIBILITY IDEOGRAPH-F974;Lo;0;L;82E5;;;;N;;;;; +F975;CJK COMPATIBILITY IDEOGRAPH-F975;Lo;0;L;63A0;;;;N;;;;; +F976;CJK COMPATIBILITY IDEOGRAPH-F976;Lo;0;L;7565;;;;N;;;;; +F977;CJK COMPATIBILITY IDEOGRAPH-F977;Lo;0;L;4EAE;;;;N;;;;; +F978;CJK COMPATIBILITY IDEOGRAPH-F978;Lo;0;L;5169;;;;N;;;;; +F979;CJK COMPATIBILITY IDEOGRAPH-F979;Lo;0;L;51C9;;;;N;;;;; +F97A;CJK COMPATIBILITY IDEOGRAPH-F97A;Lo;0;L;6881;;;;N;;;;; +F97B;CJK COMPATIBILITY IDEOGRAPH-F97B;Lo;0;L;7CE7;;;;N;;;;; +F97C;CJK COMPATIBILITY IDEOGRAPH-F97C;Lo;0;L;826F;;;;N;;;;; +F97D;CJK COMPATIBILITY IDEOGRAPH-F97D;Lo;0;L;8AD2;;;;N;;;;; +F97E;CJK COMPATIBILITY IDEOGRAPH-F97E;Lo;0;L;91CF;;;;N;;;;; +F97F;CJK COMPATIBILITY IDEOGRAPH-F97F;Lo;0;L;52F5;;;;N;;;;; +F980;CJK COMPATIBILITY IDEOGRAPH-F980;Lo;0;L;5442;;;;N;;;;; +F981;CJK COMPATIBILITY IDEOGRAPH-F981;Lo;0;L;5973;;;;N;;;;; +F982;CJK COMPATIBILITY IDEOGRAPH-F982;Lo;0;L;5EEC;;;;N;;;;; +F983;CJK COMPATIBILITY IDEOGRAPH-F983;Lo;0;L;65C5;;;;N;;;;; +F984;CJK COMPATIBILITY IDEOGRAPH-F984;Lo;0;L;6FFE;;;;N;;;;; +F985;CJK COMPATIBILITY IDEOGRAPH-F985;Lo;0;L;792A;;;;N;;;;; +F986;CJK COMPATIBILITY IDEOGRAPH-F986;Lo;0;L;95AD;;;;N;;;;; +F987;CJK COMPATIBILITY IDEOGRAPH-F987;Lo;0;L;9A6A;;;;N;;;;; +F988;CJK COMPATIBILITY IDEOGRAPH-F988;Lo;0;L;9E97;;;;N;;;;; +F989;CJK COMPATIBILITY IDEOGRAPH-F989;Lo;0;L;9ECE;;;;N;;;;; +F98A;CJK COMPATIBILITY IDEOGRAPH-F98A;Lo;0;L;529B;;;;N;;;;; +F98B;CJK COMPATIBILITY IDEOGRAPH-F98B;Lo;0;L;66C6;;;;N;;;;; +F98C;CJK COMPATIBILITY IDEOGRAPH-F98C;Lo;0;L;6B77;;;;N;;;;; +F98D;CJK COMPATIBILITY IDEOGRAPH-F98D;Lo;0;L;8F62;;;;N;;;;; +F98E;CJK COMPATIBILITY IDEOGRAPH-F98E;Lo;0;L;5E74;;;;N;;;;; +F98F;CJK COMPATIBILITY IDEOGRAPH-F98F;Lo;0;L;6190;;;;N;;;;; +F990;CJK COMPATIBILITY IDEOGRAPH-F990;Lo;0;L;6200;;;;N;;;;; +F991;CJK COMPATIBILITY IDEOGRAPH-F991;Lo;0;L;649A;;;;N;;;;; +F992;CJK COMPATIBILITY IDEOGRAPH-F992;Lo;0;L;6F23;;;;N;;;;; +F993;CJK COMPATIBILITY IDEOGRAPH-F993;Lo;0;L;7149;;;;N;;;;; +F994;CJK COMPATIBILITY IDEOGRAPH-F994;Lo;0;L;7489;;;;N;;;;; +F995;CJK COMPATIBILITY IDEOGRAPH-F995;Lo;0;L;79CA;;;;N;;;;; +F996;CJK COMPATIBILITY IDEOGRAPH-F996;Lo;0;L;7DF4;;;;N;;;;; +F997;CJK COMPATIBILITY IDEOGRAPH-F997;Lo;0;L;806F;;;;N;;;;; +F998;CJK COMPATIBILITY IDEOGRAPH-F998;Lo;0;L;8F26;;;;N;;;;; +F999;CJK COMPATIBILITY IDEOGRAPH-F999;Lo;0;L;84EE;;;;N;;;;; +F99A;CJK COMPATIBILITY IDEOGRAPH-F99A;Lo;0;L;9023;;;;N;;;;; +F99B;CJK COMPATIBILITY IDEOGRAPH-F99B;Lo;0;L;934A;;;;N;;;;; +F99C;CJK COMPATIBILITY IDEOGRAPH-F99C;Lo;0;L;5217;;;;N;;;;; +F99D;CJK COMPATIBILITY IDEOGRAPH-F99D;Lo;0;L;52A3;;;;N;;;;; +F99E;CJK COMPATIBILITY IDEOGRAPH-F99E;Lo;0;L;54BD;;;;N;;;;; +F99F;CJK COMPATIBILITY IDEOGRAPH-F99F;Lo;0;L;70C8;;;;N;;;;; +F9A0;CJK COMPATIBILITY IDEOGRAPH-F9A0;Lo;0;L;88C2;;;;N;;;;; +F9A1;CJK COMPATIBILITY IDEOGRAPH-F9A1;Lo;0;L;8AAA;;;;N;;;;; +F9A2;CJK COMPATIBILITY IDEOGRAPH-F9A2;Lo;0;L;5EC9;;;;N;;;;; +F9A3;CJK COMPATIBILITY IDEOGRAPH-F9A3;Lo;0;L;5FF5;;;;N;;;;; +F9A4;CJK COMPATIBILITY IDEOGRAPH-F9A4;Lo;0;L;637B;;;;N;;;;; +F9A5;CJK COMPATIBILITY IDEOGRAPH-F9A5;Lo;0;L;6BAE;;;;N;;;;; +F9A6;CJK COMPATIBILITY IDEOGRAPH-F9A6;Lo;0;L;7C3E;;;;N;;;;; +F9A7;CJK COMPATIBILITY IDEOGRAPH-F9A7;Lo;0;L;7375;;;;N;;;;; +F9A8;CJK COMPATIBILITY IDEOGRAPH-F9A8;Lo;0;L;4EE4;;;;N;;;;; +F9A9;CJK COMPATIBILITY IDEOGRAPH-F9A9;Lo;0;L;56F9;;;;N;;;;; +F9AA;CJK COMPATIBILITY IDEOGRAPH-F9AA;Lo;0;L;5BE7;;;;N;;;;; +F9AB;CJK COMPATIBILITY IDEOGRAPH-F9AB;Lo;0;L;5DBA;;;;N;;;;; +F9AC;CJK COMPATIBILITY IDEOGRAPH-F9AC;Lo;0;L;601C;;;;N;;;;; +F9AD;CJK COMPATIBILITY IDEOGRAPH-F9AD;Lo;0;L;73B2;;;;N;;;;; +F9AE;CJK COMPATIBILITY IDEOGRAPH-F9AE;Lo;0;L;7469;;;;N;;;;; +F9AF;CJK COMPATIBILITY IDEOGRAPH-F9AF;Lo;0;L;7F9A;;;;N;;;;; +F9B0;CJK COMPATIBILITY IDEOGRAPH-F9B0;Lo;0;L;8046;;;;N;;;;; +F9B1;CJK COMPATIBILITY IDEOGRAPH-F9B1;Lo;0;L;9234;;;;N;;;;; +F9B2;CJK COMPATIBILITY IDEOGRAPH-F9B2;Lo;0;L;96F6;;;;N;;;;; +F9B3;CJK COMPATIBILITY IDEOGRAPH-F9B3;Lo;0;L;9748;;;;N;;;;; +F9B4;CJK COMPATIBILITY IDEOGRAPH-F9B4;Lo;0;L;9818;;;;N;;;;; +F9B5;CJK COMPATIBILITY IDEOGRAPH-F9B5;Lo;0;L;4F8B;;;;N;;;;; +F9B6;CJK COMPATIBILITY IDEOGRAPH-F9B6;Lo;0;L;79AE;;;;N;;;;; +F9B7;CJK COMPATIBILITY IDEOGRAPH-F9B7;Lo;0;L;91B4;;;;N;;;;; +F9B8;CJK COMPATIBILITY IDEOGRAPH-F9B8;Lo;0;L;96B8;;;;N;;;;; +F9B9;CJK COMPATIBILITY IDEOGRAPH-F9B9;Lo;0;L;60E1;;;;N;;;;; +F9BA;CJK COMPATIBILITY IDEOGRAPH-F9BA;Lo;0;L;4E86;;;;N;;;;; +F9BB;CJK COMPATIBILITY IDEOGRAPH-F9BB;Lo;0;L;50DA;;;;N;;;;; +F9BC;CJK COMPATIBILITY IDEOGRAPH-F9BC;Lo;0;L;5BEE;;;;N;;;;; +F9BD;CJK COMPATIBILITY IDEOGRAPH-F9BD;Lo;0;L;5C3F;;;;N;;;;; +F9BE;CJK COMPATIBILITY IDEOGRAPH-F9BE;Lo;0;L;6599;;;;N;;;;; +F9BF;CJK COMPATIBILITY IDEOGRAPH-F9BF;Lo;0;L;6A02;;;;N;;;;; +F9C0;CJK COMPATIBILITY IDEOGRAPH-F9C0;Lo;0;L;71CE;;;;N;;;;; +F9C1;CJK COMPATIBILITY IDEOGRAPH-F9C1;Lo;0;L;7642;;;;N;;;;; +F9C2;CJK COMPATIBILITY IDEOGRAPH-F9C2;Lo;0;L;84FC;;;;N;;;;; +F9C3;CJK COMPATIBILITY IDEOGRAPH-F9C3;Lo;0;L;907C;;;;N;;;;; +F9C4;CJK COMPATIBILITY IDEOGRAPH-F9C4;Lo;0;L;9F8D;;;;N;;;;; +F9C5;CJK COMPATIBILITY IDEOGRAPH-F9C5;Lo;0;L;6688;;;;N;;;;; +F9C6;CJK COMPATIBILITY IDEOGRAPH-F9C6;Lo;0;L;962E;;;;N;;;;; +F9C7;CJK COMPATIBILITY IDEOGRAPH-F9C7;Lo;0;L;5289;;;;N;;;;; +F9C8;CJK COMPATIBILITY IDEOGRAPH-F9C8;Lo;0;L;677B;;;;N;;;;; +F9C9;CJK COMPATIBILITY IDEOGRAPH-F9C9;Lo;0;L;67F3;;;;N;;;;; +F9CA;CJK COMPATIBILITY IDEOGRAPH-F9CA;Lo;0;L;6D41;;;;N;;;;; +F9CB;CJK COMPATIBILITY IDEOGRAPH-F9CB;Lo;0;L;6E9C;;;;N;;;;; +F9CC;CJK COMPATIBILITY IDEOGRAPH-F9CC;Lo;0;L;7409;;;;N;;;;; +F9CD;CJK COMPATIBILITY IDEOGRAPH-F9CD;Lo;0;L;7559;;;;N;;;;; +F9CE;CJK COMPATIBILITY IDEOGRAPH-F9CE;Lo;0;L;786B;;;;N;;;;; +F9CF;CJK COMPATIBILITY IDEOGRAPH-F9CF;Lo;0;L;7D10;;;;N;;;;; +F9D0;CJK COMPATIBILITY IDEOGRAPH-F9D0;Lo;0;L;985E;;;;N;;;;; +F9D1;CJK COMPATIBILITY IDEOGRAPH-F9D1;Lo;0;L;516D;;;;N;;;;; +F9D2;CJK COMPATIBILITY IDEOGRAPH-F9D2;Lo;0;L;622E;;;;N;;;;; +F9D3;CJK COMPATIBILITY IDEOGRAPH-F9D3;Lo;0;L;9678;;;;N;;;;; +F9D4;CJK COMPATIBILITY IDEOGRAPH-F9D4;Lo;0;L;502B;;;;N;;;;; +F9D5;CJK COMPATIBILITY IDEOGRAPH-F9D5;Lo;0;L;5D19;;;;N;;;;; +F9D6;CJK COMPATIBILITY IDEOGRAPH-F9D6;Lo;0;L;6DEA;;;;N;;;;; +F9D7;CJK COMPATIBILITY IDEOGRAPH-F9D7;Lo;0;L;8F2A;;;;N;;;;; +F9D8;CJK COMPATIBILITY IDEOGRAPH-F9D8;Lo;0;L;5F8B;;;;N;;;;; +F9D9;CJK COMPATIBILITY IDEOGRAPH-F9D9;Lo;0;L;6144;;;;N;;;;; +F9DA;CJK COMPATIBILITY IDEOGRAPH-F9DA;Lo;0;L;6817;;;;N;;;;; +F9DB;CJK COMPATIBILITY IDEOGRAPH-F9DB;Lo;0;L;7387;;;;N;;;;; +F9DC;CJK COMPATIBILITY IDEOGRAPH-F9DC;Lo;0;L;9686;;;;N;;;;; +F9DD;CJK COMPATIBILITY IDEOGRAPH-F9DD;Lo;0;L;5229;;;;N;;;;; +F9DE;CJK COMPATIBILITY IDEOGRAPH-F9DE;Lo;0;L;540F;;;;N;;;;; +F9DF;CJK COMPATIBILITY IDEOGRAPH-F9DF;Lo;0;L;5C65;;;;N;;;;; +F9E0;CJK COMPATIBILITY IDEOGRAPH-F9E0;Lo;0;L;6613;;;;N;;;;; +F9E1;CJK COMPATIBILITY IDEOGRAPH-F9E1;Lo;0;L;674E;;;;N;;;;; +F9E2;CJK COMPATIBILITY IDEOGRAPH-F9E2;Lo;0;L;68A8;;;;N;;;;; +F9E3;CJK COMPATIBILITY IDEOGRAPH-F9E3;Lo;0;L;6CE5;;;;N;;;;; +F9E4;CJK COMPATIBILITY IDEOGRAPH-F9E4;Lo;0;L;7406;;;;N;;;;; +F9E5;CJK COMPATIBILITY IDEOGRAPH-F9E5;Lo;0;L;75E2;;;;N;;;;; +F9E6;CJK COMPATIBILITY IDEOGRAPH-F9E6;Lo;0;L;7F79;;;;N;;;;; +F9E7;CJK COMPATIBILITY IDEOGRAPH-F9E7;Lo;0;L;88CF;;;;N;;;;; +F9E8;CJK COMPATIBILITY IDEOGRAPH-F9E8;Lo;0;L;88E1;;;;N;;;;; +F9E9;CJK COMPATIBILITY IDEOGRAPH-F9E9;Lo;0;L;91CC;;;;N;;;;; +F9EA;CJK COMPATIBILITY IDEOGRAPH-F9EA;Lo;0;L;96E2;;;;N;;;;; +F9EB;CJK COMPATIBILITY IDEOGRAPH-F9EB;Lo;0;L;533F;;;;N;;;;; +F9EC;CJK COMPATIBILITY IDEOGRAPH-F9EC;Lo;0;L;6EBA;;;;N;;;;; +F9ED;CJK COMPATIBILITY IDEOGRAPH-F9ED;Lo;0;L;541D;;;;N;;;;; +F9EE;CJK COMPATIBILITY IDEOGRAPH-F9EE;Lo;0;L;71D0;;;;N;;;;; +F9EF;CJK COMPATIBILITY IDEOGRAPH-F9EF;Lo;0;L;7498;;;;N;;;;; +F9F0;CJK COMPATIBILITY IDEOGRAPH-F9F0;Lo;0;L;85FA;;;;N;;;;; +F9F1;CJK COMPATIBILITY IDEOGRAPH-F9F1;Lo;0;L;96A3;;;;N;;;;; +F9F2;CJK COMPATIBILITY IDEOGRAPH-F9F2;Lo;0;L;9C57;;;;N;;;;; +F9F3;CJK COMPATIBILITY IDEOGRAPH-F9F3;Lo;0;L;9E9F;;;;N;;;;; +F9F4;CJK COMPATIBILITY IDEOGRAPH-F9F4;Lo;0;L;6797;;;;N;;;;; +F9F5;CJK COMPATIBILITY IDEOGRAPH-F9F5;Lo;0;L;6DCB;;;;N;;;;; +F9F6;CJK COMPATIBILITY IDEOGRAPH-F9F6;Lo;0;L;81E8;;;;N;;;;; +F9F7;CJK COMPATIBILITY IDEOGRAPH-F9F7;Lo;0;L;7ACB;;;;N;;;;; +F9F8;CJK COMPATIBILITY IDEOGRAPH-F9F8;Lo;0;L;7B20;;;;N;;;;; +F9F9;CJK COMPATIBILITY IDEOGRAPH-F9F9;Lo;0;L;7C92;;;;N;;;;; +F9FA;CJK COMPATIBILITY IDEOGRAPH-F9FA;Lo;0;L;72C0;;;;N;;;;; +F9FB;CJK COMPATIBILITY IDEOGRAPH-F9FB;Lo;0;L;7099;;;;N;;;;; +F9FC;CJK COMPATIBILITY IDEOGRAPH-F9FC;Lo;0;L;8B58;;;;N;;;;; +F9FD;CJK COMPATIBILITY IDEOGRAPH-F9FD;Lo;0;L;4EC0;;;;N;;;;; +F9FE;CJK COMPATIBILITY IDEOGRAPH-F9FE;Lo;0;L;8336;;;;N;;;;; +F9FF;CJK COMPATIBILITY IDEOGRAPH-F9FF;Lo;0;L;523A;;;;N;;;;; +FA00;CJK COMPATIBILITY IDEOGRAPH-FA00;Lo;0;L;5207;;;;N;;;;; +FA01;CJK COMPATIBILITY IDEOGRAPH-FA01;Lo;0;L;5EA6;;;;N;;;;; +FA02;CJK COMPATIBILITY IDEOGRAPH-FA02;Lo;0;L;62D3;;;;N;;;;; +FA03;CJK COMPATIBILITY IDEOGRAPH-FA03;Lo;0;L;7CD6;;;;N;;;;; +FA04;CJK COMPATIBILITY IDEOGRAPH-FA04;Lo;0;L;5B85;;;;N;;;;; +FA05;CJK COMPATIBILITY IDEOGRAPH-FA05;Lo;0;L;6D1E;;;;N;;;;; +FA06;CJK COMPATIBILITY IDEOGRAPH-FA06;Lo;0;L;66B4;;;;N;;;;; +FA07;CJK COMPATIBILITY IDEOGRAPH-FA07;Lo;0;L;8F3B;;;;N;;;;; +FA08;CJK COMPATIBILITY IDEOGRAPH-FA08;Lo;0;L;884C;;;;N;;;;; +FA09;CJK COMPATIBILITY IDEOGRAPH-FA09;Lo;0;L;964D;;;;N;;;;; +FA0A;CJK COMPATIBILITY IDEOGRAPH-FA0A;Lo;0;L;898B;;;;N;;;;; +FA0B;CJK COMPATIBILITY IDEOGRAPH-FA0B;Lo;0;L;5ED3;;;;N;;;;; +FA0C;CJK COMPATIBILITY IDEOGRAPH-FA0C;Lo;0;L;5140;;;;N;;;;; +FA0D;CJK COMPATIBILITY IDEOGRAPH-FA0D;Lo;0;L;55C0;;;;N;;;;; +FA0E;CJK COMPATIBILITY IDEOGRAPH-FA0E;Lo;0;L;;;;;N;;;;; +FA0F;CJK COMPATIBILITY IDEOGRAPH-FA0F;Lo;0;L;;;;;N;;;;; +FA10;CJK COMPATIBILITY IDEOGRAPH-FA10;Lo;0;L;585A;;;;N;;;;; +FA11;CJK COMPATIBILITY IDEOGRAPH-FA11;Lo;0;L;;;;;N;;;;; +FA12;CJK COMPATIBILITY IDEOGRAPH-FA12;Lo;0;L;6674;;;;N;;;;; +FA13;CJK COMPATIBILITY IDEOGRAPH-FA13;Lo;0;L;;;;;N;;;;; +FA14;CJK COMPATIBILITY IDEOGRAPH-FA14;Lo;0;L;;;;;N;;;;; +FA15;CJK COMPATIBILITY IDEOGRAPH-FA15;Lo;0;L;51DE;;;;N;;;;; +FA16;CJK COMPATIBILITY IDEOGRAPH-FA16;Lo;0;L;732A;;;;N;;;;; +FA17;CJK COMPATIBILITY IDEOGRAPH-FA17;Lo;0;L;76CA;;;;N;;;;; +FA18;CJK COMPATIBILITY IDEOGRAPH-FA18;Lo;0;L;793C;;;;N;;;;; +FA19;CJK COMPATIBILITY IDEOGRAPH-FA19;Lo;0;L;795E;;;;N;;;;; +FA1A;CJK COMPATIBILITY IDEOGRAPH-FA1A;Lo;0;L;7965;;;;N;;;;; +FA1B;CJK COMPATIBILITY IDEOGRAPH-FA1B;Lo;0;L;798F;;;;N;;;;; +FA1C;CJK COMPATIBILITY IDEOGRAPH-FA1C;Lo;0;L;9756;;;;N;;;;; +FA1D;CJK COMPATIBILITY IDEOGRAPH-FA1D;Lo;0;L;7CBE;;;;N;;;;; +FA1E;CJK COMPATIBILITY IDEOGRAPH-FA1E;Lo;0;L;7FBD;;;;N;;;;; +FA1F;CJK COMPATIBILITY IDEOGRAPH-FA1F;Lo;0;L;;;;;N;;*;;; +FA20;CJK COMPATIBILITY IDEOGRAPH-FA20;Lo;0;L;8612;;;;N;;;;; +FA21;CJK COMPATIBILITY IDEOGRAPH-FA21;Lo;0;L;;;;;N;;;;; +FA22;CJK COMPATIBILITY IDEOGRAPH-FA22;Lo;0;L;8AF8;;;;N;;;;; +FA23;CJK COMPATIBILITY IDEOGRAPH-FA23;Lo;0;L;;;;;N;;*;;; +FA24;CJK COMPATIBILITY IDEOGRAPH-FA24;Lo;0;L;;;;;N;;;;; +FA25;CJK COMPATIBILITY IDEOGRAPH-FA25;Lo;0;L;9038;;;;N;;;;; +FA26;CJK COMPATIBILITY IDEOGRAPH-FA26;Lo;0;L;90FD;;;;N;;;;; +FA27;CJK COMPATIBILITY IDEOGRAPH-FA27;Lo;0;L;;;;;N;;;;; +FA28;CJK COMPATIBILITY IDEOGRAPH-FA28;Lo;0;L;;;;;N;;;;; +FA29;CJK COMPATIBILITY IDEOGRAPH-FA29;Lo;0;L;;;;;N;;;;; +FA2A;CJK COMPATIBILITY IDEOGRAPH-FA2A;Lo;0;L;98EF;;;;N;;;;; +FA2B;CJK COMPATIBILITY IDEOGRAPH-FA2B;Lo;0;L;98FC;;;;N;;;;; +FA2C;CJK COMPATIBILITY IDEOGRAPH-FA2C;Lo;0;L;9928;;;;N;;;;; +FA2D;CJK COMPATIBILITY IDEOGRAPH-FA2D;Lo;0;L;9DB4;;;;N;;;;; +FA30;CJK COMPATIBILITY IDEOGRAPH-FA30;Lo;0;L;4FAE;;;;N;;;;; +FA31;CJK COMPATIBILITY IDEOGRAPH-FA31;Lo;0;L;50E7;;;;N;;;;; +FA32;CJK COMPATIBILITY IDEOGRAPH-FA32;Lo;0;L;514D;;;;N;;;;; +FA33;CJK COMPATIBILITY IDEOGRAPH-FA33;Lo;0;L;52C9;;;;N;;;;; +FA34;CJK COMPATIBILITY IDEOGRAPH-FA34;Lo;0;L;52E4;;;;N;;;;; +FA35;CJK COMPATIBILITY IDEOGRAPH-FA35;Lo;0;L;5351;;;;N;;;;; +FA36;CJK COMPATIBILITY IDEOGRAPH-FA36;Lo;0;L;559D;;;;N;;;;; +FA37;CJK COMPATIBILITY IDEOGRAPH-FA37;Lo;0;L;5606;;;;N;;;;; +FA38;CJK COMPATIBILITY IDEOGRAPH-FA38;Lo;0;L;5668;;;;N;;;;; +FA39;CJK COMPATIBILITY IDEOGRAPH-FA39;Lo;0;L;5840;;;;N;;;;; +FA3A;CJK COMPATIBILITY IDEOGRAPH-FA3A;Lo;0;L;58A8;;;;N;;;;; +FA3B;CJK COMPATIBILITY IDEOGRAPH-FA3B;Lo;0;L;5C64;;;;N;;;;; +FA3C;CJK COMPATIBILITY IDEOGRAPH-FA3C;Lo;0;L;5C6E;;;;N;;;;; +FA3D;CJK COMPATIBILITY IDEOGRAPH-FA3D;Lo;0;L;6094;;;;N;;;;; +FA3E;CJK COMPATIBILITY IDEOGRAPH-FA3E;Lo;0;L;6168;;;;N;;;;; +FA3F;CJK COMPATIBILITY IDEOGRAPH-FA3F;Lo;0;L;618E;;;;N;;;;; +FA40;CJK COMPATIBILITY IDEOGRAPH-FA40;Lo;0;L;61F2;;;;N;;;;; +FA41;CJK COMPATIBILITY IDEOGRAPH-FA41;Lo;0;L;654F;;;;N;;;;; +FA42;CJK COMPATIBILITY IDEOGRAPH-FA42;Lo;0;L;65E2;;;;N;;;;; +FA43;CJK COMPATIBILITY IDEOGRAPH-FA43;Lo;0;L;6691;;;;N;;;;; +FA44;CJK COMPATIBILITY IDEOGRAPH-FA44;Lo;0;L;6885;;;;N;;;;; +FA45;CJK COMPATIBILITY IDEOGRAPH-FA45;Lo;0;L;6D77;;;;N;;;;; +FA46;CJK COMPATIBILITY IDEOGRAPH-FA46;Lo;0;L;6E1A;;;;N;;;;; +FA47;CJK COMPATIBILITY IDEOGRAPH-FA47;Lo;0;L;6F22;;;;N;;;;; +FA48;CJK COMPATIBILITY IDEOGRAPH-FA48;Lo;0;L;716E;;;;N;;;;; +FA49;CJK COMPATIBILITY IDEOGRAPH-FA49;Lo;0;L;722B;;;;N;;;;; +FA4A;CJK COMPATIBILITY IDEOGRAPH-FA4A;Lo;0;L;7422;;;;N;;;;; +FA4B;CJK COMPATIBILITY IDEOGRAPH-FA4B;Lo;0;L;7891;;;;N;;;;; +FA4C;CJK COMPATIBILITY IDEOGRAPH-FA4C;Lo;0;L;793E;;;;N;;;;; +FA4D;CJK COMPATIBILITY IDEOGRAPH-FA4D;Lo;0;L;7949;;;;N;;;;; +FA4E;CJK COMPATIBILITY IDEOGRAPH-FA4E;Lo;0;L;7948;;;;N;;;;; +FA4F;CJK COMPATIBILITY IDEOGRAPH-FA4F;Lo;0;L;7950;;;;N;;;;; +FA50;CJK COMPATIBILITY IDEOGRAPH-FA50;Lo;0;L;7956;;;;N;;;;; +FA51;CJK COMPATIBILITY IDEOGRAPH-FA51;Lo;0;L;795D;;;;N;;;;; +FA52;CJK COMPATIBILITY IDEOGRAPH-FA52;Lo;0;L;798D;;;;N;;;;; +FA53;CJK COMPATIBILITY IDEOGRAPH-FA53;Lo;0;L;798E;;;;N;;;;; +FA54;CJK COMPATIBILITY IDEOGRAPH-FA54;Lo;0;L;7A40;;;;N;;;;; +FA55;CJK COMPATIBILITY IDEOGRAPH-FA55;Lo;0;L;7A81;;;;N;;;;; +FA56;CJK COMPATIBILITY IDEOGRAPH-FA56;Lo;0;L;7BC0;;;;N;;;;; +FA57;CJK COMPATIBILITY IDEOGRAPH-FA57;Lo;0;L;7DF4;;;;N;;;;; +FA58;CJK COMPATIBILITY IDEOGRAPH-FA58;Lo;0;L;7E09;;;;N;;;;; +FA59;CJK COMPATIBILITY IDEOGRAPH-FA59;Lo;0;L;7E41;;;;N;;;;; +FA5A;CJK COMPATIBILITY IDEOGRAPH-FA5A;Lo;0;L;7F72;;;;N;;;;; +FA5B;CJK COMPATIBILITY IDEOGRAPH-FA5B;Lo;0;L;8005;;;;N;;;;; +FA5C;CJK COMPATIBILITY IDEOGRAPH-FA5C;Lo;0;L;81ED;;;;N;;;;; +FA5D;CJK COMPATIBILITY IDEOGRAPH-FA5D;Lo;0;L;8279;;;;N;;;;; +FA5E;CJK COMPATIBILITY IDEOGRAPH-FA5E;Lo;0;L;8279;;;;N;;;;; +FA5F;CJK COMPATIBILITY IDEOGRAPH-FA5F;Lo;0;L;8457;;;;N;;;;; +FA60;CJK COMPATIBILITY IDEOGRAPH-FA60;Lo;0;L;8910;;;;N;;;;; +FA61;CJK COMPATIBILITY IDEOGRAPH-FA61;Lo;0;L;8996;;;;N;;;;; +FA62;CJK COMPATIBILITY IDEOGRAPH-FA62;Lo;0;L;8B01;;;;N;;;;; +FA63;CJK COMPATIBILITY IDEOGRAPH-FA63;Lo;0;L;8B39;;;;N;;;;; +FA64;CJK COMPATIBILITY IDEOGRAPH-FA64;Lo;0;L;8CD3;;;;N;;;;; +FA65;CJK COMPATIBILITY IDEOGRAPH-FA65;Lo;0;L;8D08;;;;N;;;;; +FA66;CJK COMPATIBILITY IDEOGRAPH-FA66;Lo;0;L;8FB6;;;;N;;;;; +FA67;CJK COMPATIBILITY IDEOGRAPH-FA67;Lo;0;L;9038;;;;N;;;;; +FA68;CJK COMPATIBILITY IDEOGRAPH-FA68;Lo;0;L;96E3;;;;N;;;;; +FA69;CJK COMPATIBILITY IDEOGRAPH-FA69;Lo;0;L;97FF;;;;N;;;;; +FA6A;CJK COMPATIBILITY IDEOGRAPH-FA6A;Lo;0;L;983B;;;;N;;;;; +FB00;LATIN SMALL LIGATURE FF;Ll;0;L; 0066 0066;;;;N;;;;; +FB01;LATIN SMALL LIGATURE FI;Ll;0;L; 0066 0069;;;;N;;;;; +FB02;LATIN SMALL LIGATURE FL;Ll;0;L; 0066 006C;;;;N;;;;; +FB03;LATIN SMALL LIGATURE FFI;Ll;0;L; 0066 0066 0069;;;;N;;;;; +FB04;LATIN SMALL LIGATURE FFL;Ll;0;L; 0066 0066 006C;;;;N;;;;; +FB05;LATIN SMALL LIGATURE LONG S T;Ll;0;L; 017F 0074;;;;N;;;;; +FB06;LATIN SMALL LIGATURE ST;Ll;0;L; 0073 0074;;;;N;;;;; +FB13;ARMENIAN SMALL LIGATURE MEN NOW;Ll;0;L; 0574 0576;;;;N;;;;; +FB14;ARMENIAN SMALL LIGATURE MEN ECH;Ll;0;L; 0574 0565;;;;N;;;;; +FB15;ARMENIAN SMALL LIGATURE MEN INI;Ll;0;L; 0574 056B;;;;N;;;;; +FB16;ARMENIAN SMALL LIGATURE VEW NOW;Ll;0;L; 057E 0576;;;;N;;;;; +FB17;ARMENIAN SMALL LIGATURE MEN XEH;Ll;0;L; 0574 056D;;;;N;;;;; +FB1D;HEBREW LETTER YOD WITH HIRIQ;Lo;0;R;05D9 05B4;;;;N;;;;; +FB1E;HEBREW POINT JUDEO-SPANISH VARIKA;Mn;26;NSM;;;;;N;HEBREW POINT VARIKA;;;; +FB1F;HEBREW LIGATURE YIDDISH YOD YOD PATAH;Lo;0;R;05F2 05B7;;;;N;;;;; +FB20;HEBREW LETTER ALTERNATIVE AYIN;Lo;0;R; 05E2;;;;N;;;;; +FB21;HEBREW LETTER WIDE ALEF;Lo;0;R; 05D0;;;;N;;;;; +FB22;HEBREW LETTER WIDE DALET;Lo;0;R; 05D3;;;;N;;;;; +FB23;HEBREW LETTER WIDE HE;Lo;0;R; 05D4;;;;N;;;;; +FB24;HEBREW LETTER WIDE KAF;Lo;0;R; 05DB;;;;N;;;;; +FB25;HEBREW LETTER WIDE LAMED;Lo;0;R; 05DC;;;;N;;;;; +FB26;HEBREW LETTER WIDE FINAL MEM;Lo;0;R; 05DD;;;;N;;;;; +FB27;HEBREW LETTER WIDE RESH;Lo;0;R; 05E8;;;;N;;;;; +FB28;HEBREW LETTER WIDE TAV;Lo;0;R; 05EA;;;;N;;;;; +FB29;HEBREW LETTER ALTERNATIVE PLUS SIGN;Sm;0;ET; 002B;;;;N;;;;; +FB2A;HEBREW LETTER SHIN WITH SHIN DOT;Lo;0;R;05E9 05C1;;;;N;;;;; +FB2B;HEBREW LETTER SHIN WITH SIN DOT;Lo;0;R;05E9 05C2;;;;N;;;;; +FB2C;HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT;Lo;0;R;FB49 05C1;;;;N;;;;; +FB2D;HEBREW LETTER SHIN WITH DAGESH AND SIN DOT;Lo;0;R;FB49 05C2;;;;N;;;;; +FB2E;HEBREW LETTER ALEF WITH PATAH;Lo;0;R;05D0 05B7;;;;N;;;;; +FB2F;HEBREW LETTER ALEF WITH QAMATS;Lo;0;R;05D0 05B8;;;;N;;;;; +FB30;HEBREW LETTER ALEF WITH MAPIQ;Lo;0;R;05D0 05BC;;;;N;;;;; +FB31;HEBREW LETTER BET WITH DAGESH;Lo;0;R;05D1 05BC;;;;N;;;;; +FB32;HEBREW LETTER GIMEL WITH DAGESH;Lo;0;R;05D2 05BC;;;;N;;;;; +FB33;HEBREW LETTER DALET WITH DAGESH;Lo;0;R;05D3 05BC;;;;N;;;;; +FB34;HEBREW LETTER HE WITH MAPIQ;Lo;0;R;05D4 05BC;;;;N;;;;; +FB35;HEBREW LETTER VAV WITH DAGESH;Lo;0;R;05D5 05BC;;;;N;;;;; +FB36;HEBREW LETTER ZAYIN WITH DAGESH;Lo;0;R;05D6 05BC;;;;N;;;;; +FB38;HEBREW LETTER TET WITH DAGESH;Lo;0;R;05D8 05BC;;;;N;;;;; +FB39;HEBREW LETTER YOD WITH DAGESH;Lo;0;R;05D9 05BC;;;;N;;;;; +FB3A;HEBREW LETTER FINAL KAF WITH DAGESH;Lo;0;R;05DA 05BC;;;;N;;;;; +FB3B;HEBREW LETTER KAF WITH DAGESH;Lo;0;R;05DB 05BC;;;;N;;;;; +FB3C;HEBREW LETTER LAMED WITH DAGESH;Lo;0;R;05DC 05BC;;;;N;;;;; +FB3E;HEBREW LETTER MEM WITH DAGESH;Lo;0;R;05DE 05BC;;;;N;;;;; +FB40;HEBREW LETTER NUN WITH DAGESH;Lo;0;R;05E0 05BC;;;;N;;;;; +FB41;HEBREW LETTER SAMEKH WITH DAGESH;Lo;0;R;05E1 05BC;;;;N;;;;; +FB43;HEBREW LETTER FINAL PE WITH DAGESH;Lo;0;R;05E3 05BC;;;;N;;;;; +FB44;HEBREW LETTER PE WITH DAGESH;Lo;0;R;05E4 05BC;;;;N;;;;; +FB46;HEBREW LETTER TSADI WITH DAGESH;Lo;0;R;05E6 05BC;;;;N;;;;; +FB47;HEBREW LETTER QOF WITH DAGESH;Lo;0;R;05E7 05BC;;;;N;;;;; +FB48;HEBREW LETTER RESH WITH DAGESH;Lo;0;R;05E8 05BC;;;;N;;;;; +FB49;HEBREW LETTER SHIN WITH DAGESH;Lo;0;R;05E9 05BC;;;;N;;;;; +FB4A;HEBREW LETTER TAV WITH DAGESH;Lo;0;R;05EA 05BC;;;;N;;;;; +FB4B;HEBREW LETTER VAV WITH HOLAM;Lo;0;R;05D5 05B9;;;;N;;;;; +FB4C;HEBREW LETTER BET WITH RAFE;Lo;0;R;05D1 05BF;;;;N;;;;; +FB4D;HEBREW LETTER KAF WITH RAFE;Lo;0;R;05DB 05BF;;;;N;;;;; +FB4E;HEBREW LETTER PE WITH RAFE;Lo;0;R;05E4 05BF;;;;N;;;;; +FB4F;HEBREW LIGATURE ALEF LAMED;Lo;0;R; 05D0 05DC;;;;N;;;;; +FB50;ARABIC LETTER ALEF WASLA ISOLATED FORM;Lo;0;AL; 0671;;;;N;;;;; +FB51;ARABIC LETTER ALEF WASLA FINAL FORM;Lo;0;AL; 0671;;;;N;;;;; +FB52;ARABIC LETTER BEEH ISOLATED FORM;Lo;0;AL; 067B;;;;N;;;;; +FB53;ARABIC LETTER BEEH FINAL FORM;Lo;0;AL; 067B;;;;N;;;;; +FB54;ARABIC LETTER BEEH INITIAL FORM;Lo;0;AL; 067B;;;;N;;;;; +FB55;ARABIC LETTER BEEH MEDIAL FORM;Lo;0;AL; 067B;;;;N;;;;; +FB56;ARABIC LETTER PEH ISOLATED FORM;Lo;0;AL; 067E;;;;N;;;;; +FB57;ARABIC LETTER PEH FINAL FORM;Lo;0;AL; 067E;;;;N;;;;; +FB58;ARABIC LETTER PEH INITIAL FORM;Lo;0;AL; 067E;;;;N;;;;; +FB59;ARABIC LETTER PEH MEDIAL FORM;Lo;0;AL; 067E;;;;N;;;;; +FB5A;ARABIC LETTER BEHEH ISOLATED FORM;Lo;0;AL; 0680;;;;N;;;;; +FB5B;ARABIC LETTER BEHEH FINAL FORM;Lo;0;AL; 0680;;;;N;;;;; +FB5C;ARABIC LETTER BEHEH INITIAL FORM;Lo;0;AL; 0680;;;;N;;;;; +FB5D;ARABIC LETTER BEHEH MEDIAL FORM;Lo;0;AL; 0680;;;;N;;;;; +FB5E;ARABIC LETTER TTEHEH ISOLATED FORM;Lo;0;AL; 067A;;;;N;;;;; +FB5F;ARABIC LETTER TTEHEH FINAL FORM;Lo;0;AL; 067A;;;;N;;;;; +FB60;ARABIC LETTER TTEHEH INITIAL FORM;Lo;0;AL; 067A;;;;N;;;;; +FB61;ARABIC LETTER TTEHEH MEDIAL FORM;Lo;0;AL; 067A;;;;N;;;;; +FB62;ARABIC LETTER TEHEH ISOLATED FORM;Lo;0;AL; 067F;;;;N;;;;; +FB63;ARABIC LETTER TEHEH FINAL FORM;Lo;0;AL; 067F;;;;N;;;;; +FB64;ARABIC LETTER TEHEH INITIAL FORM;Lo;0;AL; 067F;;;;N;;;;; +FB65;ARABIC LETTER TEHEH MEDIAL FORM;Lo;0;AL; 067F;;;;N;;;;; +FB66;ARABIC LETTER TTEH ISOLATED FORM;Lo;0;AL; 0679;;;;N;;;;; +FB67;ARABIC LETTER TTEH FINAL FORM;Lo;0;AL; 0679;;;;N;;;;; +FB68;ARABIC LETTER TTEH INITIAL FORM;Lo;0;AL; 0679;;;;N;;;;; +FB69;ARABIC LETTER TTEH MEDIAL FORM;Lo;0;AL; 0679;;;;N;;;;; +FB6A;ARABIC LETTER VEH ISOLATED FORM;Lo;0;AL; 06A4;;;;N;;;;; +FB6B;ARABIC LETTER VEH FINAL FORM;Lo;0;AL; 06A4;;;;N;;;;; +FB6C;ARABIC LETTER VEH INITIAL FORM;Lo;0;AL; 06A4;;;;N;;;;; +FB6D;ARABIC LETTER VEH MEDIAL FORM;Lo;0;AL; 06A4;;;;N;;;;; +FB6E;ARABIC LETTER PEHEH ISOLATED FORM;Lo;0;AL; 06A6;;;;N;;;;; +FB6F;ARABIC LETTER PEHEH FINAL FORM;Lo;0;AL; 06A6;;;;N;;;;; +FB70;ARABIC LETTER PEHEH INITIAL FORM;Lo;0;AL; 06A6;;;;N;;;;; +FB71;ARABIC LETTER PEHEH MEDIAL FORM;Lo;0;AL; 06A6;;;;N;;;;; +FB72;ARABIC LETTER DYEH ISOLATED FORM;Lo;0;AL; 0684;;;;N;;;;; +FB73;ARABIC LETTER DYEH FINAL FORM;Lo;0;AL; 0684;;;;N;;;;; +FB74;ARABIC LETTER DYEH INITIAL FORM;Lo;0;AL; 0684;;;;N;;;;; +FB75;ARABIC LETTER DYEH MEDIAL FORM;Lo;0;AL; 0684;;;;N;;;;; +FB76;ARABIC LETTER NYEH ISOLATED FORM;Lo;0;AL; 0683;;;;N;;;;; +FB77;ARABIC LETTER NYEH FINAL FORM;Lo;0;AL; 0683;;;;N;;;;; +FB78;ARABIC LETTER NYEH INITIAL FORM;Lo;0;AL; 0683;;;;N;;;;; +FB79;ARABIC LETTER NYEH MEDIAL FORM;Lo;0;AL; 0683;;;;N;;;;; +FB7A;ARABIC LETTER TCHEH ISOLATED FORM;Lo;0;AL; 0686;;;;N;;;;; +FB7B;ARABIC LETTER TCHEH FINAL FORM;Lo;0;AL; 0686;;;;N;;;;; +FB7C;ARABIC LETTER TCHEH INITIAL FORM;Lo;0;AL; 0686;;;;N;;;;; +FB7D;ARABIC LETTER TCHEH MEDIAL FORM;Lo;0;AL; 0686;;;;N;;;;; +FB7E;ARABIC LETTER TCHEHEH ISOLATED FORM;Lo;0;AL; 0687;;;;N;;;;; +FB7F;ARABIC LETTER TCHEHEH FINAL FORM;Lo;0;AL; 0687;;;;N;;;;; +FB80;ARABIC LETTER TCHEHEH INITIAL FORM;Lo;0;AL; 0687;;;;N;;;;; +FB81;ARABIC LETTER TCHEHEH MEDIAL FORM;Lo;0;AL; 0687;;;;N;;;;; +FB82;ARABIC LETTER DDAHAL ISOLATED FORM;Lo;0;AL; 068D;;;;N;;;;; +FB83;ARABIC LETTER DDAHAL FINAL FORM;Lo;0;AL; 068D;;;;N;;;;; +FB84;ARABIC LETTER DAHAL ISOLATED FORM;Lo;0;AL; 068C;;;;N;;;;; +FB85;ARABIC LETTER DAHAL FINAL FORM;Lo;0;AL; 068C;;;;N;;;;; +FB86;ARABIC LETTER DUL ISOLATED FORM;Lo;0;AL; 068E;;;;N;;;;; +FB87;ARABIC LETTER DUL FINAL FORM;Lo;0;AL; 068E;;;;N;;;;; +FB88;ARABIC LETTER DDAL ISOLATED FORM;Lo;0;AL; 0688;;;;N;;;;; +FB89;ARABIC LETTER DDAL FINAL FORM;Lo;0;AL; 0688;;;;N;;;;; +FB8A;ARABIC LETTER JEH ISOLATED FORM;Lo;0;AL; 0698;;;;N;;;;; +FB8B;ARABIC LETTER JEH FINAL FORM;Lo;0;AL; 0698;;;;N;;;;; +FB8C;ARABIC LETTER RREH ISOLATED FORM;Lo;0;AL; 0691;;;;N;;;;; +FB8D;ARABIC LETTER RREH FINAL FORM;Lo;0;AL; 0691;;;;N;;;;; +FB8E;ARABIC LETTER KEHEH ISOLATED FORM;Lo;0;AL; 06A9;;;;N;;;;; +FB8F;ARABIC LETTER KEHEH FINAL FORM;Lo;0;AL; 06A9;;;;N;;;;; +FB90;ARABIC LETTER KEHEH INITIAL FORM;Lo;0;AL; 06A9;;;;N;;;;; +FB91;ARABIC LETTER KEHEH MEDIAL FORM;Lo;0;AL; 06A9;;;;N;;;;; +FB92;ARABIC LETTER GAF ISOLATED FORM;Lo;0;AL; 06AF;;;;N;;;;; +FB93;ARABIC LETTER GAF FINAL FORM;Lo;0;AL; 06AF;;;;N;;;;; +FB94;ARABIC LETTER GAF INITIAL FORM;Lo;0;AL; 06AF;;;;N;;;;; +FB95;ARABIC LETTER GAF MEDIAL FORM;Lo;0;AL; 06AF;;;;N;;;;; +FB96;ARABIC LETTER GUEH ISOLATED FORM;Lo;0;AL; 06B3;;;;N;;;;; +FB97;ARABIC LETTER GUEH FINAL FORM;Lo;0;AL; 06B3;;;;N;;;;; +FB98;ARABIC LETTER GUEH INITIAL FORM;Lo;0;AL; 06B3;;;;N;;;;; +FB99;ARABIC LETTER GUEH MEDIAL FORM;Lo;0;AL; 06B3;;;;N;;;;; +FB9A;ARABIC LETTER NGOEH ISOLATED FORM;Lo;0;AL; 06B1;;;;N;;;;; +FB9B;ARABIC LETTER NGOEH FINAL FORM;Lo;0;AL; 06B1;;;;N;;;;; +FB9C;ARABIC LETTER NGOEH INITIAL FORM;Lo;0;AL; 06B1;;;;N;;;;; +FB9D;ARABIC LETTER NGOEH MEDIAL FORM;Lo;0;AL; 06B1;;;;N;;;;; +FB9E;ARABIC LETTER NOON GHUNNA ISOLATED FORM;Lo;0;AL; 06BA;;;;N;;;;; +FB9F;ARABIC LETTER NOON GHUNNA FINAL FORM;Lo;0;AL; 06BA;;;;N;;;;; +FBA0;ARABIC LETTER RNOON ISOLATED FORM;Lo;0;AL; 06BB;;;;N;;;;; +FBA1;ARABIC LETTER RNOON FINAL FORM;Lo;0;AL; 06BB;;;;N;;;;; +FBA2;ARABIC LETTER RNOON INITIAL FORM;Lo;0;AL; 06BB;;;;N;;;;; +FBA3;ARABIC LETTER RNOON MEDIAL FORM;Lo;0;AL; 06BB;;;;N;;;;; +FBA4;ARABIC LETTER HEH WITH YEH ABOVE ISOLATED FORM;Lo;0;AL; 06C0;;;;N;;;;; +FBA5;ARABIC LETTER HEH WITH YEH ABOVE FINAL FORM;Lo;0;AL; 06C0;;;;N;;;;; +FBA6;ARABIC LETTER HEH GOAL ISOLATED FORM;Lo;0;AL; 06C1;;;;N;;;;; +FBA7;ARABIC LETTER HEH GOAL FINAL FORM;Lo;0;AL; 06C1;;;;N;;;;; +FBA8;ARABIC LETTER HEH GOAL INITIAL FORM;Lo;0;AL; 06C1;;;;N;;;;; +FBA9;ARABIC LETTER HEH GOAL MEDIAL FORM;Lo;0;AL; 06C1;;;;N;;;;; +FBAA;ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM;Lo;0;AL; 06BE;;;;N;;;;; +FBAB;ARABIC LETTER HEH DOACHASHMEE FINAL FORM;Lo;0;AL; 06BE;;;;N;;;;; +FBAC;ARABIC LETTER HEH DOACHASHMEE INITIAL FORM;Lo;0;AL; 06BE;;;;N;;;;; +FBAD;ARABIC LETTER HEH DOACHASHMEE MEDIAL FORM;Lo;0;AL; 06BE;;;;N;;;;; +FBAE;ARABIC LETTER YEH BARREE ISOLATED FORM;Lo;0;AL; 06D2;;;;N;;;;; +FBAF;ARABIC LETTER YEH BARREE FINAL FORM;Lo;0;AL; 06D2;;;;N;;;;; +FBB0;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 06D3;;;;N;;;;; +FBB1;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 06D3;;;;N;;;;; +FBD3;ARABIC LETTER NG ISOLATED FORM;Lo;0;AL; 06AD;;;;N;;;;; +FBD4;ARABIC LETTER NG FINAL FORM;Lo;0;AL; 06AD;;;;N;;;;; +FBD5;ARABIC LETTER NG INITIAL FORM;Lo;0;AL; 06AD;;;;N;;;;; +FBD6;ARABIC LETTER NG MEDIAL FORM;Lo;0;AL; 06AD;;;;N;;;;; +FBD7;ARABIC LETTER U ISOLATED FORM;Lo;0;AL; 06C7;;;;N;;;;; +FBD8;ARABIC LETTER U FINAL FORM;Lo;0;AL; 06C7;;;;N;;;;; +FBD9;ARABIC LETTER OE ISOLATED FORM;Lo;0;AL; 06C6;;;;N;;;;; +FBDA;ARABIC LETTER OE FINAL FORM;Lo;0;AL; 06C6;;;;N;;;;; +FBDB;ARABIC LETTER YU ISOLATED FORM;Lo;0;AL; 06C8;;;;N;;;;; +FBDC;ARABIC LETTER YU FINAL FORM;Lo;0;AL; 06C8;;;;N;;;;; +FBDD;ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0677;;;;N;;;;; +FBDE;ARABIC LETTER VE ISOLATED FORM;Lo;0;AL; 06CB;;;;N;;;;; +FBDF;ARABIC LETTER VE FINAL FORM;Lo;0;AL; 06CB;;;;N;;;;; +FBE0;ARABIC LETTER KIRGHIZ OE ISOLATED FORM;Lo;0;AL; 06C5;;;;N;;;;; +FBE1;ARABIC LETTER KIRGHIZ OE FINAL FORM;Lo;0;AL; 06C5;;;;N;;;;; +FBE2;ARABIC LETTER KIRGHIZ YU ISOLATED FORM;Lo;0;AL; 06C9;;;;N;;;;; +FBE3;ARABIC LETTER KIRGHIZ YU FINAL FORM;Lo;0;AL; 06C9;;;;N;;;;; +FBE4;ARABIC LETTER E ISOLATED FORM;Lo;0;AL; 06D0;;;;N;;;;; +FBE5;ARABIC LETTER E FINAL FORM;Lo;0;AL; 06D0;;;;N;;;;; +FBE6;ARABIC LETTER E INITIAL FORM;Lo;0;AL; 06D0;;;;N;;;;; +FBE7;ARABIC LETTER E MEDIAL FORM;Lo;0;AL; 06D0;;;;N;;;;; +FBE8;ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA INITIAL FORM;Lo;0;AL; 0649;;;;N;;;;; +FBE9;ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA MEDIAL FORM;Lo;0;AL; 0649;;;;N;;;;; +FBEA;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM;Lo;0;AL; 0626 0627;;;;N;;;;; +FBEB;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF FINAL FORM;Lo;0;AL; 0626 0627;;;;N;;;;; +FBEC;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE ISOLATED FORM;Lo;0;AL; 0626 06D5;;;;N;;;;; +FBED;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE FINAL FORM;Lo;0;AL; 0626 06D5;;;;N;;;;; +FBEE;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW ISOLATED FORM;Lo;0;AL; 0626 0648;;;;N;;;;; +FBEF;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW FINAL FORM;Lo;0;AL; 0626 0648;;;;N;;;;; +FBF0;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U ISOLATED FORM;Lo;0;AL; 0626 06C7;;;;N;;;;; +FBF1;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U FINAL FORM;Lo;0;AL; 0626 06C7;;;;N;;;;; +FBF2;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE ISOLATED FORM;Lo;0;AL; 0626 06C6;;;;N;;;;; +FBF3;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE FINAL FORM;Lo;0;AL; 0626 06C6;;;;N;;;;; +FBF4;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU ISOLATED FORM;Lo;0;AL; 0626 06C8;;;;N;;;;; +FBF5;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU FINAL FORM;Lo;0;AL; 0626 06C8;;;;N;;;;; +FBF6;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E ISOLATED FORM;Lo;0;AL; 0626 06D0;;;;N;;;;; +FBF7;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E FINAL FORM;Lo;0;AL; 0626 06D0;;;;N;;;;; +FBF8;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E INITIAL FORM;Lo;0;AL; 0626 06D0;;;;N;;;;; +FBF9;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0626 0649;;;;N;;;;; +FBFA;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0626 0649;;;;N;;;;; +FBFB;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA INITIAL FORM;Lo;0;AL; 0626 0649;;;;N;;;;; +FBFC;ARABIC LETTER FARSI YEH ISOLATED FORM;Lo;0;AL; 06CC;;;;N;;;;; +FBFD;ARABIC LETTER FARSI YEH FINAL FORM;Lo;0;AL; 06CC;;;;N;;;;; +FBFE;ARABIC LETTER FARSI YEH INITIAL FORM;Lo;0;AL; 06CC;;;;N;;;;; +FBFF;ARABIC LETTER FARSI YEH MEDIAL FORM;Lo;0;AL; 06CC;;;;N;;;;; +FC00;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM ISOLATED FORM;Lo;0;AL; 0626 062C;;;;N;;;;; +FC01;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH ISOLATED FORM;Lo;0;AL; 0626 062D;;;;N;;;;; +FC02;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM ISOLATED FORM;Lo;0;AL; 0626 0645;;;;N;;;;; +FC03;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0626 0649;;;;N;;;;; +FC04;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH ISOLATED FORM;Lo;0;AL; 0626 064A;;;;N;;;;; +FC05;ARABIC LIGATURE BEH WITH JEEM ISOLATED FORM;Lo;0;AL; 0628 062C;;;;N;;;;; +FC06;ARABIC LIGATURE BEH WITH HAH ISOLATED FORM;Lo;0;AL; 0628 062D;;;;N;;;;; +FC07;ARABIC LIGATURE BEH WITH KHAH ISOLATED FORM;Lo;0;AL; 0628 062E;;;;N;;;;; +FC08;ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM;Lo;0;AL; 0628 0645;;;;N;;;;; +FC09;ARABIC LIGATURE BEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0628 0649;;;;N;;;;; +FC0A;ARABIC LIGATURE BEH WITH YEH ISOLATED FORM;Lo;0;AL; 0628 064A;;;;N;;;;; +FC0B;ARABIC LIGATURE TEH WITH JEEM ISOLATED FORM;Lo;0;AL; 062A 062C;;;;N;;;;; +FC0C;ARABIC LIGATURE TEH WITH HAH ISOLATED FORM;Lo;0;AL; 062A 062D;;;;N;;;;; +FC0D;ARABIC LIGATURE TEH WITH KHAH ISOLATED FORM;Lo;0;AL; 062A 062E;;;;N;;;;; +FC0E;ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM;Lo;0;AL; 062A 0645;;;;N;;;;; +FC0F;ARABIC LIGATURE TEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062A 0649;;;;N;;;;; +FC10;ARABIC LIGATURE TEH WITH YEH ISOLATED FORM;Lo;0;AL; 062A 064A;;;;N;;;;; +FC11;ARABIC LIGATURE THEH WITH JEEM ISOLATED FORM;Lo;0;AL; 062B 062C;;;;N;;;;; +FC12;ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM;Lo;0;AL; 062B 0645;;;;N;;;;; +FC13;ARABIC LIGATURE THEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062B 0649;;;;N;;;;; +FC14;ARABIC LIGATURE THEH WITH YEH ISOLATED FORM;Lo;0;AL; 062B 064A;;;;N;;;;; +FC15;ARABIC LIGATURE JEEM WITH HAH ISOLATED FORM;Lo;0;AL; 062C 062D;;;;N;;;;; +FC16;ARABIC LIGATURE JEEM WITH MEEM ISOLATED FORM;Lo;0;AL; 062C 0645;;;;N;;;;; +FC17;ARABIC LIGATURE HAH WITH JEEM ISOLATED FORM;Lo;0;AL; 062D 062C;;;;N;;;;; +FC18;ARABIC LIGATURE HAH WITH MEEM ISOLATED FORM;Lo;0;AL; 062D 0645;;;;N;;;;; +FC19;ARABIC LIGATURE KHAH WITH JEEM ISOLATED FORM;Lo;0;AL; 062E 062C;;;;N;;;;; +FC1A;ARABIC LIGATURE KHAH WITH HAH ISOLATED FORM;Lo;0;AL; 062E 062D;;;;N;;;;; +FC1B;ARABIC LIGATURE KHAH WITH MEEM ISOLATED FORM;Lo;0;AL; 062E 0645;;;;N;;;;; +FC1C;ARABIC LIGATURE SEEN WITH JEEM ISOLATED FORM;Lo;0;AL; 0633 062C;;;;N;;;;; +FC1D;ARABIC LIGATURE SEEN WITH HAH ISOLATED FORM;Lo;0;AL; 0633 062D;;;;N;;;;; +FC1E;ARABIC LIGATURE SEEN WITH KHAH ISOLATED FORM;Lo;0;AL; 0633 062E;;;;N;;;;; +FC1F;ARABIC LIGATURE SEEN WITH MEEM ISOLATED FORM;Lo;0;AL; 0633 0645;;;;N;;;;; +FC20;ARABIC LIGATURE SAD WITH HAH ISOLATED FORM;Lo;0;AL; 0635 062D;;;;N;;;;; +FC21;ARABIC LIGATURE SAD WITH MEEM ISOLATED FORM;Lo;0;AL; 0635 0645;;;;N;;;;; +FC22;ARABIC LIGATURE DAD WITH JEEM ISOLATED FORM;Lo;0;AL; 0636 062C;;;;N;;;;; +FC23;ARABIC LIGATURE DAD WITH HAH ISOLATED FORM;Lo;0;AL; 0636 062D;;;;N;;;;; +FC24;ARABIC LIGATURE DAD WITH KHAH ISOLATED FORM;Lo;0;AL; 0636 062E;;;;N;;;;; +FC25;ARABIC LIGATURE DAD WITH MEEM ISOLATED FORM;Lo;0;AL; 0636 0645;;;;N;;;;; +FC26;ARABIC LIGATURE TAH WITH HAH ISOLATED FORM;Lo;0;AL; 0637 062D;;;;N;;;;; +FC27;ARABIC LIGATURE TAH WITH MEEM ISOLATED FORM;Lo;0;AL; 0637 0645;;;;N;;;;; +FC28;ARABIC LIGATURE ZAH WITH MEEM ISOLATED FORM;Lo;0;AL; 0638 0645;;;;N;;;;; +FC29;ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM;Lo;0;AL; 0639 062C;;;;N;;;;; +FC2A;ARABIC LIGATURE AIN WITH MEEM ISOLATED FORM;Lo;0;AL; 0639 0645;;;;N;;;;; +FC2B;ARABIC LIGATURE GHAIN WITH JEEM ISOLATED FORM;Lo;0;AL; 063A 062C;;;;N;;;;; +FC2C;ARABIC LIGATURE GHAIN WITH MEEM ISOLATED FORM;Lo;0;AL; 063A 0645;;;;N;;;;; +FC2D;ARABIC LIGATURE FEH WITH JEEM ISOLATED FORM;Lo;0;AL; 0641 062C;;;;N;;;;; +FC2E;ARABIC LIGATURE FEH WITH HAH ISOLATED FORM;Lo;0;AL; 0641 062D;;;;N;;;;; +FC2F;ARABIC LIGATURE FEH WITH KHAH ISOLATED FORM;Lo;0;AL; 0641 062E;;;;N;;;;; +FC30;ARABIC LIGATURE FEH WITH MEEM ISOLATED FORM;Lo;0;AL; 0641 0645;;;;N;;;;; +FC31;ARABIC LIGATURE FEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0641 0649;;;;N;;;;; +FC32;ARABIC LIGATURE FEH WITH YEH ISOLATED FORM;Lo;0;AL; 0641 064A;;;;N;;;;; +FC33;ARABIC LIGATURE QAF WITH HAH ISOLATED FORM;Lo;0;AL; 0642 062D;;;;N;;;;; +FC34;ARABIC LIGATURE QAF WITH MEEM ISOLATED FORM;Lo;0;AL; 0642 0645;;;;N;;;;; +FC35;ARABIC LIGATURE QAF WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0642 0649;;;;N;;;;; +FC36;ARABIC LIGATURE QAF WITH YEH ISOLATED FORM;Lo;0;AL; 0642 064A;;;;N;;;;; +FC37;ARABIC LIGATURE KAF WITH ALEF ISOLATED FORM;Lo;0;AL; 0643 0627;;;;N;;;;; +FC38;ARABIC LIGATURE KAF WITH JEEM ISOLATED FORM;Lo;0;AL; 0643 062C;;;;N;;;;; +FC39;ARABIC LIGATURE KAF WITH HAH ISOLATED FORM;Lo;0;AL; 0643 062D;;;;N;;;;; +FC3A;ARABIC LIGATURE KAF WITH KHAH ISOLATED FORM;Lo;0;AL; 0643 062E;;;;N;;;;; +FC3B;ARABIC LIGATURE KAF WITH LAM ISOLATED FORM;Lo;0;AL; 0643 0644;;;;N;;;;; +FC3C;ARABIC LIGATURE KAF WITH MEEM ISOLATED FORM;Lo;0;AL; 0643 0645;;;;N;;;;; +FC3D;ARABIC LIGATURE KAF WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0643 0649;;;;N;;;;; +FC3E;ARABIC LIGATURE KAF WITH YEH ISOLATED FORM;Lo;0;AL; 0643 064A;;;;N;;;;; +FC3F;ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM;Lo;0;AL; 0644 062C;;;;N;;;;; +FC40;ARABIC LIGATURE LAM WITH HAH ISOLATED FORM;Lo;0;AL; 0644 062D;;;;N;;;;; +FC41;ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM;Lo;0;AL; 0644 062E;;;;N;;;;; +FC42;ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM;Lo;0;AL; 0644 0645;;;;N;;;;; +FC43;ARABIC LIGATURE LAM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0644 0649;;;;N;;;;; +FC44;ARABIC LIGATURE LAM WITH YEH ISOLATED FORM;Lo;0;AL; 0644 064A;;;;N;;;;; +FC45;ARABIC LIGATURE MEEM WITH JEEM ISOLATED FORM;Lo;0;AL; 0645 062C;;;;N;;;;; +FC46;ARABIC LIGATURE MEEM WITH HAH ISOLATED FORM;Lo;0;AL; 0645 062D;;;;N;;;;; +FC47;ARABIC LIGATURE MEEM WITH KHAH ISOLATED FORM;Lo;0;AL; 0645 062E;;;;N;;;;; +FC48;ARABIC LIGATURE MEEM WITH MEEM ISOLATED FORM;Lo;0;AL; 0645 0645;;;;N;;;;; +FC49;ARABIC LIGATURE MEEM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0645 0649;;;;N;;;;; +FC4A;ARABIC LIGATURE MEEM WITH YEH ISOLATED FORM;Lo;0;AL; 0645 064A;;;;N;;;;; +FC4B;ARABIC LIGATURE NOON WITH JEEM ISOLATED FORM;Lo;0;AL; 0646 062C;;;;N;;;;; +FC4C;ARABIC LIGATURE NOON WITH HAH ISOLATED FORM;Lo;0;AL; 0646 062D;;;;N;;;;; +FC4D;ARABIC LIGATURE NOON WITH KHAH ISOLATED FORM;Lo;0;AL; 0646 062E;;;;N;;;;; +FC4E;ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM;Lo;0;AL; 0646 0645;;;;N;;;;; +FC4F;ARABIC LIGATURE NOON WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0646 0649;;;;N;;;;; +FC50;ARABIC LIGATURE NOON WITH YEH ISOLATED FORM;Lo;0;AL; 0646 064A;;;;N;;;;; +FC51;ARABIC LIGATURE HEH WITH JEEM ISOLATED FORM;Lo;0;AL; 0647 062C;;;;N;;;;; +FC52;ARABIC LIGATURE HEH WITH MEEM ISOLATED FORM;Lo;0;AL; 0647 0645;;;;N;;;;; +FC53;ARABIC LIGATURE HEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0647 0649;;;;N;;;;; +FC54;ARABIC LIGATURE HEH WITH YEH ISOLATED FORM;Lo;0;AL; 0647 064A;;;;N;;;;; +FC55;ARABIC LIGATURE YEH WITH JEEM ISOLATED FORM;Lo;0;AL; 064A 062C;;;;N;;;;; +FC56;ARABIC LIGATURE YEH WITH HAH ISOLATED FORM;Lo;0;AL; 064A 062D;;;;N;;;;; +FC57;ARABIC LIGATURE YEH WITH KHAH ISOLATED FORM;Lo;0;AL; 064A 062E;;;;N;;;;; +FC58;ARABIC LIGATURE YEH WITH MEEM ISOLATED FORM;Lo;0;AL; 064A 0645;;;;N;;;;; +FC59;ARABIC LIGATURE YEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 064A 0649;;;;N;;;;; +FC5A;ARABIC LIGATURE YEH WITH YEH ISOLATED FORM;Lo;0;AL; 064A 064A;;;;N;;;;; +FC5B;ARABIC LIGATURE THAL WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL; 0630 0670;;;;N;;;;; +FC5C;ARABIC LIGATURE REH WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL; 0631 0670;;;;N;;;;; +FC5D;ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL; 0649 0670;;;;N;;;;; +FC5E;ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM;Lo;0;AL; 0020 064C 0651;;;;N;;;;; +FC5F;ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM;Lo;0;AL; 0020 064D 0651;;;;N;;;;; +FC60;ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM;Lo;0;AL; 0020 064E 0651;;;;N;;;;; +FC61;ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM;Lo;0;AL; 0020 064F 0651;;;;N;;;;; +FC62;ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM;Lo;0;AL; 0020 0650 0651;;;;N;;;;; +FC63;ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL; 0020 0651 0670;;;;N;;;;; +FC64;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH REH FINAL FORM;Lo;0;AL; 0626 0631;;;;N;;;;; +FC65;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ZAIN FINAL FORM;Lo;0;AL; 0626 0632;;;;N;;;;; +FC66;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM FINAL FORM;Lo;0;AL; 0626 0645;;;;N;;;;; +FC67;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH NOON FINAL FORM;Lo;0;AL; 0626 0646;;;;N;;;;; +FC68;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0626 0649;;;;N;;;;; +FC69;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH FINAL FORM;Lo;0;AL; 0626 064A;;;;N;;;;; +FC6A;ARABIC LIGATURE BEH WITH REH FINAL FORM;Lo;0;AL; 0628 0631;;;;N;;;;; +FC6B;ARABIC LIGATURE BEH WITH ZAIN FINAL FORM;Lo;0;AL; 0628 0632;;;;N;;;;; +FC6C;ARABIC LIGATURE BEH WITH MEEM FINAL FORM;Lo;0;AL; 0628 0645;;;;N;;;;; +FC6D;ARABIC LIGATURE BEH WITH NOON FINAL FORM;Lo;0;AL; 0628 0646;;;;N;;;;; +FC6E;ARABIC LIGATURE BEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0628 0649;;;;N;;;;; +FC6F;ARABIC LIGATURE BEH WITH YEH FINAL FORM;Lo;0;AL; 0628 064A;;;;N;;;;; +FC70;ARABIC LIGATURE TEH WITH REH FINAL FORM;Lo;0;AL; 062A 0631;;;;N;;;;; +FC71;ARABIC LIGATURE TEH WITH ZAIN FINAL FORM;Lo;0;AL; 062A 0632;;;;N;;;;; +FC72;ARABIC LIGATURE TEH WITH MEEM FINAL FORM;Lo;0;AL; 062A 0645;;;;N;;;;; +FC73;ARABIC LIGATURE TEH WITH NOON FINAL FORM;Lo;0;AL; 062A 0646;;;;N;;;;; +FC74;ARABIC LIGATURE TEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062A 0649;;;;N;;;;; +FC75;ARABIC LIGATURE TEH WITH YEH FINAL FORM;Lo;0;AL; 062A 064A;;;;N;;;;; +FC76;ARABIC LIGATURE THEH WITH REH FINAL FORM;Lo;0;AL; 062B 0631;;;;N;;;;; +FC77;ARABIC LIGATURE THEH WITH ZAIN FINAL FORM;Lo;0;AL; 062B 0632;;;;N;;;;; +FC78;ARABIC LIGATURE THEH WITH MEEM FINAL FORM;Lo;0;AL; 062B 0645;;;;N;;;;; +FC79;ARABIC LIGATURE THEH WITH NOON FINAL FORM;Lo;0;AL; 062B 0646;;;;N;;;;; +FC7A;ARABIC LIGATURE THEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062B 0649;;;;N;;;;; +FC7B;ARABIC LIGATURE THEH WITH YEH FINAL FORM;Lo;0;AL; 062B 064A;;;;N;;;;; +FC7C;ARABIC LIGATURE FEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0641 0649;;;;N;;;;; +FC7D;ARABIC LIGATURE FEH WITH YEH FINAL FORM;Lo;0;AL; 0641 064A;;;;N;;;;; +FC7E;ARABIC LIGATURE QAF WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0642 0649;;;;N;;;;; +FC7F;ARABIC LIGATURE QAF WITH YEH FINAL FORM;Lo;0;AL; 0642 064A;;;;N;;;;; +FC80;ARABIC LIGATURE KAF WITH ALEF FINAL FORM;Lo;0;AL; 0643 0627;;;;N;;;;; +FC81;ARABIC LIGATURE KAF WITH LAM FINAL FORM;Lo;0;AL; 0643 0644;;;;N;;;;; +FC82;ARABIC LIGATURE KAF WITH MEEM FINAL FORM;Lo;0;AL; 0643 0645;;;;N;;;;; +FC83;ARABIC LIGATURE KAF WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0643 0649;;;;N;;;;; +FC84;ARABIC LIGATURE KAF WITH YEH FINAL FORM;Lo;0;AL; 0643 064A;;;;N;;;;; +FC85;ARABIC LIGATURE LAM WITH MEEM FINAL FORM;Lo;0;AL; 0644 0645;;;;N;;;;; +FC86;ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0644 0649;;;;N;;;;; +FC87;ARABIC LIGATURE LAM WITH YEH FINAL FORM;Lo;0;AL; 0644 064A;;;;N;;;;; +FC88;ARABIC LIGATURE MEEM WITH ALEF FINAL FORM;Lo;0;AL; 0645 0627;;;;N;;;;; +FC89;ARABIC LIGATURE MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0645 0645;;;;N;;;;; +FC8A;ARABIC LIGATURE NOON WITH REH FINAL FORM;Lo;0;AL; 0646 0631;;;;N;;;;; +FC8B;ARABIC LIGATURE NOON WITH ZAIN FINAL FORM;Lo;0;AL; 0646 0632;;;;N;;;;; +FC8C;ARABIC LIGATURE NOON WITH MEEM FINAL FORM;Lo;0;AL; 0646 0645;;;;N;;;;; +FC8D;ARABIC LIGATURE NOON WITH NOON FINAL FORM;Lo;0;AL; 0646 0646;;;;N;;;;; +FC8E;ARABIC LIGATURE NOON WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0646 0649;;;;N;;;;; +FC8F;ARABIC LIGATURE NOON WITH YEH FINAL FORM;Lo;0;AL; 0646 064A;;;;N;;;;; +FC90;ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF FINAL FORM;Lo;0;AL; 0649 0670;;;;N;;;;; +FC91;ARABIC LIGATURE YEH WITH REH FINAL FORM;Lo;0;AL; 064A 0631;;;;N;;;;; +FC92;ARABIC LIGATURE YEH WITH ZAIN FINAL FORM;Lo;0;AL; 064A 0632;;;;N;;;;; +FC93;ARABIC LIGATURE YEH WITH MEEM FINAL FORM;Lo;0;AL; 064A 0645;;;;N;;;;; +FC94;ARABIC LIGATURE YEH WITH NOON FINAL FORM;Lo;0;AL; 064A 0646;;;;N;;;;; +FC95;ARABIC LIGATURE YEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 064A 0649;;;;N;;;;; +FC96;ARABIC LIGATURE YEH WITH YEH FINAL FORM;Lo;0;AL; 064A 064A;;;;N;;;;; +FC97;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM INITIAL FORM;Lo;0;AL; 0626 062C;;;;N;;;;; +FC98;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH INITIAL FORM;Lo;0;AL; 0626 062D;;;;N;;;;; +FC99;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH KHAH INITIAL FORM;Lo;0;AL; 0626 062E;;;;N;;;;; +FC9A;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM INITIAL FORM;Lo;0;AL; 0626 0645;;;;N;;;;; +FC9B;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH INITIAL FORM;Lo;0;AL; 0626 0647;;;;N;;;;; +FC9C;ARABIC LIGATURE BEH WITH JEEM INITIAL FORM;Lo;0;AL; 0628 062C;;;;N;;;;; +FC9D;ARABIC LIGATURE BEH WITH HAH INITIAL FORM;Lo;0;AL; 0628 062D;;;;N;;;;; +FC9E;ARABIC LIGATURE BEH WITH KHAH INITIAL FORM;Lo;0;AL; 0628 062E;;;;N;;;;; +FC9F;ARABIC LIGATURE BEH WITH MEEM INITIAL FORM;Lo;0;AL; 0628 0645;;;;N;;;;; +FCA0;ARABIC LIGATURE BEH WITH HEH INITIAL FORM;Lo;0;AL; 0628 0647;;;;N;;;;; +FCA1;ARABIC LIGATURE TEH WITH JEEM INITIAL FORM;Lo;0;AL; 062A 062C;;;;N;;;;; +FCA2;ARABIC LIGATURE TEH WITH HAH INITIAL FORM;Lo;0;AL; 062A 062D;;;;N;;;;; +FCA3;ARABIC LIGATURE TEH WITH KHAH INITIAL FORM;Lo;0;AL; 062A 062E;;;;N;;;;; +FCA4;ARABIC LIGATURE TEH WITH MEEM INITIAL FORM;Lo;0;AL; 062A 0645;;;;N;;;;; +FCA5;ARABIC LIGATURE TEH WITH HEH INITIAL FORM;Lo;0;AL; 062A 0647;;;;N;;;;; +FCA6;ARABIC LIGATURE THEH WITH MEEM INITIAL FORM;Lo;0;AL; 062B 0645;;;;N;;;;; +FCA7;ARABIC LIGATURE JEEM WITH HAH INITIAL FORM;Lo;0;AL; 062C 062D;;;;N;;;;; +FCA8;ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 062C 0645;;;;N;;;;; +FCA9;ARABIC LIGATURE HAH WITH JEEM INITIAL FORM;Lo;0;AL; 062D 062C;;;;N;;;;; +FCAA;ARABIC LIGATURE HAH WITH MEEM INITIAL FORM;Lo;0;AL; 062D 0645;;;;N;;;;; +FCAB;ARABIC LIGATURE KHAH WITH JEEM INITIAL FORM;Lo;0;AL; 062E 062C;;;;N;;;;; +FCAC;ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 062E 0645;;;;N;;;;; +FCAD;ARABIC LIGATURE SEEN WITH JEEM INITIAL FORM;Lo;0;AL; 0633 062C;;;;N;;;;; +FCAE;ARABIC LIGATURE SEEN WITH HAH INITIAL FORM;Lo;0;AL; 0633 062D;;;;N;;;;; +FCAF;ARABIC LIGATURE SEEN WITH KHAH INITIAL FORM;Lo;0;AL; 0633 062E;;;;N;;;;; +FCB0;ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM;Lo;0;AL; 0633 0645;;;;N;;;;; +FCB1;ARABIC LIGATURE SAD WITH HAH INITIAL FORM;Lo;0;AL; 0635 062D;;;;N;;;;; +FCB2;ARABIC LIGATURE SAD WITH KHAH INITIAL FORM;Lo;0;AL; 0635 062E;;;;N;;;;; +FCB3;ARABIC LIGATURE SAD WITH MEEM INITIAL FORM;Lo;0;AL; 0635 0645;;;;N;;;;; +FCB4;ARABIC LIGATURE DAD WITH JEEM INITIAL FORM;Lo;0;AL; 0636 062C;;;;N;;;;; +FCB5;ARABIC LIGATURE DAD WITH HAH INITIAL FORM;Lo;0;AL; 0636 062D;;;;N;;;;; +FCB6;ARABIC LIGATURE DAD WITH KHAH INITIAL FORM;Lo;0;AL; 0636 062E;;;;N;;;;; +FCB7;ARABIC LIGATURE DAD WITH MEEM INITIAL FORM;Lo;0;AL; 0636 0645;;;;N;;;;; +FCB8;ARABIC LIGATURE TAH WITH HAH INITIAL FORM;Lo;0;AL; 0637 062D;;;;N;;;;; +FCB9;ARABIC LIGATURE ZAH WITH MEEM INITIAL FORM;Lo;0;AL; 0638 0645;;;;N;;;;; +FCBA;ARABIC LIGATURE AIN WITH JEEM INITIAL FORM;Lo;0;AL; 0639 062C;;;;N;;;;; +FCBB;ARABIC LIGATURE AIN WITH MEEM INITIAL FORM;Lo;0;AL; 0639 0645;;;;N;;;;; +FCBC;ARABIC LIGATURE GHAIN WITH JEEM INITIAL FORM;Lo;0;AL; 063A 062C;;;;N;;;;; +FCBD;ARABIC LIGATURE GHAIN WITH MEEM INITIAL FORM;Lo;0;AL; 063A 0645;;;;N;;;;; +FCBE;ARABIC LIGATURE FEH WITH JEEM INITIAL FORM;Lo;0;AL; 0641 062C;;;;N;;;;; +FCBF;ARABIC LIGATURE FEH WITH HAH INITIAL FORM;Lo;0;AL; 0641 062D;;;;N;;;;; +FCC0;ARABIC LIGATURE FEH WITH KHAH INITIAL FORM;Lo;0;AL; 0641 062E;;;;N;;;;; +FCC1;ARABIC LIGATURE FEH WITH MEEM INITIAL FORM;Lo;0;AL; 0641 0645;;;;N;;;;; +FCC2;ARABIC LIGATURE QAF WITH HAH INITIAL FORM;Lo;0;AL; 0642 062D;;;;N;;;;; +FCC3;ARABIC LIGATURE QAF WITH MEEM INITIAL FORM;Lo;0;AL; 0642 0645;;;;N;;;;; +FCC4;ARABIC LIGATURE KAF WITH JEEM INITIAL FORM;Lo;0;AL; 0643 062C;;;;N;;;;; +FCC5;ARABIC LIGATURE KAF WITH HAH INITIAL FORM;Lo;0;AL; 0643 062D;;;;N;;;;; +FCC6;ARABIC LIGATURE KAF WITH KHAH INITIAL FORM;Lo;0;AL; 0643 062E;;;;N;;;;; +FCC7;ARABIC LIGATURE KAF WITH LAM INITIAL FORM;Lo;0;AL; 0643 0644;;;;N;;;;; +FCC8;ARABIC LIGATURE KAF WITH MEEM INITIAL FORM;Lo;0;AL; 0643 0645;;;;N;;;;; +FCC9;ARABIC LIGATURE LAM WITH JEEM INITIAL FORM;Lo;0;AL; 0644 062C;;;;N;;;;; +FCCA;ARABIC LIGATURE LAM WITH HAH INITIAL FORM;Lo;0;AL; 0644 062D;;;;N;;;;; +FCCB;ARABIC LIGATURE LAM WITH KHAH INITIAL FORM;Lo;0;AL; 0644 062E;;;;N;;;;; +FCCC;ARABIC LIGATURE LAM WITH MEEM INITIAL FORM;Lo;0;AL; 0644 0645;;;;N;;;;; +FCCD;ARABIC LIGATURE LAM WITH HEH INITIAL FORM;Lo;0;AL; 0644 0647;;;;N;;;;; +FCCE;ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM;Lo;0;AL; 0645 062C;;;;N;;;;; +FCCF;ARABIC LIGATURE MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0645 062D;;;;N;;;;; +FCD0;ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM;Lo;0;AL; 0645 062E;;;;N;;;;; +FCD1;ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0645 0645;;;;N;;;;; +FCD2;ARABIC LIGATURE NOON WITH JEEM INITIAL FORM;Lo;0;AL; 0646 062C;;;;N;;;;; +FCD3;ARABIC LIGATURE NOON WITH HAH INITIAL FORM;Lo;0;AL; 0646 062D;;;;N;;;;; +FCD4;ARABIC LIGATURE NOON WITH KHAH INITIAL FORM;Lo;0;AL; 0646 062E;;;;N;;;;; +FCD5;ARABIC LIGATURE NOON WITH MEEM INITIAL FORM;Lo;0;AL; 0646 0645;;;;N;;;;; +FCD6;ARABIC LIGATURE NOON WITH HEH INITIAL FORM;Lo;0;AL; 0646 0647;;;;N;;;;; +FCD7;ARABIC LIGATURE HEH WITH JEEM INITIAL FORM;Lo;0;AL; 0647 062C;;;;N;;;;; +FCD8;ARABIC LIGATURE HEH WITH MEEM INITIAL FORM;Lo;0;AL; 0647 0645;;;;N;;;;; +FCD9;ARABIC LIGATURE HEH WITH SUPERSCRIPT ALEF INITIAL FORM;Lo;0;AL; 0647 0670;;;;N;;;;; +FCDA;ARABIC LIGATURE YEH WITH JEEM INITIAL FORM;Lo;0;AL; 064A 062C;;;;N;;;;; +FCDB;ARABIC LIGATURE YEH WITH HAH INITIAL FORM;Lo;0;AL; 064A 062D;;;;N;;;;; +FCDC;ARABIC LIGATURE YEH WITH KHAH INITIAL FORM;Lo;0;AL; 064A 062E;;;;N;;;;; +FCDD;ARABIC LIGATURE YEH WITH MEEM INITIAL FORM;Lo;0;AL; 064A 0645;;;;N;;;;; +FCDE;ARABIC LIGATURE YEH WITH HEH INITIAL FORM;Lo;0;AL; 064A 0647;;;;N;;;;; +FCDF;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM MEDIAL FORM;Lo;0;AL; 0626 0645;;;;N;;;;; +FCE0;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH MEDIAL FORM;Lo;0;AL; 0626 0647;;;;N;;;;; +FCE1;ARABIC LIGATURE BEH WITH MEEM MEDIAL FORM;Lo;0;AL; 0628 0645;;;;N;;;;; +FCE2;ARABIC LIGATURE BEH WITH HEH MEDIAL FORM;Lo;0;AL; 0628 0647;;;;N;;;;; +FCE3;ARABIC LIGATURE TEH WITH MEEM MEDIAL FORM;Lo;0;AL; 062A 0645;;;;N;;;;; +FCE4;ARABIC LIGATURE TEH WITH HEH MEDIAL FORM;Lo;0;AL; 062A 0647;;;;N;;;;; +FCE5;ARABIC LIGATURE THEH WITH MEEM MEDIAL FORM;Lo;0;AL; 062B 0645;;;;N;;;;; +FCE6;ARABIC LIGATURE THEH WITH HEH MEDIAL FORM;Lo;0;AL; 062B 0647;;;;N;;;;; +FCE7;ARABIC LIGATURE SEEN WITH MEEM MEDIAL FORM;Lo;0;AL; 0633 0645;;;;N;;;;; +FCE8;ARABIC LIGATURE SEEN WITH HEH MEDIAL FORM;Lo;0;AL; 0633 0647;;;;N;;;;; +FCE9;ARABIC LIGATURE SHEEN WITH MEEM MEDIAL FORM;Lo;0;AL; 0634 0645;;;;N;;;;; +FCEA;ARABIC LIGATURE SHEEN WITH HEH MEDIAL FORM;Lo;0;AL; 0634 0647;;;;N;;;;; +FCEB;ARABIC LIGATURE KAF WITH LAM MEDIAL FORM;Lo;0;AL; 0643 0644;;;;N;;;;; +FCEC;ARABIC LIGATURE KAF WITH MEEM MEDIAL FORM;Lo;0;AL; 0643 0645;;;;N;;;;; +FCED;ARABIC LIGATURE LAM WITH MEEM MEDIAL FORM;Lo;0;AL; 0644 0645;;;;N;;;;; +FCEE;ARABIC LIGATURE NOON WITH MEEM MEDIAL FORM;Lo;0;AL; 0646 0645;;;;N;;;;; +FCEF;ARABIC LIGATURE NOON WITH HEH MEDIAL FORM;Lo;0;AL; 0646 0647;;;;N;;;;; +FCF0;ARABIC LIGATURE YEH WITH MEEM MEDIAL FORM;Lo;0;AL; 064A 0645;;;;N;;;;; +FCF1;ARABIC LIGATURE YEH WITH HEH MEDIAL FORM;Lo;0;AL; 064A 0647;;;;N;;;;; +FCF2;ARABIC LIGATURE SHADDA WITH FATHA MEDIAL FORM;Lo;0;AL; 0640 064E 0651;;;;N;;;;; +FCF3;ARABIC LIGATURE SHADDA WITH DAMMA MEDIAL FORM;Lo;0;AL; 0640 064F 0651;;;;N;;;;; +FCF4;ARABIC LIGATURE SHADDA WITH KASRA MEDIAL FORM;Lo;0;AL; 0640 0650 0651;;;;N;;;;; +FCF5;ARABIC LIGATURE TAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0637 0649;;;;N;;;;; +FCF6;ARABIC LIGATURE TAH WITH YEH ISOLATED FORM;Lo;0;AL; 0637 064A;;;;N;;;;; +FCF7;ARABIC LIGATURE AIN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0639 0649;;;;N;;;;; +FCF8;ARABIC LIGATURE AIN WITH YEH ISOLATED FORM;Lo;0;AL; 0639 064A;;;;N;;;;; +FCF9;ARABIC LIGATURE GHAIN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 063A 0649;;;;N;;;;; +FCFA;ARABIC LIGATURE GHAIN WITH YEH ISOLATED FORM;Lo;0;AL; 063A 064A;;;;N;;;;; +FCFB;ARABIC LIGATURE SEEN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0633 0649;;;;N;;;;; +FCFC;ARABIC LIGATURE SEEN WITH YEH ISOLATED FORM;Lo;0;AL; 0633 064A;;;;N;;;;; +FCFD;ARABIC LIGATURE SHEEN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0634 0649;;;;N;;;;; +FCFE;ARABIC LIGATURE SHEEN WITH YEH ISOLATED FORM;Lo;0;AL; 0634 064A;;;;N;;;;; +FCFF;ARABIC LIGATURE HAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062D 0649;;;;N;;;;; +FD00;ARABIC LIGATURE HAH WITH YEH ISOLATED FORM;Lo;0;AL; 062D 064A;;;;N;;;;; +FD01;ARABIC LIGATURE JEEM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062C 0649;;;;N;;;;; +FD02;ARABIC LIGATURE JEEM WITH YEH ISOLATED FORM;Lo;0;AL; 062C 064A;;;;N;;;;; +FD03;ARABIC LIGATURE KHAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062E 0649;;;;N;;;;; +FD04;ARABIC LIGATURE KHAH WITH YEH ISOLATED FORM;Lo;0;AL; 062E 064A;;;;N;;;;; +FD05;ARABIC LIGATURE SAD WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0635 0649;;;;N;;;;; +FD06;ARABIC LIGATURE SAD WITH YEH ISOLATED FORM;Lo;0;AL; 0635 064A;;;;N;;;;; +FD07;ARABIC LIGATURE DAD WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0636 0649;;;;N;;;;; +FD08;ARABIC LIGATURE DAD WITH YEH ISOLATED FORM;Lo;0;AL; 0636 064A;;;;N;;;;; +FD09;ARABIC LIGATURE SHEEN WITH JEEM ISOLATED FORM;Lo;0;AL; 0634 062C;;;;N;;;;; +FD0A;ARABIC LIGATURE SHEEN WITH HAH ISOLATED FORM;Lo;0;AL; 0634 062D;;;;N;;;;; +FD0B;ARABIC LIGATURE SHEEN WITH KHAH ISOLATED FORM;Lo;0;AL; 0634 062E;;;;N;;;;; +FD0C;ARABIC LIGATURE SHEEN WITH MEEM ISOLATED FORM;Lo;0;AL; 0634 0645;;;;N;;;;; +FD0D;ARABIC LIGATURE SHEEN WITH REH ISOLATED FORM;Lo;0;AL; 0634 0631;;;;N;;;;; +FD0E;ARABIC LIGATURE SEEN WITH REH ISOLATED FORM;Lo;0;AL; 0633 0631;;;;N;;;;; +FD0F;ARABIC LIGATURE SAD WITH REH ISOLATED FORM;Lo;0;AL; 0635 0631;;;;N;;;;; +FD10;ARABIC LIGATURE DAD WITH REH ISOLATED FORM;Lo;0;AL; 0636 0631;;;;N;;;;; +FD11;ARABIC LIGATURE TAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0637 0649;;;;N;;;;; +FD12;ARABIC LIGATURE TAH WITH YEH FINAL FORM;Lo;0;AL; 0637 064A;;;;N;;;;; +FD13;ARABIC LIGATURE AIN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0639 0649;;;;N;;;;; +FD14;ARABIC LIGATURE AIN WITH YEH FINAL FORM;Lo;0;AL; 0639 064A;;;;N;;;;; +FD15;ARABIC LIGATURE GHAIN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 063A 0649;;;;N;;;;; +FD16;ARABIC LIGATURE GHAIN WITH YEH FINAL FORM;Lo;0;AL; 063A 064A;;;;N;;;;; +FD17;ARABIC LIGATURE SEEN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0633 0649;;;;N;;;;; +FD18;ARABIC LIGATURE SEEN WITH YEH FINAL FORM;Lo;0;AL; 0633 064A;;;;N;;;;; +FD19;ARABIC LIGATURE SHEEN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0634 0649;;;;N;;;;; +FD1A;ARABIC LIGATURE SHEEN WITH YEH FINAL FORM;Lo;0;AL; 0634 064A;;;;N;;;;; +FD1B;ARABIC LIGATURE HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062D 0649;;;;N;;;;; +FD1C;ARABIC LIGATURE HAH WITH YEH FINAL FORM;Lo;0;AL; 062D 064A;;;;N;;;;; +FD1D;ARABIC LIGATURE JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062C 0649;;;;N;;;;; +FD1E;ARABIC LIGATURE JEEM WITH YEH FINAL FORM;Lo;0;AL; 062C 064A;;;;N;;;;; +FD1F;ARABIC LIGATURE KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062E 0649;;;;N;;;;; +FD20;ARABIC LIGATURE KHAH WITH YEH FINAL FORM;Lo;0;AL; 062E 064A;;;;N;;;;; +FD21;ARABIC LIGATURE SAD WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0635 0649;;;;N;;;;; +FD22;ARABIC LIGATURE SAD WITH YEH FINAL FORM;Lo;0;AL; 0635 064A;;;;N;;;;; +FD23;ARABIC LIGATURE DAD WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0636 0649;;;;N;;;;; +FD24;ARABIC LIGATURE DAD WITH YEH FINAL FORM;Lo;0;AL; 0636 064A;;;;N;;;;; +FD25;ARABIC LIGATURE SHEEN WITH JEEM FINAL FORM;Lo;0;AL; 0634 062C;;;;N;;;;; +FD26;ARABIC LIGATURE SHEEN WITH HAH FINAL FORM;Lo;0;AL; 0634 062D;;;;N;;;;; +FD27;ARABIC LIGATURE SHEEN WITH KHAH FINAL FORM;Lo;0;AL; 0634 062E;;;;N;;;;; +FD28;ARABIC LIGATURE SHEEN WITH MEEM FINAL FORM;Lo;0;AL; 0634 0645;;;;N;;;;; +FD29;ARABIC LIGATURE SHEEN WITH REH FINAL FORM;Lo;0;AL; 0634 0631;;;;N;;;;; +FD2A;ARABIC LIGATURE SEEN WITH REH FINAL FORM;Lo;0;AL; 0633 0631;;;;N;;;;; +FD2B;ARABIC LIGATURE SAD WITH REH FINAL FORM;Lo;0;AL; 0635 0631;;;;N;;;;; +FD2C;ARABIC LIGATURE DAD WITH REH FINAL FORM;Lo;0;AL; 0636 0631;;;;N;;;;; +FD2D;ARABIC LIGATURE SHEEN WITH JEEM INITIAL FORM;Lo;0;AL; 0634 062C;;;;N;;;;; +FD2E;ARABIC LIGATURE SHEEN WITH HAH INITIAL FORM;Lo;0;AL; 0634 062D;;;;N;;;;; +FD2F;ARABIC LIGATURE SHEEN WITH KHAH INITIAL FORM;Lo;0;AL; 0634 062E;;;;N;;;;; +FD30;ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM;Lo;0;AL; 0634 0645;;;;N;;;;; +FD31;ARABIC LIGATURE SEEN WITH HEH INITIAL FORM;Lo;0;AL; 0633 0647;;;;N;;;;; +FD32;ARABIC LIGATURE SHEEN WITH HEH INITIAL FORM;Lo;0;AL; 0634 0647;;;;N;;;;; +FD33;ARABIC LIGATURE TAH WITH MEEM INITIAL FORM;Lo;0;AL; 0637 0645;;;;N;;;;; +FD34;ARABIC LIGATURE SEEN WITH JEEM MEDIAL FORM;Lo;0;AL; 0633 062C;;;;N;;;;; +FD35;ARABIC LIGATURE SEEN WITH HAH MEDIAL FORM;Lo;0;AL; 0633 062D;;;;N;;;;; +FD36;ARABIC LIGATURE SEEN WITH KHAH MEDIAL FORM;Lo;0;AL; 0633 062E;;;;N;;;;; +FD37;ARABIC LIGATURE SHEEN WITH JEEM MEDIAL FORM;Lo;0;AL; 0634 062C;;;;N;;;;; +FD38;ARABIC LIGATURE SHEEN WITH HAH MEDIAL FORM;Lo;0;AL; 0634 062D;;;;N;;;;; +FD39;ARABIC LIGATURE SHEEN WITH KHAH MEDIAL FORM;Lo;0;AL; 0634 062E;;;;N;;;;; +FD3A;ARABIC LIGATURE TAH WITH MEEM MEDIAL FORM;Lo;0;AL; 0637 0645;;;;N;;;;; +FD3B;ARABIC LIGATURE ZAH WITH MEEM MEDIAL FORM;Lo;0;AL; 0638 0645;;;;N;;;;; +FD3C;ARABIC LIGATURE ALEF WITH FATHATAN FINAL FORM;Lo;0;AL; 0627 064B;;;;N;;;;; +FD3D;ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM;Lo;0;AL; 0627 064B;;;;N;;;;; +FD3E;ORNATE LEFT PARENTHESIS;Ps;0;ON;;;;;N;;;;; +FD3F;ORNATE RIGHT PARENTHESIS;Pe;0;ON;;;;;N;;;;; +FD50;ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 062A 062C 0645;;;;N;;;;; +FD51;ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM;Lo;0;AL; 062A 062D 062C;;;;N;;;;; +FD52;ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL; 062A 062D 062C;;;;N;;;;; +FD53;ARABIC LIGATURE TEH WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 062A 062D 0645;;;;N;;;;; +FD54;ARABIC LIGATURE TEH WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 062A 062E 0645;;;;N;;;;; +FD55;ARABIC LIGATURE TEH WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL; 062A 0645 062C;;;;N;;;;; +FD56;ARABIC LIGATURE TEH WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 062A 0645 062D;;;;N;;;;; +FD57;ARABIC LIGATURE TEH WITH MEEM WITH KHAH INITIAL FORM;Lo;0;AL; 062A 0645 062E;;;;N;;;;; +FD58;ARABIC LIGATURE JEEM WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 062C 0645 062D;;;;N;;;;; +FD59;ARABIC LIGATURE JEEM WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 062C 0645 062D;;;;N;;;;; +FD5A;ARABIC LIGATURE HAH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 062D 0645 064A;;;;N;;;;; +FD5B;ARABIC LIGATURE HAH WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062D 0645 0649;;;;N;;;;; +FD5C;ARABIC LIGATURE SEEN WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL; 0633 062D 062C;;;;N;;;;; +FD5D;ARABIC LIGATURE SEEN WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL; 0633 062C 062D;;;;N;;;;; +FD5E;ARABIC LIGATURE SEEN WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0633 062C 0649;;;;N;;;;; +FD5F;ARABIC LIGATURE SEEN WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 0633 0645 062D;;;;N;;;;; +FD60;ARABIC LIGATURE SEEN WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0633 0645 062D;;;;N;;;;; +FD61;ARABIC LIGATURE SEEN WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL; 0633 0645 062C;;;;N;;;;; +FD62;ARABIC LIGATURE SEEN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0633 0645 0645;;;;N;;;;; +FD63;ARABIC LIGATURE SEEN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0633 0645 0645;;;;N;;;;; +FD64;ARABIC LIGATURE SAD WITH HAH WITH HAH FINAL FORM;Lo;0;AL; 0635 062D 062D;;;;N;;;;; +FD65;ARABIC LIGATURE SAD WITH HAH WITH HAH INITIAL FORM;Lo;0;AL; 0635 062D 062D;;;;N;;;;; +FD66;ARABIC LIGATURE SAD WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0635 0645 0645;;;;N;;;;; +FD67;ARABIC LIGATURE SHEEN WITH HAH WITH MEEM FINAL FORM;Lo;0;AL; 0634 062D 0645;;;;N;;;;; +FD68;ARABIC LIGATURE SHEEN WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 0634 062D 0645;;;;N;;;;; +FD69;ARABIC LIGATURE SHEEN WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 0634 062C 064A;;;;N;;;;; +FD6A;ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH FINAL FORM;Lo;0;AL; 0634 0645 062E;;;;N;;;;; +FD6B;ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH INITIAL FORM;Lo;0;AL; 0634 0645 062E;;;;N;;;;; +FD6C;ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0634 0645 0645;;;;N;;;;; +FD6D;ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0634 0645 0645;;;;N;;;;; +FD6E;ARABIC LIGATURE DAD WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0636 062D 0649;;;;N;;;;; +FD6F;ARABIC LIGATURE DAD WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL; 0636 062E 0645;;;;N;;;;; +FD70;ARABIC LIGATURE DAD WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 0636 062E 0645;;;;N;;;;; +FD71;ARABIC LIGATURE TAH WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 0637 0645 062D;;;;N;;;;; +FD72;ARABIC LIGATURE TAH WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0637 0645 062D;;;;N;;;;; +FD73;ARABIC LIGATURE TAH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0637 0645 0645;;;;N;;;;; +FD74;ARABIC LIGATURE TAH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0637 0645 064A;;;;N;;;;; +FD75;ARABIC LIGATURE AIN WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL; 0639 062C 0645;;;;N;;;;; +FD76;ARABIC LIGATURE AIN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0639 0645 0645;;;;N;;;;; +FD77;ARABIC LIGATURE AIN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0639 0645 0645;;;;N;;;;; +FD78;ARABIC LIGATURE AIN WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0639 0645 0649;;;;N;;;;; +FD79;ARABIC LIGATURE GHAIN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 063A 0645 0645;;;;N;;;;; +FD7A;ARABIC LIGATURE GHAIN WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 063A 0645 064A;;;;N;;;;; +FD7B;ARABIC LIGATURE GHAIN WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 063A 0645 0649;;;;N;;;;; +FD7C;ARABIC LIGATURE FEH WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL; 0641 062E 0645;;;;N;;;;; +FD7D;ARABIC LIGATURE FEH WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 0641 062E 0645;;;;N;;;;; +FD7E;ARABIC LIGATURE QAF WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 0642 0645 062D;;;;N;;;;; +FD7F;ARABIC LIGATURE QAF WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0642 0645 0645;;;;N;;;;; +FD80;ARABIC LIGATURE LAM WITH HAH WITH MEEM FINAL FORM;Lo;0;AL; 0644 062D 0645;;;;N;;;;; +FD81;ARABIC LIGATURE LAM WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0644 062D 064A;;;;N;;;;; +FD82;ARABIC LIGATURE LAM WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0644 062D 0649;;;;N;;;;; +FD83;ARABIC LIGATURE LAM WITH JEEM WITH JEEM INITIAL FORM;Lo;0;AL; 0644 062C 062C;;;;N;;;;; +FD84;ARABIC LIGATURE LAM WITH JEEM WITH JEEM FINAL FORM;Lo;0;AL; 0644 062C 062C;;;;N;;;;; +FD85;ARABIC LIGATURE LAM WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL; 0644 062E 0645;;;;N;;;;; +FD86;ARABIC LIGATURE LAM WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 0644 062E 0645;;;;N;;;;; +FD87;ARABIC LIGATURE LAM WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 0644 0645 062D;;;;N;;;;; +FD88;ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0644 0645 062D;;;;N;;;;; +FD89;ARABIC LIGATURE MEEM WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL; 0645 062D 062C;;;;N;;;;; +FD8A;ARABIC LIGATURE MEEM WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 0645 062D 0645;;;;N;;;;; +FD8B;ARABIC LIGATURE MEEM WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0645 062D 064A;;;;N;;;;; +FD8C;ARABIC LIGATURE MEEM WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL; 0645 062C 062D;;;;N;;;;; +FD8D;ARABIC LIGATURE MEEM WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0645 062C 0645;;;;N;;;;; +FD8E;ARABIC LIGATURE MEEM WITH KHAH WITH JEEM INITIAL FORM;Lo;0;AL; 0645 062E 062C;;;;N;;;;; +FD8F;ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 0645 062E 0645;;;;N;;;;; +FD92;ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM;Lo;0;AL; 0645 062C 062E;;;;N;;;;; +FD93;ARABIC LIGATURE HEH WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL; 0647 0645 062C;;;;N;;;;; +FD94;ARABIC LIGATURE HEH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0647 0645 0645;;;;N;;;;; +FD95;ARABIC LIGATURE NOON WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 0646 062D 0645;;;;N;;;;; +FD96;ARABIC LIGATURE NOON WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0646 062D 0649;;;;N;;;;; +FD97;ARABIC LIGATURE NOON WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL; 0646 062C 0645;;;;N;;;;; +FD98;ARABIC LIGATURE NOON WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0646 062C 0645;;;;N;;;;; +FD99;ARABIC LIGATURE NOON WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0646 062C 0649;;;;N;;;;; +FD9A;ARABIC LIGATURE NOON WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0646 0645 064A;;;;N;;;;; +FD9B;ARABIC LIGATURE NOON WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0646 0645 0649;;;;N;;;;; +FD9C;ARABIC LIGATURE YEH WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 064A 0645 0645;;;;N;;;;; +FD9D;ARABIC LIGATURE YEH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 064A 0645 0645;;;;N;;;;; +FD9E;ARABIC LIGATURE BEH WITH KHAH WITH YEH FINAL FORM;Lo;0;AL; 0628 062E 064A;;;;N;;;;; +FD9F;ARABIC LIGATURE TEH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 062A 062C 064A;;;;N;;;;; +FDA0;ARABIC LIGATURE TEH WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062A 062C 0649;;;;N;;;;; +FDA1;ARABIC LIGATURE TEH WITH KHAH WITH YEH FINAL FORM;Lo;0;AL; 062A 062E 064A;;;;N;;;;; +FDA2;ARABIC LIGATURE TEH WITH KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062A 062E 0649;;;;N;;;;; +FDA3;ARABIC LIGATURE TEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 062A 0645 064A;;;;N;;;;; +FDA4;ARABIC LIGATURE TEH WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062A 0645 0649;;;;N;;;;; +FDA5;ARABIC LIGATURE JEEM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 062C 0645 064A;;;;N;;;;; +FDA6;ARABIC LIGATURE JEEM WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062C 062D 0649;;;;N;;;;; +FDA7;ARABIC LIGATURE JEEM WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062C 0645 0649;;;;N;;;;; +FDA8;ARABIC LIGATURE SEEN WITH KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0633 062E 0649;;;;N;;;;; +FDA9;ARABIC LIGATURE SAD WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0635 062D 064A;;;;N;;;;; +FDAA;ARABIC LIGATURE SHEEN WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0634 062D 064A;;;;N;;;;; +FDAB;ARABIC LIGATURE DAD WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0636 062D 064A;;;;N;;;;; +FDAC;ARABIC LIGATURE LAM WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 0644 062C 064A;;;;N;;;;; +FDAD;ARABIC LIGATURE LAM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0644 0645 064A;;;;N;;;;; +FDAE;ARABIC LIGATURE YEH WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 064A 062D 064A;;;;N;;;;; +FDAF;ARABIC LIGATURE YEH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 064A 062C 064A;;;;N;;;;; +FDB0;ARABIC LIGATURE YEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 064A 0645 064A;;;;N;;;;; +FDB1;ARABIC LIGATURE MEEM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0645 0645 064A;;;;N;;;;; +FDB2;ARABIC LIGATURE QAF WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0642 0645 064A;;;;N;;;;; +FDB3;ARABIC LIGATURE NOON WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0646 062D 064A;;;;N;;;;; +FDB4;ARABIC LIGATURE QAF WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0642 0645 062D;;;;N;;;;; +FDB5;ARABIC LIGATURE LAM WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 0644 062D 0645;;;;N;;;;; +FDB6;ARABIC LIGATURE AIN WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0639 0645 064A;;;;N;;;;; +FDB7;ARABIC LIGATURE KAF WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0643 0645 064A;;;;N;;;;; +FDB8;ARABIC LIGATURE NOON WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL; 0646 062C 062D;;;;N;;;;; +FDB9;ARABIC LIGATURE MEEM WITH KHAH WITH YEH FINAL FORM;Lo;0;AL; 0645 062E 064A;;;;N;;;;; +FDBA;ARABIC LIGATURE LAM WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0644 062C 0645;;;;N;;;;; +FDBB;ARABIC LIGATURE KAF WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0643 0645 0645;;;;N;;;;; +FDBC;ARABIC LIGATURE LAM WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL; 0644 062C 0645;;;;N;;;;; +FDBD;ARABIC LIGATURE NOON WITH JEEM WITH HAH FINAL FORM;Lo;0;AL; 0646 062C 062D;;;;N;;;;; +FDBE;ARABIC LIGATURE JEEM WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 062C 062D 064A;;;;N;;;;; +FDBF;ARABIC LIGATURE HAH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 062D 062C 064A;;;;N;;;;; +FDC0;ARABIC LIGATURE MEEM WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 0645 062C 064A;;;;N;;;;; +FDC1;ARABIC LIGATURE FEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0641 0645 064A;;;;N;;;;; +FDC2;ARABIC LIGATURE BEH WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0628 062D 064A;;;;N;;;;; +FDC3;ARABIC LIGATURE KAF WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0643 0645 0645;;;;N;;;;; +FDC4;ARABIC LIGATURE AIN WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0639 062C 0645;;;;N;;;;; +FDC5;ARABIC LIGATURE SAD WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0635 0645 0645;;;;N;;;;; +FDC6;ARABIC LIGATURE SEEN WITH KHAH WITH YEH FINAL FORM;Lo;0;AL; 0633 062E 064A;;;;N;;;;; +FDC7;ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 0646 062C 064A;;;;N;;;;; +FDF0;ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL; 0635 0644 06D2;;;;N;;;;; +FDF1;ARABIC LIGATURE QALA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL; 0642 0644 06D2;;;;N;;;;; +FDF2;ARABIC LIGATURE ALLAH ISOLATED FORM;Lo;0;AL; 0627 0644 0644 0647;;;;N;;;;; +FDF3;ARABIC LIGATURE AKBAR ISOLATED FORM;Lo;0;AL; 0627 0643 0628 0631;;;;N;;;;; +FDF4;ARABIC LIGATURE MOHAMMAD ISOLATED FORM;Lo;0;AL; 0645 062D 0645 062F;;;;N;;;;; +FDF5;ARABIC LIGATURE SALAM ISOLATED FORM;Lo;0;AL; 0635 0644 0639 0645;;;;N;;;;; +FDF6;ARABIC LIGATURE RASOUL ISOLATED FORM;Lo;0;AL; 0631 0633 0648 0644;;;;N;;;;; +FDF7;ARABIC LIGATURE ALAYHE ISOLATED FORM;Lo;0;AL; 0639 0644 064A 0647;;;;N;;;;; +FDF8;ARABIC LIGATURE WASALLAM ISOLATED FORM;Lo;0;AL; 0648 0633 0644 0645;;;;N;;;;; +FDF9;ARABIC LIGATURE SALLA ISOLATED FORM;Lo;0;AL; 0635 0644 0649;;;;N;;;;; +FDFA;ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM;Lo;0;AL; 0635 0644 0649 0020 0627 0644 0644 0647 0020 0639 0644 064A 0647 0020 0648 0633 0644 0645;;;;N;ARABIC LETTER SALLALLAHOU ALAYHE WASALLAM;;;; +FDFB;ARABIC LIGATURE JALLAJALALOUHOU;Lo;0;AL; 062C 0644 0020 062C 0644 0627 0644 0647;;;;N;ARABIC LETTER JALLAJALALOUHOU;;;; +FDFC;RIAL SIGN;Sc;0;AL; 0631 06CC 0627 0644;;;;N;;;;; +FE00;VARIATION SELECTOR-1;Mn;0;NSM;;;;;N;;;;; +FE01;VARIATION SELECTOR-2;Mn;0;NSM;;;;;N;;;;; +FE02;VARIATION SELECTOR-3;Mn;0;NSM;;;;;N;;;;; +FE03;VARIATION SELECTOR-4;Mn;0;NSM;;;;;N;;;;; +FE04;VARIATION SELECTOR-5;Mn;0;NSM;;;;;N;;;;; +FE05;VARIATION SELECTOR-6;Mn;0;NSM;;;;;N;;;;; +FE06;VARIATION SELECTOR-7;Mn;0;NSM;;;;;N;;;;; +FE07;VARIATION SELECTOR-8;Mn;0;NSM;;;;;N;;;;; +FE08;VARIATION SELECTOR-9;Mn;0;NSM;;;;;N;;;;; +FE09;VARIATION SELECTOR-10;Mn;0;NSM;;;;;N;;;;; +FE0A;VARIATION SELECTOR-11;Mn;0;NSM;;;;;N;;;;; +FE0B;VARIATION SELECTOR-12;Mn;0;NSM;;;;;N;;;;; +FE0C;VARIATION SELECTOR-13;Mn;0;NSM;;;;;N;;;;; +FE0D;VARIATION SELECTOR-14;Mn;0;NSM;;;;;N;;;;; +FE0E;VARIATION SELECTOR-15;Mn;0;NSM;;;;;N;;;;; +FE0F;VARIATION SELECTOR-16;Mn;0;NSM;;;;;N;;;;; +FE20;COMBINING LIGATURE LEFT HALF;Mn;230;NSM;;;;;N;;;;; +FE21;COMBINING LIGATURE RIGHT HALF;Mn;230;NSM;;;;;N;;;;; +FE22;COMBINING DOUBLE TILDE LEFT HALF;Mn;230;NSM;;;;;N;;;;; +FE23;COMBINING DOUBLE TILDE RIGHT HALF;Mn;230;NSM;;;;;N;;;;; +FE30;PRESENTATION FORM FOR VERTICAL TWO DOT LEADER;Po;0;ON; 2025;;;;N;GLYPH FOR VERTICAL TWO DOT LEADER;;;; +FE31;PRESENTATION FORM FOR VERTICAL EM DASH;Pd;0;ON; 2014;;;;N;GLYPH FOR VERTICAL EM DASH;;;; +FE32;PRESENTATION FORM FOR VERTICAL EN DASH;Pd;0;ON; 2013;;;;N;GLYPH FOR VERTICAL EN DASH;;;; +FE33;PRESENTATION FORM FOR VERTICAL LOW LINE;Pc;0;ON; 005F;;;;N;GLYPH FOR VERTICAL SPACING UNDERSCORE;;;; +FE34;PRESENTATION FORM FOR VERTICAL WAVY LOW LINE;Pc;0;ON; 005F;;;;N;GLYPH FOR VERTICAL SPACING WAVY UNDERSCORE;;;; +FE35;PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS;Ps;0;ON; 0028;;;;N;GLYPH FOR VERTICAL OPENING PARENTHESIS;;;; +FE36;PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;N;GLYPH FOR VERTICAL CLOSING PARENTHESIS;;;; +FE37;PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET;Ps;0;ON; 007B;;;;N;GLYPH FOR VERTICAL OPENING CURLY BRACKET;;;; +FE38;PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET;Pe;0;ON; 007D;;;;N;GLYPH FOR VERTICAL CLOSING CURLY BRACKET;;;; +FE39;PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET;Ps;0;ON; 3014;;;;N;GLYPH FOR VERTICAL OPENING TORTOISE SHELL BRACKET;;;; +FE3A;PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET;Pe;0;ON; 3015;;;;N;GLYPH FOR VERTICAL CLOSING TORTOISE SHELL BRACKET;;;; +FE3B;PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET;Ps;0;ON; 3010;;;;N;GLYPH FOR VERTICAL OPENING BLACK LENTICULAR BRACKET;;;; +FE3C;PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET;Pe;0;ON; 3011;;;;N;GLYPH FOR VERTICAL CLOSING BLACK LENTICULAR BRACKET;;;; +FE3D;PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET;Ps;0;ON; 300A;;;;N;GLYPH FOR VERTICAL OPENING DOUBLE ANGLE BRACKET;;;; +FE3E;PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON; 300B;;;;N;GLYPH FOR VERTICAL CLOSING DOUBLE ANGLE BRACKET;;;; +FE3F;PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET;Ps;0;ON; 3008;;;;N;GLYPH FOR VERTICAL OPENING ANGLE BRACKET;;;; +FE40;PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET;Pe;0;ON; 3009;;;;N;GLYPH FOR VERTICAL CLOSING ANGLE BRACKET;;;; +FE41;PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET;Ps;0;ON; 300C;;;;N;GLYPH FOR VERTICAL OPENING CORNER BRACKET;;;; +FE42;PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET;Pe;0;ON; 300D;;;;N;GLYPH FOR VERTICAL CLOSING CORNER BRACKET;;;; +FE43;PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET;Ps;0;ON; 300E;;;;N;GLYPH FOR VERTICAL OPENING WHITE CORNER BRACKET;;;; +FE44;PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET;Pe;0;ON; 300F;;;;N;GLYPH FOR VERTICAL CLOSING WHITE CORNER BRACKET;;;; +FE45;SESAME DOT;Po;0;ON;;;;;N;;;;; +FE46;WHITE SESAME DOT;Po;0;ON;;;;;N;;;;; +FE49;DASHED OVERLINE;Po;0;ON; 203E;;;;N;SPACING DASHED OVERSCORE;;;; +FE4A;CENTRELINE OVERLINE;Po;0;ON; 203E;;;;N;SPACING CENTERLINE OVERSCORE;;;; +FE4B;WAVY OVERLINE;Po;0;ON; 203E;;;;N;SPACING WAVY OVERSCORE;;;; +FE4C;DOUBLE WAVY OVERLINE;Po;0;ON; 203E;;;;N;SPACING DOUBLE WAVY OVERSCORE;;;; +FE4D;DASHED LOW LINE;Pc;0;ON; 005F;;;;N;SPACING DASHED UNDERSCORE;;;; +FE4E;CENTRELINE LOW LINE;Pc;0;ON; 005F;;;;N;SPACING CENTERLINE UNDERSCORE;;;; +FE4F;WAVY LOW LINE;Pc;0;ON; 005F;;;;N;SPACING WAVY UNDERSCORE;;;; +FE50;SMALL COMMA;Po;0;CS; 002C;;;;N;;;;; +FE51;SMALL IDEOGRAPHIC COMMA;Po;0;ON; 3001;;;;N;;;;; +FE52;SMALL FULL STOP;Po;0;CS; 002E;;;;N;SMALL PERIOD;;;; +FE54;SMALL SEMICOLON;Po;0;ON; 003B;;;;N;;;;; +FE55;SMALL COLON;Po;0;CS; 003A;;;;N;;;;; +FE56;SMALL QUESTION MARK;Po;0;ON; 003F;;;;N;;;;; +FE57;SMALL EXCLAMATION MARK;Po;0;ON; 0021;;;;N;;;;; +FE58;SMALL EM DASH;Pd;0;ON; 2014;;;;N;;;;; +FE59;SMALL LEFT PARENTHESIS;Ps;0;ON; 0028;;;;N;SMALL OPENING PARENTHESIS;;;; +FE5A;SMALL RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;N;SMALL CLOSING PARENTHESIS;;;; +FE5B;SMALL LEFT CURLY BRACKET;Ps;0;ON; 007B;;;;N;SMALL OPENING CURLY BRACKET;;;; +FE5C;SMALL RIGHT CURLY BRACKET;Pe;0;ON; 007D;;;;N;SMALL CLOSING CURLY BRACKET;;;; +FE5D;SMALL LEFT TORTOISE SHELL BRACKET;Ps;0;ON; 3014;;;;N;SMALL OPENING TORTOISE SHELL BRACKET;;;; +FE5E;SMALL RIGHT TORTOISE SHELL BRACKET;Pe;0;ON; 3015;;;;N;SMALL CLOSING TORTOISE SHELL BRACKET;;;; +FE5F;SMALL NUMBER SIGN;Po;0;ET; 0023;;;;N;;;;; +FE60;SMALL AMPERSAND;Po;0;ON; 0026;;;;N;;;;; +FE61;SMALL ASTERISK;Po;0;ON; 002A;;;;N;;;;; +FE62;SMALL PLUS SIGN;Sm;0;ET; 002B;;;;N;;;;; +FE63;SMALL HYPHEN-MINUS;Pd;0;ET; 002D;;;;N;;;;; +FE64;SMALL LESS-THAN SIGN;Sm;0;ON; 003C;;;;N;;;;; +FE65;SMALL GREATER-THAN SIGN;Sm;0;ON; 003E;;;;N;;;;; +FE66;SMALL EQUALS SIGN;Sm;0;ON; 003D;;;;N;;;;; +FE68;SMALL REVERSE SOLIDUS;Po;0;ON; 005C;;;;N;SMALL BACKSLASH;;;; +FE69;SMALL DOLLAR SIGN;Sc;0;ET; 0024;;;;N;;;;; +FE6A;SMALL PERCENT SIGN;Po;0;ET; 0025;;;;N;;;;; +FE6B;SMALL COMMERCIAL AT;Po;0;ON; 0040;;;;N;;;;; +FE70;ARABIC FATHATAN ISOLATED FORM;Lo;0;AL; 0020 064B;;;;N;ARABIC SPACING FATHATAN;;;; +FE71;ARABIC TATWEEL WITH FATHATAN ABOVE;Lo;0;AL; 0640 064B;;;;N;ARABIC FATHATAN ON TATWEEL;;;; +FE72;ARABIC DAMMATAN ISOLATED FORM;Lo;0;AL; 0020 064C;;;;N;ARABIC SPACING DAMMATAN;;;; +FE73;ARABIC TAIL FRAGMENT;Lo;0;AL;;;;;N;;;;; +FE74;ARABIC KASRATAN ISOLATED FORM;Lo;0;AL; 0020 064D;;;;N;ARABIC SPACING KASRATAN;;;; +FE76;ARABIC FATHA ISOLATED FORM;Lo;0;AL; 0020 064E;;;;N;ARABIC SPACING FATHAH;;;; +FE77;ARABIC FATHA MEDIAL FORM;Lo;0;AL; 0640 064E;;;;N;ARABIC FATHAH ON TATWEEL;;;; +FE78;ARABIC DAMMA ISOLATED FORM;Lo;0;AL; 0020 064F;;;;N;ARABIC SPACING DAMMAH;;;; +FE79;ARABIC DAMMA MEDIAL FORM;Lo;0;AL; 0640 064F;;;;N;ARABIC DAMMAH ON TATWEEL;;;; +FE7A;ARABIC KASRA ISOLATED FORM;Lo;0;AL; 0020 0650;;;;N;ARABIC SPACING KASRAH;;;; +FE7B;ARABIC KASRA MEDIAL FORM;Lo;0;AL; 0640 0650;;;;N;ARABIC KASRAH ON TATWEEL;;;; +FE7C;ARABIC SHADDA ISOLATED FORM;Lo;0;AL; 0020 0651;;;;N;ARABIC SPACING SHADDAH;;;; +FE7D;ARABIC SHADDA MEDIAL FORM;Lo;0;AL; 0640 0651;;;;N;ARABIC SHADDAH ON TATWEEL;;;; +FE7E;ARABIC SUKUN ISOLATED FORM;Lo;0;AL; 0020 0652;;;;N;ARABIC SPACING SUKUN;;;; +FE7F;ARABIC SUKUN MEDIAL FORM;Lo;0;AL; 0640 0652;;;;N;ARABIC SUKUN ON TATWEEL;;;; +FE80;ARABIC LETTER HAMZA ISOLATED FORM;Lo;0;AL; 0621;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH;;;; +FE81;ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM;Lo;0;AL; 0622;;;;N;GLYPH FOR ISOLATE ARABIC MADDAH ON ALEF;;;; +FE82;ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM;Lo;0;AL; 0622;;;;N;GLYPH FOR FINAL ARABIC MADDAH ON ALEF;;;; +FE83;ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0623;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON ALEF;;;; +FE84;ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 0623;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON ALEF;;;; +FE85;ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0624;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON WAW;;;; +FE86;ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 0624;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON WAW;;;; +FE87;ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM;Lo;0;AL; 0625;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH UNDER ALEF;;;; +FE88;ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM;Lo;0;AL; 0625;;;;N;GLYPH FOR FINAL ARABIC HAMZAH UNDER ALEF;;;; +FE89;ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0626;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON YA;;;; +FE8A;ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 0626;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON YA;;;; +FE8B;ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM;Lo;0;AL; 0626;;;;N;GLYPH FOR INITIAL ARABIC HAMZAH ON YA;;;; +FE8C;ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM;Lo;0;AL; 0626;;;;N;GLYPH FOR MEDIAL ARABIC HAMZAH ON YA;;;; +FE8D;ARABIC LETTER ALEF ISOLATED FORM;Lo;0;AL; 0627;;;;N;GLYPH FOR ISOLATE ARABIC ALEF;;;; +FE8E;ARABIC LETTER ALEF FINAL FORM;Lo;0;AL; 0627;;;;N;GLYPH FOR FINAL ARABIC ALEF;;;; +FE8F;ARABIC LETTER BEH ISOLATED FORM;Lo;0;AL; 0628;;;;N;GLYPH FOR ISOLATE ARABIC BAA;;;; +FE90;ARABIC LETTER BEH FINAL FORM;Lo;0;AL; 0628;;;;N;GLYPH FOR FINAL ARABIC BAA;;;; +FE91;ARABIC LETTER BEH INITIAL FORM;Lo;0;AL; 0628;;;;N;GLYPH FOR INITIAL ARABIC BAA;;;; +FE92;ARABIC LETTER BEH MEDIAL FORM;Lo;0;AL; 0628;;;;N;GLYPH FOR MEDIAL ARABIC BAA;;;; +FE93;ARABIC LETTER TEH MARBUTA ISOLATED FORM;Lo;0;AL; 0629;;;;N;GLYPH FOR ISOLATE ARABIC TAA MARBUTAH;;;; +FE94;ARABIC LETTER TEH MARBUTA FINAL FORM;Lo;0;AL; 0629;;;;N;GLYPH FOR FINAL ARABIC TAA MARBUTAH;;;; +FE95;ARABIC LETTER TEH ISOLATED FORM;Lo;0;AL; 062A;;;;N;GLYPH FOR ISOLATE ARABIC TAA;;;; +FE96;ARABIC LETTER TEH FINAL FORM;Lo;0;AL; 062A;;;;N;GLYPH FOR FINAL ARABIC TAA;;;; +FE97;ARABIC LETTER TEH INITIAL FORM;Lo;0;AL; 062A;;;;N;GLYPH FOR INITIAL ARABIC TAA;;;; +FE98;ARABIC LETTER TEH MEDIAL FORM;Lo;0;AL; 062A;;;;N;GLYPH FOR MEDIAL ARABIC TAA;;;; +FE99;ARABIC LETTER THEH ISOLATED FORM;Lo;0;AL; 062B;;;;N;GLYPH FOR ISOLATE ARABIC THAA;;;; +FE9A;ARABIC LETTER THEH FINAL FORM;Lo;0;AL; 062B;;;;N;GLYPH FOR FINAL ARABIC THAA;;;; +FE9B;ARABIC LETTER THEH INITIAL FORM;Lo;0;AL; 062B;;;;N;GLYPH FOR INITIAL ARABIC THAA;;;; +FE9C;ARABIC LETTER THEH MEDIAL FORM;Lo;0;AL; 062B;;;;N;GLYPH FOR MEDIAL ARABIC THAA;;;; +FE9D;ARABIC LETTER JEEM ISOLATED FORM;Lo;0;AL; 062C;;;;N;GLYPH FOR ISOLATE ARABIC JEEM;;;; +FE9E;ARABIC LETTER JEEM FINAL FORM;Lo;0;AL; 062C;;;;N;GLYPH FOR FINAL ARABIC JEEM;;;; +FE9F;ARABIC LETTER JEEM INITIAL FORM;Lo;0;AL; 062C;;;;N;GLYPH FOR INITIAL ARABIC JEEM;;;; +FEA0;ARABIC LETTER JEEM MEDIAL FORM;Lo;0;AL; 062C;;;;N;GLYPH FOR MEDIAL ARABIC JEEM;;;; +FEA1;ARABIC LETTER HAH ISOLATED FORM;Lo;0;AL; 062D;;;;N;GLYPH FOR ISOLATE ARABIC HAA;;;; +FEA2;ARABIC LETTER HAH FINAL FORM;Lo;0;AL; 062D;;;;N;GLYPH FOR FINAL ARABIC HAA;;;; +FEA3;ARABIC LETTER HAH INITIAL FORM;Lo;0;AL; 062D;;;;N;GLYPH FOR INITIAL ARABIC HAA;;;; +FEA4;ARABIC LETTER HAH MEDIAL FORM;Lo;0;AL; 062D;;;;N;GLYPH FOR MEDIAL ARABIC HAA;;;; +FEA5;ARABIC LETTER KHAH ISOLATED FORM;Lo;0;AL; 062E;;;;N;GLYPH FOR ISOLATE ARABIC KHAA;;;; +FEA6;ARABIC LETTER KHAH FINAL FORM;Lo;0;AL; 062E;;;;N;GLYPH FOR FINAL ARABIC KHAA;;;; +FEA7;ARABIC LETTER KHAH INITIAL FORM;Lo;0;AL; 062E;;;;N;GLYPH FOR INITIAL ARABIC KHAA;;;; +FEA8;ARABIC LETTER KHAH MEDIAL FORM;Lo;0;AL; 062E;;;;N;GLYPH FOR MEDIAL ARABIC KHAA;;;; +FEA9;ARABIC LETTER DAL ISOLATED FORM;Lo;0;AL; 062F;;;;N;GLYPH FOR ISOLATE ARABIC DAL;;;; +FEAA;ARABIC LETTER DAL FINAL FORM;Lo;0;AL; 062F;;;;N;GLYPH FOR FINAL ARABIC DAL;;;; +FEAB;ARABIC LETTER THAL ISOLATED FORM;Lo;0;AL; 0630;;;;N;GLYPH FOR ISOLATE ARABIC THAL;;;; +FEAC;ARABIC LETTER THAL FINAL FORM;Lo;0;AL; 0630;;;;N;GLYPH FOR FINAL ARABIC THAL;;;; +FEAD;ARABIC LETTER REH ISOLATED FORM;Lo;0;AL; 0631;;;;N;GLYPH FOR ISOLATE ARABIC RA;;;; +FEAE;ARABIC LETTER REH FINAL FORM;Lo;0;AL; 0631;;;;N;GLYPH FOR FINAL ARABIC RA;;;; +FEAF;ARABIC LETTER ZAIN ISOLATED FORM;Lo;0;AL; 0632;;;;N;GLYPH FOR ISOLATE ARABIC ZAIN;;;; +FEB0;ARABIC LETTER ZAIN FINAL FORM;Lo;0;AL; 0632;;;;N;GLYPH FOR FINAL ARABIC ZAIN;;;; +FEB1;ARABIC LETTER SEEN ISOLATED FORM;Lo;0;AL; 0633;;;;N;GLYPH FOR ISOLATE ARABIC SEEN;;;; +FEB2;ARABIC LETTER SEEN FINAL FORM;Lo;0;AL; 0633;;;;N;GLYPH FOR FINAL ARABIC SEEN;;;; +FEB3;ARABIC LETTER SEEN INITIAL FORM;Lo;0;AL; 0633;;;;N;GLYPH FOR INITIAL ARABIC SEEN;;;; +FEB4;ARABIC LETTER SEEN MEDIAL FORM;Lo;0;AL; 0633;;;;N;GLYPH FOR MEDIAL ARABIC SEEN;;;; +FEB5;ARABIC LETTER SHEEN ISOLATED FORM;Lo;0;AL; 0634;;;;N;GLYPH FOR ISOLATE ARABIC SHEEN;;;; +FEB6;ARABIC LETTER SHEEN FINAL FORM;Lo;0;AL; 0634;;;;N;GLYPH FOR FINAL ARABIC SHEEN;;;; +FEB7;ARABIC LETTER SHEEN INITIAL FORM;Lo;0;AL; 0634;;;;N;GLYPH FOR INITIAL ARABIC SHEEN;;;; +FEB8;ARABIC LETTER SHEEN MEDIAL FORM;Lo;0;AL; 0634;;;;N;GLYPH FOR MEDIAL ARABIC SHEEN;;;; +FEB9;ARABIC LETTER SAD ISOLATED FORM;Lo;0;AL; 0635;;;;N;GLYPH FOR ISOLATE ARABIC SAD;;;; +FEBA;ARABIC LETTER SAD FINAL FORM;Lo;0;AL; 0635;;;;N;GLYPH FOR FINAL ARABIC SAD;;;; +FEBB;ARABIC LETTER SAD INITIAL FORM;Lo;0;AL; 0635;;;;N;GLYPH FOR INITIAL ARABIC SAD;;;; +FEBC;ARABIC LETTER SAD MEDIAL FORM;Lo;0;AL; 0635;;;;N;GLYPH FOR MEDIAL ARABIC SAD;;;; +FEBD;ARABIC LETTER DAD ISOLATED FORM;Lo;0;AL; 0636;;;;N;GLYPH FOR ISOLATE ARABIC DAD;;;; +FEBE;ARABIC LETTER DAD FINAL FORM;Lo;0;AL; 0636;;;;N;GLYPH FOR FINAL ARABIC DAD;;;; +FEBF;ARABIC LETTER DAD INITIAL FORM;Lo;0;AL; 0636;;;;N;GLYPH FOR INITIAL ARABIC DAD;;;; +FEC0;ARABIC LETTER DAD MEDIAL FORM;Lo;0;AL; 0636;;;;N;GLYPH FOR MEDIAL ARABIC DAD;;;; +FEC1;ARABIC LETTER TAH ISOLATED FORM;Lo;0;AL; 0637;;;;N;GLYPH FOR ISOLATE ARABIC TAH;;;; +FEC2;ARABIC LETTER TAH FINAL FORM;Lo;0;AL; 0637;;;;N;GLYPH FOR FINAL ARABIC TAH;;;; +FEC3;ARABIC LETTER TAH INITIAL FORM;Lo;0;AL; 0637;;;;N;GLYPH FOR INITIAL ARABIC TAH;;;; +FEC4;ARABIC LETTER TAH MEDIAL FORM;Lo;0;AL; 0637;;;;N;GLYPH FOR MEDIAL ARABIC TAH;;;; +FEC5;ARABIC LETTER ZAH ISOLATED FORM;Lo;0;AL; 0638;;;;N;GLYPH FOR ISOLATE ARABIC DHAH;;;; +FEC6;ARABIC LETTER ZAH FINAL FORM;Lo;0;AL; 0638;;;;N;GLYPH FOR FINAL ARABIC DHAH;;;; +FEC7;ARABIC LETTER ZAH INITIAL FORM;Lo;0;AL; 0638;;;;N;GLYPH FOR INITIAL ARABIC DHAH;;;; +FEC8;ARABIC LETTER ZAH MEDIAL FORM;Lo;0;AL; 0638;;;;N;GLYPH FOR MEDIAL ARABIC DHAH;;;; +FEC9;ARABIC LETTER AIN ISOLATED FORM;Lo;0;AL; 0639;;;;N;GLYPH FOR ISOLATE ARABIC AIN;;;; +FECA;ARABIC LETTER AIN FINAL FORM;Lo;0;AL; 0639;;;;N;GLYPH FOR FINAL ARABIC AIN;;;; +FECB;ARABIC LETTER AIN INITIAL FORM;Lo;0;AL; 0639;;;;N;GLYPH FOR INITIAL ARABIC AIN;;;; +FECC;ARABIC LETTER AIN MEDIAL FORM;Lo;0;AL; 0639;;;;N;GLYPH FOR MEDIAL ARABIC AIN;;;; +FECD;ARABIC LETTER GHAIN ISOLATED FORM;Lo;0;AL; 063A;;;;N;GLYPH FOR ISOLATE ARABIC GHAIN;;;; +FECE;ARABIC LETTER GHAIN FINAL FORM;Lo;0;AL; 063A;;;;N;GLYPH FOR FINAL ARABIC GHAIN;;;; +FECF;ARABIC LETTER GHAIN INITIAL FORM;Lo;0;AL; 063A;;;;N;GLYPH FOR INITIAL ARABIC GHAIN;;;; +FED0;ARABIC LETTER GHAIN MEDIAL FORM;Lo;0;AL; 063A;;;;N;GLYPH FOR MEDIAL ARABIC GHAIN;;;; +FED1;ARABIC LETTER FEH ISOLATED FORM;Lo;0;AL; 0641;;;;N;GLYPH FOR ISOLATE ARABIC FA;;;; +FED2;ARABIC LETTER FEH FINAL FORM;Lo;0;AL; 0641;;;;N;GLYPH FOR FINAL ARABIC FA;;;; +FED3;ARABIC LETTER FEH INITIAL FORM;Lo;0;AL; 0641;;;;N;GLYPH FOR INITIAL ARABIC FA;;;; +FED4;ARABIC LETTER FEH MEDIAL FORM;Lo;0;AL; 0641;;;;N;GLYPH FOR MEDIAL ARABIC FA;;;; +FED5;ARABIC LETTER QAF ISOLATED FORM;Lo;0;AL; 0642;;;;N;GLYPH FOR ISOLATE ARABIC QAF;;;; +FED6;ARABIC LETTER QAF FINAL FORM;Lo;0;AL; 0642;;;;N;GLYPH FOR FINAL ARABIC QAF;;;; +FED7;ARABIC LETTER QAF INITIAL FORM;Lo;0;AL; 0642;;;;N;GLYPH FOR INITIAL ARABIC QAF;;;; +FED8;ARABIC LETTER QAF MEDIAL FORM;Lo;0;AL; 0642;;;;N;GLYPH FOR MEDIAL ARABIC QAF;;;; +FED9;ARABIC LETTER KAF ISOLATED FORM;Lo;0;AL; 0643;;;;N;GLYPH FOR ISOLATE ARABIC CAF;;;; +FEDA;ARABIC LETTER KAF FINAL FORM;Lo;0;AL; 0643;;;;N;GLYPH FOR FINAL ARABIC CAF;;;; +FEDB;ARABIC LETTER KAF INITIAL FORM;Lo;0;AL; 0643;;;;N;GLYPH FOR INITIAL ARABIC CAF;;;; +FEDC;ARABIC LETTER KAF MEDIAL FORM;Lo;0;AL; 0643;;;;N;GLYPH FOR MEDIAL ARABIC CAF;;;; +FEDD;ARABIC LETTER LAM ISOLATED FORM;Lo;0;AL; 0644;;;;N;GLYPH FOR ISOLATE ARABIC LAM;;;; +FEDE;ARABIC LETTER LAM FINAL FORM;Lo;0;AL; 0644;;;;N;GLYPH FOR FINAL ARABIC LAM;;;; +FEDF;ARABIC LETTER LAM INITIAL FORM;Lo;0;AL; 0644;;;;N;GLYPH FOR INITIAL ARABIC LAM;;;; +FEE0;ARABIC LETTER LAM MEDIAL FORM;Lo;0;AL; 0644;;;;N;GLYPH FOR MEDIAL ARABIC LAM;;;; +FEE1;ARABIC LETTER MEEM ISOLATED FORM;Lo;0;AL; 0645;;;;N;GLYPH FOR ISOLATE ARABIC MEEM;;;; +FEE2;ARABIC LETTER MEEM FINAL FORM;Lo;0;AL; 0645;;;;N;GLYPH FOR FINAL ARABIC MEEM;;;; +FEE3;ARABIC LETTER MEEM INITIAL FORM;Lo;0;AL; 0645;;;;N;GLYPH FOR INITIAL ARABIC MEEM;;;; +FEE4;ARABIC LETTER MEEM MEDIAL FORM;Lo;0;AL; 0645;;;;N;GLYPH FOR MEDIAL ARABIC MEEM;;;; +FEE5;ARABIC LETTER NOON ISOLATED FORM;Lo;0;AL; 0646;;;;N;GLYPH FOR ISOLATE ARABIC NOON;;;; +FEE6;ARABIC LETTER NOON FINAL FORM;Lo;0;AL; 0646;;;;N;GLYPH FOR FINAL ARABIC NOON;;;; +FEE7;ARABIC LETTER NOON INITIAL FORM;Lo;0;AL; 0646;;;;N;GLYPH FOR INITIAL ARABIC NOON;;;; +FEE8;ARABIC LETTER NOON MEDIAL FORM;Lo;0;AL; 0646;;;;N;GLYPH FOR MEDIAL ARABIC NOON;;;; +FEE9;ARABIC LETTER HEH ISOLATED FORM;Lo;0;AL; 0647;;;;N;GLYPH FOR ISOLATE ARABIC HA;;;; +FEEA;ARABIC LETTER HEH FINAL FORM;Lo;0;AL; 0647;;;;N;GLYPH FOR FINAL ARABIC HA;;;; +FEEB;ARABIC LETTER HEH INITIAL FORM;Lo;0;AL; 0647;;;;N;GLYPH FOR INITIAL ARABIC HA;;;; +FEEC;ARABIC LETTER HEH MEDIAL FORM;Lo;0;AL; 0647;;;;N;GLYPH FOR MEDIAL ARABIC HA;;;; +FEED;ARABIC LETTER WAW ISOLATED FORM;Lo;0;AL; 0648;;;;N;GLYPH FOR ISOLATE ARABIC WAW;;;; +FEEE;ARABIC LETTER WAW FINAL FORM;Lo;0;AL; 0648;;;;N;GLYPH FOR FINAL ARABIC WAW;;;; +FEEF;ARABIC LETTER ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0649;;;;N;GLYPH FOR ISOLATE ARABIC ALEF MAQSURAH;;;; +FEF0;ARABIC LETTER ALEF MAKSURA FINAL FORM;Lo;0;AL; 0649;;;;N;GLYPH FOR FINAL ARABIC ALEF MAQSURAH;;;; +FEF1;ARABIC LETTER YEH ISOLATED FORM;Lo;0;AL; 064A;;;;N;GLYPH FOR ISOLATE ARABIC YA;;;; +FEF2;ARABIC LETTER YEH FINAL FORM;Lo;0;AL; 064A;;;;N;GLYPH FOR FINAL ARABIC YA;;;; +FEF3;ARABIC LETTER YEH INITIAL FORM;Lo;0;AL; 064A;;;;N;GLYPH FOR INITIAL ARABIC YA;;;; +FEF4;ARABIC LETTER YEH MEDIAL FORM;Lo;0;AL; 064A;;;;N;GLYPH FOR MEDIAL ARABIC YA;;;; +FEF5;ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM;Lo;0;AL; 0644 0622;;;;N;GLYPH FOR ISOLATE ARABIC MADDAH ON LIGATURE LAM ALEF;;;; +FEF6;ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM;Lo;0;AL; 0644 0622;;;;N;GLYPH FOR FINAL ARABIC MADDAH ON LIGATURE LAM ALEF;;;; +FEF7;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0644 0623;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON LIGATURE LAM ALEF;;;; +FEF8;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 0644 0623;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON LIGATURE LAM ALEF;;;; +FEF9;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM;Lo;0;AL; 0644 0625;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH UNDER LIGATURE LAM ALEF;;;; +FEFA;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM;Lo;0;AL; 0644 0625;;;;N;GLYPH FOR FINAL ARABIC HAMZAH UNDER LIGATURE LAM ALEF;;;; +FEFB;ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM;Lo;0;AL; 0644 0627;;;;N;GLYPH FOR ISOLATE ARABIC LIGATURE LAM ALEF;;;; +FEFC;ARABIC LIGATURE LAM WITH ALEF FINAL FORM;Lo;0;AL; 0644 0627;;;;N;GLYPH FOR FINAL ARABIC LIGATURE LAM ALEF;;;; +FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;; +FF01;FULLWIDTH EXCLAMATION MARK;Po;0;ON; 0021;;;;N;;;;; +FF02;FULLWIDTH QUOTATION MARK;Po;0;ON; 0022;;;;N;;;;; +FF03;FULLWIDTH NUMBER SIGN;Po;0;ET; 0023;;;;N;;;;; +FF04;FULLWIDTH DOLLAR SIGN;Sc;0;ET; 0024;;;;N;;;;; +FF05;FULLWIDTH PERCENT SIGN;Po;0;ET; 0025;;;;N;;;;; +FF06;FULLWIDTH AMPERSAND;Po;0;ON; 0026;;;;N;;;;; +FF07;FULLWIDTH APOSTROPHE;Po;0;ON; 0027;;;;N;;;;; +FF08;FULLWIDTH LEFT PARENTHESIS;Ps;0;ON; 0028;;;;Y;FULLWIDTH OPENING PARENTHESIS;;;; +FF09;FULLWIDTH RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;Y;FULLWIDTH CLOSING PARENTHESIS;;;; +FF0A;FULLWIDTH ASTERISK;Po;0;ON; 002A;;;;N;;;;; +FF0B;FULLWIDTH PLUS SIGN;Sm;0;ET; 002B;;;;N;;;;; +FF0C;FULLWIDTH COMMA;Po;0;CS; 002C;;;;N;;;;; +FF0D;FULLWIDTH HYPHEN-MINUS;Pd;0;ET; 002D;;;;N;;;;; +FF0E;FULLWIDTH FULL STOP;Po;0;CS; 002E;;;;N;FULLWIDTH PERIOD;;;; +FF0F;FULLWIDTH SOLIDUS;Po;0;ES; 002F;;;;N;FULLWIDTH SLASH;;;; +FF10;FULLWIDTH DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +FF11;FULLWIDTH DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +FF12;FULLWIDTH DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +FF13;FULLWIDTH DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +FF14;FULLWIDTH DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +FF15;FULLWIDTH DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +FF16;FULLWIDTH DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +FF17;FULLWIDTH DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +FF18;FULLWIDTH DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +FF19;FULLWIDTH DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +FF1A;FULLWIDTH COLON;Po;0;CS; 003A;;;;N;;;;; +FF1B;FULLWIDTH SEMICOLON;Po;0;ON; 003B;;;;N;;;;; +FF1C;FULLWIDTH LESS-THAN SIGN;Sm;0;ON; 003C;;;;Y;;;;; +FF1D;FULLWIDTH EQUALS SIGN;Sm;0;ON; 003D;;;;N;;;;; +FF1E;FULLWIDTH GREATER-THAN SIGN;Sm;0;ON; 003E;;;;Y;;;;; +FF1F;FULLWIDTH QUESTION MARK;Po;0;ON; 003F;;;;N;;;;; +FF20;FULLWIDTH COMMERCIAL AT;Po;0;ON; 0040;;;;N;;;;; +FF21;FULLWIDTH LATIN CAPITAL LETTER A;Lu;0;L; 0041;;;;N;;;;FF41; +FF22;FULLWIDTH LATIN CAPITAL LETTER B;Lu;0;L; 0042;;;;N;;;;FF42; +FF23;FULLWIDTH LATIN CAPITAL LETTER C;Lu;0;L; 0043;;;;N;;;;FF43; +FF24;FULLWIDTH LATIN CAPITAL LETTER D;Lu;0;L; 0044;;;;N;;;;FF44; +FF25;FULLWIDTH LATIN CAPITAL LETTER E;Lu;0;L; 0045;;;;N;;;;FF45; +FF26;FULLWIDTH LATIN CAPITAL LETTER F;Lu;0;L; 0046;;;;N;;;;FF46; +FF27;FULLWIDTH LATIN CAPITAL LETTER G;Lu;0;L; 0047;;;;N;;;;FF47; +FF28;FULLWIDTH LATIN CAPITAL LETTER H;Lu;0;L; 0048;;;;N;;;;FF48; +FF29;FULLWIDTH LATIN CAPITAL LETTER I;Lu;0;L; 0049;;;;N;;;;FF49; +FF2A;FULLWIDTH LATIN CAPITAL LETTER J;Lu;0;L; 004A;;;;N;;;;FF4A; +FF2B;FULLWIDTH LATIN CAPITAL LETTER K;Lu;0;L; 004B;;;;N;;;;FF4B; +FF2C;FULLWIDTH LATIN CAPITAL LETTER L;Lu;0;L; 004C;;;;N;;;;FF4C; +FF2D;FULLWIDTH LATIN CAPITAL LETTER M;Lu;0;L; 004D;;;;N;;;;FF4D; +FF2E;FULLWIDTH LATIN CAPITAL LETTER N;Lu;0;L; 004E;;;;N;;;;FF4E; +FF2F;FULLWIDTH LATIN CAPITAL LETTER O;Lu;0;L; 004F;;;;N;;;;FF4F; +FF30;FULLWIDTH LATIN CAPITAL LETTER P;Lu;0;L; 0050;;;;N;;;;FF50; +FF31;FULLWIDTH LATIN CAPITAL LETTER Q;Lu;0;L; 0051;;;;N;;;;FF51; +FF32;FULLWIDTH LATIN CAPITAL LETTER R;Lu;0;L; 0052;;;;N;;;;FF52; +FF33;FULLWIDTH LATIN CAPITAL LETTER S;Lu;0;L; 0053;;;;N;;;;FF53; +FF34;FULLWIDTH LATIN CAPITAL LETTER T;Lu;0;L; 0054;;;;N;;;;FF54; +FF35;FULLWIDTH LATIN CAPITAL LETTER U;Lu;0;L; 0055;;;;N;;;;FF55; +FF36;FULLWIDTH LATIN CAPITAL LETTER V;Lu;0;L; 0056;;;;N;;;;FF56; +FF37;FULLWIDTH LATIN CAPITAL LETTER W;Lu;0;L; 0057;;;;N;;;;FF57; +FF38;FULLWIDTH LATIN CAPITAL LETTER X;Lu;0;L; 0058;;;;N;;;;FF58; +FF39;FULLWIDTH LATIN CAPITAL LETTER Y;Lu;0;L; 0059;;;;N;;;;FF59; +FF3A;FULLWIDTH LATIN CAPITAL LETTER Z;Lu;0;L; 005A;;;;N;;;;FF5A; +FF3B;FULLWIDTH LEFT SQUARE BRACKET;Ps;0;ON; 005B;;;;Y;FULLWIDTH OPENING SQUARE BRACKET;;;; +FF3C;FULLWIDTH REVERSE SOLIDUS;Po;0;ON; 005C;;;;N;FULLWIDTH BACKSLASH;;;; +FF3D;FULLWIDTH RIGHT SQUARE BRACKET;Pe;0;ON; 005D;;;;Y;FULLWIDTH CLOSING SQUARE BRACKET;;;; +FF3E;FULLWIDTH CIRCUMFLEX ACCENT;Sk;0;ON; 005E;;;;N;FULLWIDTH SPACING CIRCUMFLEX;;;; +FF3F;FULLWIDTH LOW LINE;Pc;0;ON; 005F;;;;N;FULLWIDTH SPACING UNDERSCORE;;;; +FF40;FULLWIDTH GRAVE ACCENT;Sk;0;ON; 0060;;;;N;FULLWIDTH SPACING GRAVE;;;; +FF41;FULLWIDTH LATIN SMALL LETTER A;Ll;0;L; 0061;;;;N;;;FF21;;FF21 +FF42;FULLWIDTH LATIN SMALL LETTER B;Ll;0;L; 0062;;;;N;;;FF22;;FF22 +FF43;FULLWIDTH LATIN SMALL LETTER C;Ll;0;L; 0063;;;;N;;;FF23;;FF23 +FF44;FULLWIDTH LATIN SMALL LETTER D;Ll;0;L; 0064;;;;N;;;FF24;;FF24 +FF45;FULLWIDTH LATIN SMALL LETTER E;Ll;0;L; 0065;;;;N;;;FF25;;FF25 +FF46;FULLWIDTH LATIN SMALL LETTER F;Ll;0;L; 0066;;;;N;;;FF26;;FF26 +FF47;FULLWIDTH LATIN SMALL LETTER G;Ll;0;L; 0067;;;;N;;;FF27;;FF27 +FF48;FULLWIDTH LATIN SMALL LETTER H;Ll;0;L; 0068;;;;N;;;FF28;;FF28 +FF49;FULLWIDTH LATIN SMALL LETTER I;Ll;0;L; 0069;;;;N;;;FF29;;FF29 +FF4A;FULLWIDTH LATIN SMALL LETTER J;Ll;0;L; 006A;;;;N;;;FF2A;;FF2A +FF4B;FULLWIDTH LATIN SMALL LETTER K;Ll;0;L; 006B;;;;N;;;FF2B;;FF2B +FF4C;FULLWIDTH LATIN SMALL LETTER L;Ll;0;L; 006C;;;;N;;;FF2C;;FF2C +FF4D;FULLWIDTH LATIN SMALL LETTER M;Ll;0;L; 006D;;;;N;;;FF2D;;FF2D +FF4E;FULLWIDTH LATIN SMALL LETTER N;Ll;0;L; 006E;;;;N;;;FF2E;;FF2E +FF4F;FULLWIDTH LATIN SMALL LETTER O;Ll;0;L; 006F;;;;N;;;FF2F;;FF2F +FF50;FULLWIDTH LATIN SMALL LETTER P;Ll;0;L; 0070;;;;N;;;FF30;;FF30 +FF51;FULLWIDTH LATIN SMALL LETTER Q;Ll;0;L; 0071;;;;N;;;FF31;;FF31 +FF52;FULLWIDTH LATIN SMALL LETTER R;Ll;0;L; 0072;;;;N;;;FF32;;FF32 +FF53;FULLWIDTH LATIN SMALL LETTER S;Ll;0;L; 0073;;;;N;;;FF33;;FF33 +FF54;FULLWIDTH LATIN SMALL LETTER T;Ll;0;L; 0074;;;;N;;;FF34;;FF34 +FF55;FULLWIDTH LATIN SMALL LETTER U;Ll;0;L; 0075;;;;N;;;FF35;;FF35 +FF56;FULLWIDTH LATIN SMALL LETTER V;Ll;0;L; 0076;;;;N;;;FF36;;FF36 +FF57;FULLWIDTH LATIN SMALL LETTER W;Ll;0;L; 0077;;;;N;;;FF37;;FF37 +FF58;FULLWIDTH LATIN SMALL LETTER X;Ll;0;L; 0078;;;;N;;;FF38;;FF38 +FF59;FULLWIDTH LATIN SMALL LETTER Y;Ll;0;L; 0079;;;;N;;;FF39;;FF39 +FF5A;FULLWIDTH LATIN SMALL LETTER Z;Ll;0;L; 007A;;;;N;;;FF3A;;FF3A +FF5B;FULLWIDTH LEFT CURLY BRACKET;Ps;0;ON; 007B;;;;Y;FULLWIDTH OPENING CURLY BRACKET;;;; +FF5C;FULLWIDTH VERTICAL LINE;Sm;0;ON; 007C;;;;N;FULLWIDTH VERTICAL BAR;;;; +FF5D;FULLWIDTH RIGHT CURLY BRACKET;Pe;0;ON; 007D;;;;Y;FULLWIDTH CLOSING CURLY BRACKET;;;; +FF5E;FULLWIDTH TILDE;Sm;0;ON; 007E;;;;N;FULLWIDTH SPACING TILDE;;;; +FF5F;FULLWIDTH LEFT WHITE PARENTHESIS;Ps;0;ON; 2985;;;;Y;;*;;; +FF60;FULLWIDTH RIGHT WHITE PARENTHESIS;Pe;0;ON; 2986;;;;Y;;*;;; +FF61;HALFWIDTH IDEOGRAPHIC FULL STOP;Po;0;ON; 3002;;;;N;HALFWIDTH IDEOGRAPHIC PERIOD;;;; +FF62;HALFWIDTH LEFT CORNER BRACKET;Ps;0;ON; 300C;;;;Y;HALFWIDTH OPENING CORNER BRACKET;;;; +FF63;HALFWIDTH RIGHT CORNER BRACKET;Pe;0;ON; 300D;;;;Y;HALFWIDTH CLOSING CORNER BRACKET;;;; +FF64;HALFWIDTH IDEOGRAPHIC COMMA;Po;0;ON; 3001;;;;N;;;;; +FF65;HALFWIDTH KATAKANA MIDDLE DOT;Pc;0;ON; 30FB;;;;N;;;;; +FF66;HALFWIDTH KATAKANA LETTER WO;Lo;0;L; 30F2;;;;N;;;;; +FF67;HALFWIDTH KATAKANA LETTER SMALL A;Lo;0;L; 30A1;;;;N;;;;; +FF68;HALFWIDTH KATAKANA LETTER SMALL I;Lo;0;L; 30A3;;;;N;;;;; +FF69;HALFWIDTH KATAKANA LETTER SMALL U;Lo;0;L; 30A5;;;;N;;;;; +FF6A;HALFWIDTH KATAKANA LETTER SMALL E;Lo;0;L; 30A7;;;;N;;;;; +FF6B;HALFWIDTH KATAKANA LETTER SMALL O;Lo;0;L; 30A9;;;;N;;;;; +FF6C;HALFWIDTH KATAKANA LETTER SMALL YA;Lo;0;L; 30E3;;;;N;;;;; +FF6D;HALFWIDTH KATAKANA LETTER SMALL YU;Lo;0;L; 30E5;;;;N;;;;; +FF6E;HALFWIDTH KATAKANA LETTER SMALL YO;Lo;0;L; 30E7;;;;N;;;;; +FF6F;HALFWIDTH KATAKANA LETTER SMALL TU;Lo;0;L; 30C3;;;;N;;;;; +FF70;HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK;Lm;0;L; 30FC;;;;N;;;;; +FF71;HALFWIDTH KATAKANA LETTER A;Lo;0;L; 30A2;;;;N;;;;; +FF72;HALFWIDTH KATAKANA LETTER I;Lo;0;L; 30A4;;;;N;;;;; +FF73;HALFWIDTH KATAKANA LETTER U;Lo;0;L; 30A6;;;;N;;;;; +FF74;HALFWIDTH KATAKANA LETTER E;Lo;0;L; 30A8;;;;N;;;;; +FF75;HALFWIDTH KATAKANA LETTER O;Lo;0;L; 30AA;;;;N;;;;; +FF76;HALFWIDTH KATAKANA LETTER KA;Lo;0;L; 30AB;;;;N;;;;; +FF77;HALFWIDTH KATAKANA LETTER KI;Lo;0;L; 30AD;;;;N;;;;; +FF78;HALFWIDTH KATAKANA LETTER KU;Lo;0;L; 30AF;;;;N;;;;; +FF79;HALFWIDTH KATAKANA LETTER KE;Lo;0;L; 30B1;;;;N;;;;; +FF7A;HALFWIDTH KATAKANA LETTER KO;Lo;0;L; 30B3;;;;N;;;;; +FF7B;HALFWIDTH KATAKANA LETTER SA;Lo;0;L; 30B5;;;;N;;;;; +FF7C;HALFWIDTH KATAKANA LETTER SI;Lo;0;L; 30B7;;;;N;;;;; +FF7D;HALFWIDTH KATAKANA LETTER SU;Lo;0;L; 30B9;;;;N;;;;; +FF7E;HALFWIDTH KATAKANA LETTER SE;Lo;0;L; 30BB;;;;N;;;;; +FF7F;HALFWIDTH KATAKANA LETTER SO;Lo;0;L; 30BD;;;;N;;;;; +FF80;HALFWIDTH KATAKANA LETTER TA;Lo;0;L; 30BF;;;;N;;;;; +FF81;HALFWIDTH KATAKANA LETTER TI;Lo;0;L; 30C1;;;;N;;;;; +FF82;HALFWIDTH KATAKANA LETTER TU;Lo;0;L; 30C4;;;;N;;;;; +FF83;HALFWIDTH KATAKANA LETTER TE;Lo;0;L; 30C6;;;;N;;;;; +FF84;HALFWIDTH KATAKANA LETTER TO;Lo;0;L; 30C8;;;;N;;;;; +FF85;HALFWIDTH KATAKANA LETTER NA;Lo;0;L; 30CA;;;;N;;;;; +FF86;HALFWIDTH KATAKANA LETTER NI;Lo;0;L; 30CB;;;;N;;;;; +FF87;HALFWIDTH KATAKANA LETTER NU;Lo;0;L; 30CC;;;;N;;;;; +FF88;HALFWIDTH KATAKANA LETTER NE;Lo;0;L; 30CD;;;;N;;;;; +FF89;HALFWIDTH KATAKANA LETTER NO;Lo;0;L; 30CE;;;;N;;;;; +FF8A;HALFWIDTH KATAKANA LETTER HA;Lo;0;L; 30CF;;;;N;;;;; +FF8B;HALFWIDTH KATAKANA LETTER HI;Lo;0;L; 30D2;;;;N;;;;; +FF8C;HALFWIDTH KATAKANA LETTER HU;Lo;0;L; 30D5;;;;N;;;;; +FF8D;HALFWIDTH KATAKANA LETTER HE;Lo;0;L; 30D8;;;;N;;;;; +FF8E;HALFWIDTH KATAKANA LETTER HO;Lo;0;L; 30DB;;;;N;;;;; +FF8F;HALFWIDTH KATAKANA LETTER MA;Lo;0;L; 30DE;;;;N;;;;; +FF90;HALFWIDTH KATAKANA LETTER MI;Lo;0;L; 30DF;;;;N;;;;; +FF91;HALFWIDTH KATAKANA LETTER MU;Lo;0;L; 30E0;;;;N;;;;; +FF92;HALFWIDTH KATAKANA LETTER ME;Lo;0;L; 30E1;;;;N;;;;; +FF93;HALFWIDTH KATAKANA LETTER MO;Lo;0;L; 30E2;;;;N;;;;; +FF94;HALFWIDTH KATAKANA LETTER YA;Lo;0;L; 30E4;;;;N;;;;; +FF95;HALFWIDTH KATAKANA LETTER YU;Lo;0;L; 30E6;;;;N;;;;; +FF96;HALFWIDTH KATAKANA LETTER YO;Lo;0;L; 30E8;;;;N;;;;; +FF97;HALFWIDTH KATAKANA LETTER RA;Lo;0;L; 30E9;;;;N;;;;; +FF98;HALFWIDTH KATAKANA LETTER RI;Lo;0;L; 30EA;;;;N;;;;; +FF99;HALFWIDTH KATAKANA LETTER RU;Lo;0;L; 30EB;;;;N;;;;; +FF9A;HALFWIDTH KATAKANA LETTER RE;Lo;0;L; 30EC;;;;N;;;;; +FF9B;HALFWIDTH KATAKANA LETTER RO;Lo;0;L; 30ED;;;;N;;;;; +FF9C;HALFWIDTH KATAKANA LETTER WA;Lo;0;L; 30EF;;;;N;;;;; +FF9D;HALFWIDTH KATAKANA LETTER N;Lo;0;L; 30F3;;;;N;;;;; +FF9E;HALFWIDTH KATAKANA VOICED SOUND MARK;Lm;0;L; 3099;;;;N;;halfwidth katakana-hiragana voiced sound mark;;; +FF9F;HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK;Lm;0;L; 309A;;;;N;;halfwidth katakana-hiragana semi-voiced sound mark;;; +FFA0;HALFWIDTH HANGUL FILLER;Lo;0;L; 3164;;;;N;HALFWIDTH HANGUL CAE OM;;;; +FFA1;HALFWIDTH HANGUL LETTER KIYEOK;Lo;0;L; 3131;;;;N;HALFWIDTH HANGUL LETTER GIYEOG;;;; +FFA2;HALFWIDTH HANGUL LETTER SSANGKIYEOK;Lo;0;L; 3132;;;;N;HALFWIDTH HANGUL LETTER SSANG GIYEOG;;;; +FFA3;HALFWIDTH HANGUL LETTER KIYEOK-SIOS;Lo;0;L; 3133;;;;N;HALFWIDTH HANGUL LETTER GIYEOG SIOS;;;; +FFA4;HALFWIDTH HANGUL LETTER NIEUN;Lo;0;L; 3134;;;;N;;;;; +FFA5;HALFWIDTH HANGUL LETTER NIEUN-CIEUC;Lo;0;L; 3135;;;;N;HALFWIDTH HANGUL LETTER NIEUN JIEUJ;;;; +FFA6;HALFWIDTH HANGUL LETTER NIEUN-HIEUH;Lo;0;L; 3136;;;;N;HALFWIDTH HANGUL LETTER NIEUN HIEUH;;;; +FFA7;HALFWIDTH HANGUL LETTER TIKEUT;Lo;0;L; 3137;;;;N;HALFWIDTH HANGUL LETTER DIGEUD;;;; +FFA8;HALFWIDTH HANGUL LETTER SSANGTIKEUT;Lo;0;L; 3138;;;;N;HALFWIDTH HANGUL LETTER SSANG DIGEUD;;;; +FFA9;HALFWIDTH HANGUL LETTER RIEUL;Lo;0;L; 3139;;;;N;HALFWIDTH HANGUL LETTER LIEUL;;;; +FFAA;HALFWIDTH HANGUL LETTER RIEUL-KIYEOK;Lo;0;L; 313A;;;;N;HALFWIDTH HANGUL LETTER LIEUL GIYEOG;;;; +FFAB;HALFWIDTH HANGUL LETTER RIEUL-MIEUM;Lo;0;L; 313B;;;;N;HALFWIDTH HANGUL LETTER LIEUL MIEUM;;;; +FFAC;HALFWIDTH HANGUL LETTER RIEUL-PIEUP;Lo;0;L; 313C;;;;N;HALFWIDTH HANGUL LETTER LIEUL BIEUB;;;; +FFAD;HALFWIDTH HANGUL LETTER RIEUL-SIOS;Lo;0;L; 313D;;;;N;HALFWIDTH HANGUL LETTER LIEUL SIOS;;;; +FFAE;HALFWIDTH HANGUL LETTER RIEUL-THIEUTH;Lo;0;L; 313E;;;;N;HALFWIDTH HANGUL LETTER LIEUL TIEUT;;;; +FFAF;HALFWIDTH HANGUL LETTER RIEUL-PHIEUPH;Lo;0;L; 313F;;;;N;HALFWIDTH HANGUL LETTER LIEUL PIEUP;;;; +FFB0;HALFWIDTH HANGUL LETTER RIEUL-HIEUH;Lo;0;L; 3140;;;;N;HALFWIDTH HANGUL LETTER LIEUL HIEUH;;;; +FFB1;HALFWIDTH HANGUL LETTER MIEUM;Lo;0;L; 3141;;;;N;;;;; +FFB2;HALFWIDTH HANGUL LETTER PIEUP;Lo;0;L; 3142;;;;N;HALFWIDTH HANGUL LETTER BIEUB;;;; +FFB3;HALFWIDTH HANGUL LETTER SSANGPIEUP;Lo;0;L; 3143;;;;N;HALFWIDTH HANGUL LETTER SSANG BIEUB;;;; +FFB4;HALFWIDTH HANGUL LETTER PIEUP-SIOS;Lo;0;L; 3144;;;;N;HALFWIDTH HANGUL LETTER BIEUB SIOS;;;; +FFB5;HALFWIDTH HANGUL LETTER SIOS;Lo;0;L; 3145;;;;N;;;;; +FFB6;HALFWIDTH HANGUL LETTER SSANGSIOS;Lo;0;L; 3146;;;;N;HALFWIDTH HANGUL LETTER SSANG SIOS;;;; +FFB7;HALFWIDTH HANGUL LETTER IEUNG;Lo;0;L; 3147;;;;N;;;;; +FFB8;HALFWIDTH HANGUL LETTER CIEUC;Lo;0;L; 3148;;;;N;HALFWIDTH HANGUL LETTER JIEUJ;;;; +FFB9;HALFWIDTH HANGUL LETTER SSANGCIEUC;Lo;0;L; 3149;;;;N;HALFWIDTH HANGUL LETTER SSANG JIEUJ;;;; +FFBA;HALFWIDTH HANGUL LETTER CHIEUCH;Lo;0;L; 314A;;;;N;HALFWIDTH HANGUL LETTER CIEUC;;;; +FFBB;HALFWIDTH HANGUL LETTER KHIEUKH;Lo;0;L; 314B;;;;N;HALFWIDTH HANGUL LETTER KIYEOK;;;; +FFBC;HALFWIDTH HANGUL LETTER THIEUTH;Lo;0;L; 314C;;;;N;HALFWIDTH HANGUL LETTER TIEUT;;;; +FFBD;HALFWIDTH HANGUL LETTER PHIEUPH;Lo;0;L; 314D;;;;N;HALFWIDTH HANGUL LETTER PIEUP;;;; +FFBE;HALFWIDTH HANGUL LETTER HIEUH;Lo;0;L; 314E;;;;N;;;;; +FFC2;HALFWIDTH HANGUL LETTER A;Lo;0;L; 314F;;;;N;;;;; +FFC3;HALFWIDTH HANGUL LETTER AE;Lo;0;L; 3150;;;;N;;;;; +FFC4;HALFWIDTH HANGUL LETTER YA;Lo;0;L; 3151;;;;N;;;;; +FFC5;HALFWIDTH HANGUL LETTER YAE;Lo;0;L; 3152;;;;N;;;;; +FFC6;HALFWIDTH HANGUL LETTER EO;Lo;0;L; 3153;;;;N;;;;; +FFC7;HALFWIDTH HANGUL LETTER E;Lo;0;L; 3154;;;;N;;;;; +FFCA;HALFWIDTH HANGUL LETTER YEO;Lo;0;L; 3155;;;;N;;;;; +FFCB;HALFWIDTH HANGUL LETTER YE;Lo;0;L; 3156;;;;N;;;;; +FFCC;HALFWIDTH HANGUL LETTER O;Lo;0;L; 3157;;;;N;;;;; +FFCD;HALFWIDTH HANGUL LETTER WA;Lo;0;L; 3158;;;;N;;;;; +FFCE;HALFWIDTH HANGUL LETTER WAE;Lo;0;L; 3159;;;;N;;;;; +FFCF;HALFWIDTH HANGUL LETTER OE;Lo;0;L; 315A;;;;N;;;;; +FFD2;HALFWIDTH HANGUL LETTER YO;Lo;0;L; 315B;;;;N;;;;; +FFD3;HALFWIDTH HANGUL LETTER U;Lo;0;L; 315C;;;;N;;;;; +FFD4;HALFWIDTH HANGUL LETTER WEO;Lo;0;L; 315D;;;;N;;;;; +FFD5;HALFWIDTH HANGUL LETTER WE;Lo;0;L; 315E;;;;N;;;;; +FFD6;HALFWIDTH HANGUL LETTER WI;Lo;0;L; 315F;;;;N;;;;; +FFD7;HALFWIDTH HANGUL LETTER YU;Lo;0;L; 3160;;;;N;;;;; +FFDA;HALFWIDTH HANGUL LETTER EU;Lo;0;L; 3161;;;;N;;;;; +FFDB;HALFWIDTH HANGUL LETTER YI;Lo;0;L; 3162;;;;N;;;;; +FFDC;HALFWIDTH HANGUL LETTER I;Lo;0;L; 3163;;;;N;;;;; +FFE0;FULLWIDTH CENT SIGN;Sc;0;ET; 00A2;;;;N;;;;; +FFE1;FULLWIDTH POUND SIGN;Sc;0;ET; 00A3;;;;N;;;;; +FFE2;FULLWIDTH NOT SIGN;Sm;0;ON; 00AC;;;;N;;;;; +FFE3;FULLWIDTH MACRON;Sk;0;ON; 00AF;;;;N;FULLWIDTH SPACING MACRON;*;;; +FFE4;FULLWIDTH BROKEN BAR;So;0;ON; 00A6;;;;N;FULLWIDTH BROKEN VERTICAL BAR;;;; +FFE5;FULLWIDTH YEN SIGN;Sc;0;ET; 00A5;;;;N;;;;; +FFE6;FULLWIDTH WON SIGN;Sc;0;ET; 20A9;;;;N;;;;; +FFE8;HALFWIDTH FORMS LIGHT VERTICAL;So;0;ON; 2502;;;;N;;;;; +FFE9;HALFWIDTH LEFTWARDS ARROW;Sm;0;ON; 2190;;;;N;;;;; +FFEA;HALFWIDTH UPWARDS ARROW;Sm;0;ON; 2191;;;;N;;;;; +FFEB;HALFWIDTH RIGHTWARDS ARROW;Sm;0;ON; 2192;;;;N;;;;; +FFEC;HALFWIDTH DOWNWARDS ARROW;Sm;0;ON; 2193;;;;N;;;;; +FFED;HALFWIDTH BLACK SQUARE;So;0;ON; 25A0;;;;N;;;;; +FFEE;HALFWIDTH WHITE CIRCLE;So;0;ON; 25CB;;;;N;;;;; +FFF9;INTERLINEAR ANNOTATION ANCHOR;Cf;0;BN;;;;;N;;;;; +FFFA;INTERLINEAR ANNOTATION SEPARATOR;Cf;0;BN;;;;;N;;;;; +FFFB;INTERLINEAR ANNOTATION TERMINATOR;Cf;0;BN;;;;;N;;;;; +FFFC;OBJECT REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; +FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; +10300;OLD ITALIC LETTER A;Lo;0;L;;;;;N;;;;; +10301;OLD ITALIC LETTER BE;Lo;0;L;;;;;N;;;;; +10302;OLD ITALIC LETTER KE;Lo;0;L;;;;;N;;;;; +10303;OLD ITALIC LETTER DE;Lo;0;L;;;;;N;;;;; +10304;OLD ITALIC LETTER E;Lo;0;L;;;;;N;;;;; +10305;OLD ITALIC LETTER VE;Lo;0;L;;;;;N;;;;; +10306;OLD ITALIC LETTER ZE;Lo;0;L;;;;;N;;;;; +10307;OLD ITALIC LETTER HE;Lo;0;L;;;;;N;;;;; +10308;OLD ITALIC LETTER THE;Lo;0;L;;;;;N;;;;; +10309;OLD ITALIC LETTER I;Lo;0;L;;;;;N;;;;; +1030A;OLD ITALIC LETTER KA;Lo;0;L;;;;;N;;;;; +1030B;OLD ITALIC LETTER EL;Lo;0;L;;;;;N;;;;; +1030C;OLD ITALIC LETTER EM;Lo;0;L;;;;;N;;;;; +1030D;OLD ITALIC LETTER EN;Lo;0;L;;;;;N;;;;; +1030E;OLD ITALIC LETTER ESH;Lo;0;L;;;;;N;;;;; +1030F;OLD ITALIC LETTER O;Lo;0;L;;;;;N;;Faliscan;;; +10310;OLD ITALIC LETTER PE;Lo;0;L;;;;;N;;;;; +10311;OLD ITALIC LETTER SHE;Lo;0;L;;;;;N;;;;; +10312;OLD ITALIC LETTER KU;Lo;0;L;;;;;N;;;;; +10313;OLD ITALIC LETTER ER;Lo;0;L;;;;;N;;;;; +10314;OLD ITALIC LETTER ES;Lo;0;L;;;;;N;;;;; +10315;OLD ITALIC LETTER TE;Lo;0;L;;;;;N;;;;; +10316;OLD ITALIC LETTER U;Lo;0;L;;;;;N;;;;; +10317;OLD ITALIC LETTER EKS;Lo;0;L;;;;;N;;Faliscan;;; +10318;OLD ITALIC LETTER PHE;Lo;0;L;;;;;N;;;;; +10319;OLD ITALIC LETTER KHE;Lo;0;L;;;;;N;;;;; +1031A;OLD ITALIC LETTER EF;Lo;0;L;;;;;N;;;;; +1031B;OLD ITALIC LETTER ERS;Lo;0;L;;;;;N;;Umbrian;;; +1031C;OLD ITALIC LETTER CHE;Lo;0;L;;;;;N;;Umbrian;;; +1031D;OLD ITALIC LETTER II;Lo;0;L;;;;;N;;Oscan;;; +1031E;OLD ITALIC LETTER UU;Lo;0;L;;;;;N;;Oscan;;; +10320;OLD ITALIC NUMERAL ONE;No;0;L;;;;1;N;;;;; +10321;OLD ITALIC NUMERAL FIVE;No;0;L;;;;5;N;;;;; +10322;OLD ITALIC NUMERAL TEN;No;0;L;;;;10;N;;;;; +10323;OLD ITALIC NUMERAL FIFTY;No;0;L;;;;50;N;;;;; +10330;GOTHIC LETTER AHSA;Lo;0;L;;;;;N;;;;; +10331;GOTHIC LETTER BAIRKAN;Lo;0;L;;;;;N;;;;; +10332;GOTHIC LETTER GIBA;Lo;0;L;;;;;N;;;;; +10333;GOTHIC LETTER DAGS;Lo;0;L;;;;;N;;;;; +10334;GOTHIC LETTER AIHVUS;Lo;0;L;;;;;N;;;;; +10335;GOTHIC LETTER QAIRTHRA;Lo;0;L;;;;;N;;;;; +10336;GOTHIC LETTER IUJA;Lo;0;L;;;;;N;;;;; +10337;GOTHIC LETTER HAGL;Lo;0;L;;;;;N;;;;; +10338;GOTHIC LETTER THIUTH;Lo;0;L;;;;;N;;;;; +10339;GOTHIC LETTER EIS;Lo;0;L;;;;;N;;;;; +1033A;GOTHIC LETTER KUSMA;Lo;0;L;;;;;N;;;;; +1033B;GOTHIC LETTER LAGUS;Lo;0;L;;;;;N;;;;; +1033C;GOTHIC LETTER MANNA;Lo;0;L;;;;;N;;;;; +1033D;GOTHIC LETTER NAUTHS;Lo;0;L;;;;;N;;;;; +1033E;GOTHIC LETTER JER;Lo;0;L;;;;;N;;;;; +1033F;GOTHIC LETTER URUS;Lo;0;L;;;;;N;;;;; +10340;GOTHIC LETTER PAIRTHRA;Lo;0;L;;;;;N;;;;; +10341;GOTHIC LETTER NINETY;Lo;0;L;;;;;N;;;;; +10342;GOTHIC LETTER RAIDA;Lo;0;L;;;;;N;;;;; +10343;GOTHIC LETTER SAUIL;Lo;0;L;;;;;N;;;;; +10344;GOTHIC LETTER TEIWS;Lo;0;L;;;;;N;;;;; +10345;GOTHIC LETTER WINJA;Lo;0;L;;;;;N;;;;; +10346;GOTHIC LETTER FAIHU;Lo;0;L;;;;;N;;;;; +10347;GOTHIC LETTER IGGWS;Lo;0;L;;;;;N;;;;; +10348;GOTHIC LETTER HWAIR;Lo;0;L;;;;;N;;;;; +10349;GOTHIC LETTER OTHAL;Lo;0;L;;;;;N;;;;; +1034A;GOTHIC LETTER NINE HUNDRED;Nl;0;L;;;;;N;;;;; +10400;DESERET CAPITAL LETTER LONG I;Lu;0;L;;;;;N;;;;10428; +10401;DESERET CAPITAL LETTER LONG E;Lu;0;L;;;;;N;;;;10429; +10402;DESERET CAPITAL LETTER LONG A;Lu;0;L;;;;;N;;;;1042A; +10403;DESERET CAPITAL LETTER LONG AH;Lu;0;L;;;;;N;;;;1042B; +10404;DESERET CAPITAL LETTER LONG O;Lu;0;L;;;;;N;;;;1042C; +10405;DESERET CAPITAL LETTER LONG OO;Lu;0;L;;;;;N;;;;1042D; +10406;DESERET CAPITAL LETTER SHORT I;Lu;0;L;;;;;N;;;;1042E; +10407;DESERET CAPITAL LETTER SHORT E;Lu;0;L;;;;;N;;;;1042F; +10408;DESERET CAPITAL LETTER SHORT A;Lu;0;L;;;;;N;;;;10430; +10409;DESERET CAPITAL LETTER SHORT AH;Lu;0;L;;;;;N;;;;10431; +1040A;DESERET CAPITAL LETTER SHORT O;Lu;0;L;;;;;N;;;;10432; +1040B;DESERET CAPITAL LETTER SHORT OO;Lu;0;L;;;;;N;;;;10433; +1040C;DESERET CAPITAL LETTER AY;Lu;0;L;;;;;N;;;;10434; +1040D;DESERET CAPITAL LETTER OW;Lu;0;L;;;;;N;;;;10435; +1040E;DESERET CAPITAL LETTER WU;Lu;0;L;;;;;N;;;;10436; +1040F;DESERET CAPITAL LETTER YEE;Lu;0;L;;;;;N;;;;10437; +10410;DESERET CAPITAL LETTER H;Lu;0;L;;;;;N;;;;10438; +10411;DESERET CAPITAL LETTER PEE;Lu;0;L;;;;;N;;;;10439; +10412;DESERET CAPITAL LETTER BEE;Lu;0;L;;;;;N;;;;1043A; +10413;DESERET CAPITAL LETTER TEE;Lu;0;L;;;;;N;;;;1043B; +10414;DESERET CAPITAL LETTER DEE;Lu;0;L;;;;;N;;;;1043C; +10415;DESERET CAPITAL LETTER CHEE;Lu;0;L;;;;;N;;;;1043D; +10416;DESERET CAPITAL LETTER JEE;Lu;0;L;;;;;N;;;;1043E; +10417;DESERET CAPITAL LETTER KAY;Lu;0;L;;;;;N;;;;1043F; +10418;DESERET CAPITAL LETTER GAY;Lu;0;L;;;;;N;;;;10440; +10419;DESERET CAPITAL LETTER EF;Lu;0;L;;;;;N;;;;10441; +1041A;DESERET CAPITAL LETTER VEE;Lu;0;L;;;;;N;;;;10442; +1041B;DESERET CAPITAL LETTER ETH;Lu;0;L;;;;;N;;;;10443; +1041C;DESERET CAPITAL LETTER THEE;Lu;0;L;;;;;N;;;;10444; +1041D;DESERET CAPITAL LETTER ES;Lu;0;L;;;;;N;;;;10445; +1041E;DESERET CAPITAL LETTER ZEE;Lu;0;L;;;;;N;;;;10446; +1041F;DESERET CAPITAL LETTER ESH;Lu;0;L;;;;;N;;;;10447; +10420;DESERET CAPITAL LETTER ZHEE;Lu;0;L;;;;;N;;;;10448; +10421;DESERET CAPITAL LETTER ER;Lu;0;L;;;;;N;;;;10449; +10422;DESERET CAPITAL LETTER EL;Lu;0;L;;;;;N;;;;1044A; +10423;DESERET CAPITAL LETTER EM;Lu;0;L;;;;;N;;;;1044B; +10424;DESERET CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;1044C; +10425;DESERET CAPITAL LETTER ENG;Lu;0;L;;;;;N;;;;1044D; +10428;DESERET SMALL LETTER LONG I;Ll;0;L;;;;;N;;;10400;;10400 +10429;DESERET SMALL LETTER LONG E;Ll;0;L;;;;;N;;;10401;;10401 +1042A;DESERET SMALL LETTER LONG A;Ll;0;L;;;;;N;;;10402;;10402 +1042B;DESERET SMALL LETTER LONG AH;Ll;0;L;;;;;N;;;10403;;10403 +1042C;DESERET SMALL LETTER LONG O;Ll;0;L;;;;;N;;;10404;;10404 +1042D;DESERET SMALL LETTER LONG OO;Ll;0;L;;;;;N;;;10405;;10405 +1042E;DESERET SMALL LETTER SHORT I;Ll;0;L;;;;;N;;;10406;;10406 +1042F;DESERET SMALL LETTER SHORT E;Ll;0;L;;;;;N;;;10407;;10407 +10430;DESERET SMALL LETTER SHORT A;Ll;0;L;;;;;N;;;10408;;10408 +10431;DESERET SMALL LETTER SHORT AH;Ll;0;L;;;;;N;;;10409;;10409 +10432;DESERET SMALL LETTER SHORT O;Ll;0;L;;;;;N;;;1040A;;1040A +10433;DESERET SMALL LETTER SHORT OO;Ll;0;L;;;;;N;;;1040B;;1040B +10434;DESERET SMALL LETTER AY;Ll;0;L;;;;;N;;;1040C;;1040C +10435;DESERET SMALL LETTER OW;Ll;0;L;;;;;N;;;1040D;;1040D +10436;DESERET SMALL LETTER WU;Ll;0;L;;;;;N;;;1040E;;1040E +10437;DESERET SMALL LETTER YEE;Ll;0;L;;;;;N;;;1040F;;1040F +10438;DESERET SMALL LETTER H;Ll;0;L;;;;;N;;;10410;;10410 +10439;DESERET SMALL LETTER PEE;Ll;0;L;;;;;N;;;10411;;10411 +1043A;DESERET SMALL LETTER BEE;Ll;0;L;;;;;N;;;10412;;10412 +1043B;DESERET SMALL LETTER TEE;Ll;0;L;;;;;N;;;10413;;10413 +1043C;DESERET SMALL LETTER DEE;Ll;0;L;;;;;N;;;10414;;10414 +1043D;DESERET SMALL LETTER CHEE;Ll;0;L;;;;;N;;;10415;;10415 +1043E;DESERET SMALL LETTER JEE;Ll;0;L;;;;;N;;;10416;;10416 +1043F;DESERET SMALL LETTER KAY;Ll;0;L;;;;;N;;;10417;;10417 +10440;DESERET SMALL LETTER GAY;Ll;0;L;;;;;N;;;10418;;10418 +10441;DESERET SMALL LETTER EF;Ll;0;L;;;;;N;;;10419;;10419 +10442;DESERET SMALL LETTER VEE;Ll;0;L;;;;;N;;;1041A;;1041A +10443;DESERET SMALL LETTER ETH;Ll;0;L;;;;;N;;;1041B;;1041B +10444;DESERET SMALL LETTER THEE;Ll;0;L;;;;;N;;;1041C;;1041C +10445;DESERET SMALL LETTER ES;Ll;0;L;;;;;N;;;1041D;;1041D +10446;DESERET SMALL LETTER ZEE;Ll;0;L;;;;;N;;;1041E;;1041E +10447;DESERET SMALL LETTER ESH;Ll;0;L;;;;;N;;;1041F;;1041F +10448;DESERET SMALL LETTER ZHEE;Ll;0;L;;;;;N;;;10420;;10420 +10449;DESERET SMALL LETTER ER;Ll;0;L;;;;;N;;;10421;;10421 +1044A;DESERET SMALL LETTER EL;Ll;0;L;;;;;N;;;10422;;10422 +1044B;DESERET SMALL LETTER EM;Ll;0;L;;;;;N;;;10423;;10423 +1044C;DESERET SMALL LETTER EN;Ll;0;L;;;;;N;;;10424;;10424 +1044D;DESERET SMALL LETTER ENG;Ll;0;L;;;;;N;;;10425;;10425 +1D000;BYZANTINE MUSICAL SYMBOL PSILI;So;0;L;;;;;N;;;;; +1D001;BYZANTINE MUSICAL SYMBOL DASEIA;So;0;L;;;;;N;;;;; +1D002;BYZANTINE MUSICAL SYMBOL PERISPOMENI;So;0;L;;;;;N;;;;; +1D003;BYZANTINE MUSICAL SYMBOL OXEIA EKFONITIKON;So;0;L;;;;;N;;;;; +1D004;BYZANTINE MUSICAL SYMBOL OXEIA DIPLI;So;0;L;;;;;N;;;;; +1D005;BYZANTINE MUSICAL SYMBOL VAREIA EKFONITIKON;So;0;L;;;;;N;;;;; +1D006;BYZANTINE MUSICAL SYMBOL VAREIA DIPLI;So;0;L;;;;;N;;;;; +1D007;BYZANTINE MUSICAL SYMBOL KATHISTI;So;0;L;;;;;N;;;;; +1D008;BYZANTINE MUSICAL SYMBOL SYRMATIKI;So;0;L;;;;;N;;;;; +1D009;BYZANTINE MUSICAL SYMBOL PARAKLITIKI;So;0;L;;;;;N;;;;; +1D00A;BYZANTINE MUSICAL SYMBOL YPOKRISIS;So;0;L;;;;;N;;;;; +1D00B;BYZANTINE MUSICAL SYMBOL YPOKRISIS DIPLI;So;0;L;;;;;N;;;;; +1D00C;BYZANTINE MUSICAL SYMBOL KREMASTI;So;0;L;;;;;N;;;;; +1D00D;BYZANTINE MUSICAL SYMBOL APESO EKFONITIKON;So;0;L;;;;;N;;;;; +1D00E;BYZANTINE MUSICAL SYMBOL EXO EKFONITIKON;So;0;L;;;;;N;;;;; +1D00F;BYZANTINE MUSICAL SYMBOL TELEIA;So;0;L;;;;;N;;;;; +1D010;BYZANTINE MUSICAL SYMBOL KENTIMATA;So;0;L;;;;;N;;;;; +1D011;BYZANTINE MUSICAL SYMBOL APOSTROFOS;So;0;L;;;;;N;;;;; +1D012;BYZANTINE MUSICAL SYMBOL APOSTROFOS DIPLI;So;0;L;;;;;N;;;;; +1D013;BYZANTINE MUSICAL SYMBOL SYNEVMA;So;0;L;;;;;N;;;;; +1D014;BYZANTINE MUSICAL SYMBOL THITA;So;0;L;;;;;N;;;;; +1D015;BYZANTINE MUSICAL SYMBOL OLIGON ARCHAION;So;0;L;;;;;N;;;;; +1D016;BYZANTINE MUSICAL SYMBOL GORGON ARCHAION;So;0;L;;;;;N;;;;; +1D017;BYZANTINE MUSICAL SYMBOL PSILON;So;0;L;;;;;N;;;;; +1D018;BYZANTINE MUSICAL SYMBOL CHAMILON;So;0;L;;;;;N;;;;; +1D019;BYZANTINE MUSICAL SYMBOL VATHY;So;0;L;;;;;N;;;;; +1D01A;BYZANTINE MUSICAL SYMBOL ISON ARCHAION;So;0;L;;;;;N;;;;; +1D01B;BYZANTINE MUSICAL SYMBOL KENTIMA ARCHAION;So;0;L;;;;;N;;;;; +1D01C;BYZANTINE MUSICAL SYMBOL KENTIMATA ARCHAION;So;0;L;;;;;N;;;;; +1D01D;BYZANTINE MUSICAL SYMBOL SAXIMATA;So;0;L;;;;;N;;;;; +1D01E;BYZANTINE MUSICAL SYMBOL PARICHON;So;0;L;;;;;N;;;;; +1D01F;BYZANTINE MUSICAL SYMBOL STAVROS APODEXIA;So;0;L;;;;;N;;;;; +1D020;BYZANTINE MUSICAL SYMBOL OXEIAI ARCHAION;So;0;L;;;;;N;;;;; +1D021;BYZANTINE MUSICAL SYMBOL VAREIAI ARCHAION;So;0;L;;;;;N;;;;; +1D022;BYZANTINE MUSICAL SYMBOL APODERMA ARCHAION;So;0;L;;;;;N;;;;; +1D023;BYZANTINE MUSICAL SYMBOL APOTHEMA;So;0;L;;;;;N;;;;; +1D024;BYZANTINE MUSICAL SYMBOL KLASMA;So;0;L;;;;;N;;;;; +1D025;BYZANTINE MUSICAL SYMBOL REVMA;So;0;L;;;;;N;;;;; +1D026;BYZANTINE MUSICAL SYMBOL PIASMA ARCHAION;So;0;L;;;;;N;;;;; +1D027;BYZANTINE MUSICAL SYMBOL TINAGMA;So;0;L;;;;;N;;;;; +1D028;BYZANTINE MUSICAL SYMBOL ANATRICHISMA;So;0;L;;;;;N;;;;; +1D029;BYZANTINE MUSICAL SYMBOL SEISMA;So;0;L;;;;;N;;;;; +1D02A;BYZANTINE MUSICAL SYMBOL SYNAGMA ARCHAION;So;0;L;;;;;N;;;;; +1D02B;BYZANTINE MUSICAL SYMBOL SYNAGMA META STAVROU;So;0;L;;;;;N;;;;; +1D02C;BYZANTINE MUSICAL SYMBOL OYRANISMA ARCHAION;So;0;L;;;;;N;;;;; +1D02D;BYZANTINE MUSICAL SYMBOL THEMA;So;0;L;;;;;N;;;;; +1D02E;BYZANTINE MUSICAL SYMBOL LEMOI;So;0;L;;;;;N;;;;; +1D02F;BYZANTINE MUSICAL SYMBOL DYO;So;0;L;;;;;N;;;;; +1D030;BYZANTINE MUSICAL SYMBOL TRIA;So;0;L;;;;;N;;;;; +1D031;BYZANTINE MUSICAL SYMBOL TESSERA;So;0;L;;;;;N;;;;; +1D032;BYZANTINE MUSICAL SYMBOL KRATIMATA;So;0;L;;;;;N;;;;; +1D033;BYZANTINE MUSICAL SYMBOL APESO EXO NEO;So;0;L;;;;;N;;;;; +1D034;BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION;So;0;L;;;;;N;;;;; +1D035;BYZANTINE MUSICAL SYMBOL IMIFTHORA;So;0;L;;;;;N;;;;; +1D036;BYZANTINE MUSICAL SYMBOL TROMIKON ARCHAION;So;0;L;;;;;N;;;;; +1D037;BYZANTINE MUSICAL SYMBOL KATAVA TROMIKON;So;0;L;;;;;N;;;;; +1D038;BYZANTINE MUSICAL SYMBOL PELASTON;So;0;L;;;;;N;;;;; +1D039;BYZANTINE MUSICAL SYMBOL PSIFISTON;So;0;L;;;;;N;;;;; +1D03A;BYZANTINE MUSICAL SYMBOL KONTEVMA;So;0;L;;;;;N;;;;; +1D03B;BYZANTINE MUSICAL SYMBOL CHOREVMA ARCHAION;So;0;L;;;;;N;;;;; +1D03C;BYZANTINE MUSICAL SYMBOL RAPISMA;So;0;L;;;;;N;;;;; +1D03D;BYZANTINE MUSICAL SYMBOL PARAKALESMA ARCHAION;So;0;L;;;;;N;;;;; +1D03E;BYZANTINE MUSICAL SYMBOL PARAKLITIKI ARCHAION;So;0;L;;;;;N;;;;; +1D03F;BYZANTINE MUSICAL SYMBOL ICHADIN;So;0;L;;;;;N;;;;; +1D040;BYZANTINE MUSICAL SYMBOL NANA;So;0;L;;;;;N;;;;; +1D041;BYZANTINE MUSICAL SYMBOL PETASMA;So;0;L;;;;;N;;;;; +1D042;BYZANTINE MUSICAL SYMBOL KONTEVMA ALLO;So;0;L;;;;;N;;;;; +1D043;BYZANTINE MUSICAL SYMBOL TROMIKON ALLO;So;0;L;;;;;N;;;;; +1D044;BYZANTINE MUSICAL SYMBOL STRAGGISMATA;So;0;L;;;;;N;;;;; +1D045;BYZANTINE MUSICAL SYMBOL GRONTHISMATA;So;0;L;;;;;N;;;;; +1D046;BYZANTINE MUSICAL SYMBOL ISON NEO;So;0;L;;;;;N;;;;; +1D047;BYZANTINE MUSICAL SYMBOL OLIGON NEO;So;0;L;;;;;N;;;;; +1D048;BYZANTINE MUSICAL SYMBOL OXEIA NEO;So;0;L;;;;;N;;;;; +1D049;BYZANTINE MUSICAL SYMBOL PETASTI;So;0;L;;;;;N;;;;; +1D04A;BYZANTINE MUSICAL SYMBOL KOUFISMA;So;0;L;;;;;N;;;;; +1D04B;BYZANTINE MUSICAL SYMBOL PETASTOKOUFISMA;So;0;L;;;;;N;;;;; +1D04C;BYZANTINE MUSICAL SYMBOL KRATIMOKOUFISMA;So;0;L;;;;;N;;;;; +1D04D;BYZANTINE MUSICAL SYMBOL PELASTON NEO;So;0;L;;;;;N;;;;; +1D04E;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO ANO;So;0;L;;;;;N;;;;; +1D04F;BYZANTINE MUSICAL SYMBOL KENTIMA NEO ANO;So;0;L;;;;;N;;;;; +1D050;BYZANTINE MUSICAL SYMBOL YPSILI;So;0;L;;;;;N;;;;; +1D051;BYZANTINE MUSICAL SYMBOL APOSTROFOS NEO;So;0;L;;;;;N;;;;; +1D052;BYZANTINE MUSICAL SYMBOL APOSTROFOI SYNDESMOS NEO;So;0;L;;;;;N;;;;; +1D053;BYZANTINE MUSICAL SYMBOL YPORROI;So;0;L;;;;;N;;;;; +1D054;BYZANTINE MUSICAL SYMBOL KRATIMOYPORROON;So;0;L;;;;;N;;;;; +1D055;BYZANTINE MUSICAL SYMBOL ELAFRON;So;0;L;;;;;N;;;;; +1D056;BYZANTINE MUSICAL SYMBOL CHAMILI;So;0;L;;;;;N;;;;; +1D057;BYZANTINE MUSICAL SYMBOL MIKRON ISON;So;0;L;;;;;N;;;;; +1D058;BYZANTINE MUSICAL SYMBOL VAREIA NEO;So;0;L;;;;;N;;;;; +1D059;BYZANTINE MUSICAL SYMBOL PIASMA NEO;So;0;L;;;;;N;;;;; +1D05A;BYZANTINE MUSICAL SYMBOL PSIFISTON NEO;So;0;L;;;;;N;;;;; +1D05B;BYZANTINE MUSICAL SYMBOL OMALON;So;0;L;;;;;N;;;;; +1D05C;BYZANTINE MUSICAL SYMBOL ANTIKENOMA;So;0;L;;;;;N;;;;; +1D05D;BYZANTINE MUSICAL SYMBOL LYGISMA;So;0;L;;;;;N;;;;; +1D05E;BYZANTINE MUSICAL SYMBOL PARAKLITIKI NEO;So;0;L;;;;;N;;;;; +1D05F;BYZANTINE MUSICAL SYMBOL PARAKALESMA NEO;So;0;L;;;;;N;;;;; +1D060;BYZANTINE MUSICAL SYMBOL ETERON PARAKALESMA;So;0;L;;;;;N;;;;; +1D061;BYZANTINE MUSICAL SYMBOL KYLISMA;So;0;L;;;;;N;;;;; +1D062;BYZANTINE MUSICAL SYMBOL ANTIKENOKYLISMA;So;0;L;;;;;N;;;;; +1D063;BYZANTINE MUSICAL SYMBOL TROMIKON NEO;So;0;L;;;;;N;;;;; +1D064;BYZANTINE MUSICAL SYMBOL EKSTREPTON;So;0;L;;;;;N;;;;; +1D065;BYZANTINE MUSICAL SYMBOL SYNAGMA NEO;So;0;L;;;;;N;;;;; +1D066;BYZANTINE MUSICAL SYMBOL SYRMA;So;0;L;;;;;N;;;;; +1D067;BYZANTINE MUSICAL SYMBOL CHOREVMA NEO;So;0;L;;;;;N;;;;; +1D068;BYZANTINE MUSICAL SYMBOL EPEGERMA;So;0;L;;;;;N;;;;; +1D069;BYZANTINE MUSICAL SYMBOL SEISMA NEO;So;0;L;;;;;N;;;;; +1D06A;BYZANTINE MUSICAL SYMBOL XIRON KLASMA;So;0;L;;;;;N;;;;; +1D06B;BYZANTINE MUSICAL SYMBOL TROMIKOPSIFISTON;So;0;L;;;;;N;;;;; +1D06C;BYZANTINE MUSICAL SYMBOL PSIFISTOLYGISMA;So;0;L;;;;;N;;;;; +1D06D;BYZANTINE MUSICAL SYMBOL TROMIKOLYGISMA;So;0;L;;;;;N;;;;; +1D06E;BYZANTINE MUSICAL SYMBOL TROMIKOPARAKALESMA;So;0;L;;;;;N;;;;; +1D06F;BYZANTINE MUSICAL SYMBOL PSIFISTOPARAKALESMA;So;0;L;;;;;N;;;;; +1D070;BYZANTINE MUSICAL SYMBOL TROMIKOSYNAGMA;So;0;L;;;;;N;;;;; +1D071;BYZANTINE MUSICAL SYMBOL PSIFISTOSYNAGMA;So;0;L;;;;;N;;;;; +1D072;BYZANTINE MUSICAL SYMBOL GORGOSYNTHETON;So;0;L;;;;;N;;;;; +1D073;BYZANTINE MUSICAL SYMBOL ARGOSYNTHETON;So;0;L;;;;;N;;;;; +1D074;BYZANTINE MUSICAL SYMBOL ETERON ARGOSYNTHETON;So;0;L;;;;;N;;;;; +1D075;BYZANTINE MUSICAL SYMBOL OYRANISMA NEO;So;0;L;;;;;N;;;;; +1D076;BYZANTINE MUSICAL SYMBOL THEMATISMOS ESO;So;0;L;;;;;N;;;;; +1D077;BYZANTINE MUSICAL SYMBOL THEMATISMOS EXO;So;0;L;;;;;N;;;;; +1D078;BYZANTINE MUSICAL SYMBOL THEMA APLOUN;So;0;L;;;;;N;;;;; +1D079;BYZANTINE MUSICAL SYMBOL THES KAI APOTHES;So;0;L;;;;;N;;;;; +1D07A;BYZANTINE MUSICAL SYMBOL KATAVASMA;So;0;L;;;;;N;;;;; +1D07B;BYZANTINE MUSICAL SYMBOL ENDOFONON;So;0;L;;;;;N;;;;; +1D07C;BYZANTINE MUSICAL SYMBOL YFEN KATO;So;0;L;;;;;N;;;;; +1D07D;BYZANTINE MUSICAL SYMBOL YFEN ANO;So;0;L;;;;;N;;;;; +1D07E;BYZANTINE MUSICAL SYMBOL STAVROS;So;0;L;;;;;N;;;;; +1D07F;BYZANTINE MUSICAL SYMBOL KLASMA ANO;So;0;L;;;;;N;;;;; +1D080;BYZANTINE MUSICAL SYMBOL DIPLI ARCHAION;So;0;L;;;;;N;;;;; +1D081;BYZANTINE MUSICAL SYMBOL KRATIMA ARCHAION;So;0;L;;;;;N;;;;; +1D082;BYZANTINE MUSICAL SYMBOL KRATIMA ALLO;So;0;L;;;;;N;;;;; +1D083;BYZANTINE MUSICAL SYMBOL KRATIMA NEO;So;0;L;;;;;N;;;;; +1D084;BYZANTINE MUSICAL SYMBOL APODERMA NEO;So;0;L;;;;;N;;;;; +1D085;BYZANTINE MUSICAL SYMBOL APLI;So;0;L;;;;;N;;;;; +1D086;BYZANTINE MUSICAL SYMBOL DIPLI;So;0;L;;;;;N;;;;; +1D087;BYZANTINE MUSICAL SYMBOL TRIPLI;So;0;L;;;;;N;;;;; +1D088;BYZANTINE MUSICAL SYMBOL TETRAPLI;So;0;L;;;;;N;;;;; +1D089;BYZANTINE MUSICAL SYMBOL KORONIS;So;0;L;;;;;N;;;;; +1D08A;BYZANTINE MUSICAL SYMBOL LEIMMA ENOS CHRONOU;So;0;L;;;;;N;;;;; +1D08B;BYZANTINE MUSICAL SYMBOL LEIMMA DYO CHRONON;So;0;L;;;;;N;;;;; +1D08C;BYZANTINE MUSICAL SYMBOL LEIMMA TRION CHRONON;So;0;L;;;;;N;;;;; +1D08D;BYZANTINE MUSICAL SYMBOL LEIMMA TESSARON CHRONON;So;0;L;;;;;N;;;;; +1D08E;BYZANTINE MUSICAL SYMBOL LEIMMA IMISEOS CHRONOU;So;0;L;;;;;N;;;;; +1D08F;BYZANTINE MUSICAL SYMBOL GORGON NEO ANO;So;0;L;;;;;N;;;;; +1D090;BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON ARISTERA;So;0;L;;;;;N;;;;; +1D091;BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON DEXIA;So;0;L;;;;;N;;;;; +1D092;BYZANTINE MUSICAL SYMBOL DIGORGON;So;0;L;;;;;N;;;;; +1D093;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA KATO;So;0;L;;;;;N;;;;; +1D094;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA ANO;So;0;L;;;;;N;;;;; +1D095;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON DEXIA;So;0;L;;;;;N;;;;; +1D096;BYZANTINE MUSICAL SYMBOL TRIGORGON;So;0;L;;;;;N;;;;; +1D097;BYZANTINE MUSICAL SYMBOL ARGON;So;0;L;;;;;N;;;;; +1D098;BYZANTINE MUSICAL SYMBOL IMIDIARGON;So;0;L;;;;;N;;;;; +1D099;BYZANTINE MUSICAL SYMBOL DIARGON;So;0;L;;;;;N;;;;; +1D09A;BYZANTINE MUSICAL SYMBOL AGOGI POLI ARGI;So;0;L;;;;;N;;;;; +1D09B;BYZANTINE MUSICAL SYMBOL AGOGI ARGOTERI;So;0;L;;;;;N;;;;; +1D09C;BYZANTINE MUSICAL SYMBOL AGOGI ARGI;So;0;L;;;;;N;;;;; +1D09D;BYZANTINE MUSICAL SYMBOL AGOGI METRIA;So;0;L;;;;;N;;;;; +1D09E;BYZANTINE MUSICAL SYMBOL AGOGI MESI;So;0;L;;;;;N;;;;; +1D09F;BYZANTINE MUSICAL SYMBOL AGOGI GORGI;So;0;L;;;;;N;;;;; +1D0A0;BYZANTINE MUSICAL SYMBOL AGOGI GORGOTERI;So;0;L;;;;;N;;;;; +1D0A1;BYZANTINE MUSICAL SYMBOL AGOGI POLI GORGI;So;0;L;;;;;N;;;;; +1D0A2;BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOS ICHOS;So;0;L;;;;;N;;;;; +1D0A3;BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI PROTOS ICHOS;So;0;L;;;;;N;;;;; +1D0A4;BYZANTINE MUSICAL SYMBOL MARTYRIA DEYTEROS ICHOS;So;0;L;;;;;N;;;;; +1D0A5;BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI DEYTEROS ICHOS;So;0;L;;;;;N;;;;; +1D0A6;BYZANTINE MUSICAL SYMBOL MARTYRIA TRITOS ICHOS;So;0;L;;;;;N;;;;; +1D0A7;BYZANTINE MUSICAL SYMBOL MARTYRIA TRIFONIAS;So;0;L;;;;;N;;;;; +1D0A8;BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS ICHOS;So;0;L;;;;;N;;;;; +1D0A9;BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS LEGETOS ICHOS;So;0;L;;;;;N;;;;; +1D0AA;BYZANTINE MUSICAL SYMBOL MARTYRIA LEGETOS ICHOS;So;0;L;;;;;N;;;;; +1D0AB;BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS ICHOS;So;0;L;;;;;N;;;;; +1D0AC;BYZANTINE MUSICAL SYMBOL ISAKIA TELOUS ICHIMATOS;So;0;L;;;;;N;;;;; +1D0AD;BYZANTINE MUSICAL SYMBOL APOSTROFOI TELOUS ICHIMATOS;So;0;L;;;;;N;;;;; +1D0AE;BYZANTINE MUSICAL SYMBOL FANEROSIS TETRAFONIAS;So;0;L;;;;;N;;;;; +1D0AF;BYZANTINE MUSICAL SYMBOL FANEROSIS MONOFONIAS;So;0;L;;;;;N;;;;; +1D0B0;BYZANTINE MUSICAL SYMBOL FANEROSIS DIFONIAS;So;0;L;;;;;N;;;;; +1D0B1;BYZANTINE MUSICAL SYMBOL MARTYRIA VARYS ICHOS;So;0;L;;;;;N;;;;; +1D0B2;BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOVARYS ICHOS;So;0;L;;;;;N;;;;; +1D0B3;BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS TETARTOS ICHOS;So;0;L;;;;;N;;;;; +1D0B4;BYZANTINE MUSICAL SYMBOL GORTHMIKON N APLOUN;So;0;L;;;;;N;;;;; +1D0B5;BYZANTINE MUSICAL SYMBOL GORTHMIKON N DIPLOUN;So;0;L;;;;;N;;;;; +1D0B6;BYZANTINE MUSICAL SYMBOL ENARXIS KAI FTHORA VOU;So;0;L;;;;;N;;;;; +1D0B7;BYZANTINE MUSICAL SYMBOL IMIFONON;So;0;L;;;;;N;;;;; +1D0B8;BYZANTINE MUSICAL SYMBOL IMIFTHORON;So;0;L;;;;;N;;;;; +1D0B9;BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION DEYTEROU ICHOU;So;0;L;;;;;N;;;;; +1D0BA;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI PA;So;0;L;;;;;N;;;;; +1D0BB;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NANA;So;0;L;;;;;N;;;;; +1D0BC;BYZANTINE MUSICAL SYMBOL FTHORA NAOS ICHOS;So;0;L;;;;;N;;;;; +1D0BD;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI DI;So;0;L;;;;;N;;;;; +1D0BE;BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON DIATONON DI;So;0;L;;;;;N;;;;; +1D0BF;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI KE;So;0;L;;;;;N;;;;; +1D0C0;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI ZO;So;0;L;;;;;N;;;;; +1D0C1;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI KATO;So;0;L;;;;;N;;;;; +1D0C2;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI ANO;So;0;L;;;;;N;;;;; +1D0C3;BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA DIFONIAS;So;0;L;;;;;N;;;;; +1D0C4;BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA MONOFONIAS;So;0;L;;;;;N;;;;; +1D0C5;BYZANTINE MUSICAL SYMBOL FHTORA SKLIRON CHROMA VASIS;So;0;L;;;;;N;;;;; +1D0C6;BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON CHROMA SYNAFI;So;0;L;;;;;N;;;;; +1D0C7;BYZANTINE MUSICAL SYMBOL FTHORA NENANO;So;0;L;;;;;N;;;;; +1D0C8;BYZANTINE MUSICAL SYMBOL CHROA ZYGOS;So;0;L;;;;;N;;;;; +1D0C9;BYZANTINE MUSICAL SYMBOL CHROA KLITON;So;0;L;;;;;N;;;;; +1D0CA;BYZANTINE MUSICAL SYMBOL CHROA SPATHI;So;0;L;;;;;N;;;;; +1D0CB;BYZANTINE MUSICAL SYMBOL FTHORA I YFESIS TETARTIMORION;So;0;L;;;;;N;;;;; +1D0CC;BYZANTINE MUSICAL SYMBOL FTHORA ENARMONIOS ANTIFONIA;So;0;L;;;;;N;;;;; +1D0CD;BYZANTINE MUSICAL SYMBOL YFESIS TRITIMORION;So;0;L;;;;;N;;;;; +1D0CE;BYZANTINE MUSICAL SYMBOL DIESIS TRITIMORION;So;0;L;;;;;N;;;;; +1D0CF;BYZANTINE MUSICAL SYMBOL DIESIS TETARTIMORION;So;0;L;;;;;N;;;;; +1D0D0;BYZANTINE MUSICAL SYMBOL DIESIS APLI DYO DODEKATA;So;0;L;;;;;N;;;;; +1D0D1;BYZANTINE MUSICAL SYMBOL DIESIS MONOGRAMMOS TESSERA DODEKATA;So;0;L;;;;;N;;;;; +1D0D2;BYZANTINE MUSICAL SYMBOL DIESIS DIGRAMMOS EX DODEKATA;So;0;L;;;;;N;;;;; +1D0D3;BYZANTINE MUSICAL SYMBOL DIESIS TRIGRAMMOS OKTO DODEKATA;So;0;L;;;;;N;;;;; +1D0D4;BYZANTINE MUSICAL SYMBOL YFESIS APLI DYO DODEKATA;So;0;L;;;;;N;;;;; +1D0D5;BYZANTINE MUSICAL SYMBOL YFESIS MONOGRAMMOS TESSERA DODEKATA;So;0;L;;;;;N;;;;; +1D0D6;BYZANTINE MUSICAL SYMBOL YFESIS DIGRAMMOS EX DODEKATA;So;0;L;;;;;N;;;;; +1D0D7;BYZANTINE MUSICAL SYMBOL YFESIS TRIGRAMMOS OKTO DODEKATA;So;0;L;;;;;N;;;;; +1D0D8;BYZANTINE MUSICAL SYMBOL GENIKI DIESIS;So;0;L;;;;;N;;;;; +1D0D9;BYZANTINE MUSICAL SYMBOL GENIKI YFESIS;So;0;L;;;;;N;;;;; +1D0DA;BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MIKRI;So;0;L;;;;;N;;;;; +1D0DB;BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MEGALI;So;0;L;;;;;N;;;;; +1D0DC;BYZANTINE MUSICAL SYMBOL DIASTOLI DIPLI;So;0;L;;;;;N;;;;; +1D0DD;BYZANTINE MUSICAL SYMBOL DIASTOLI THESEOS;So;0;L;;;;;N;;;;; +1D0DE;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS;So;0;L;;;;;N;;;;; +1D0DF;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS DISIMOU;So;0;L;;;;;N;;;;; +1D0E0;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TRISIMOU;So;0;L;;;;;N;;;;; +1D0E1;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TETRASIMOU;So;0;L;;;;;N;;;;; +1D0E2;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS;So;0;L;;;;;N;;;;; +1D0E3;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS DISIMOU;So;0;L;;;;;N;;;;; +1D0E4;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TRISIMOU;So;0;L;;;;;N;;;;; +1D0E5;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TETRASIMOU;So;0;L;;;;;N;;;;; +1D0E6;BYZANTINE MUSICAL SYMBOL DIGRAMMA GG;So;0;L;;;;;N;;;;; +1D0E7;BYZANTINE MUSICAL SYMBOL DIFTOGGOS OU;So;0;L;;;;;N;;;;; +1D0E8;BYZANTINE MUSICAL SYMBOL STIGMA;So;0;L;;;;;N;;;;; +1D0E9;BYZANTINE MUSICAL SYMBOL ARKTIKO PA;So;0;L;;;;;N;;;;; +1D0EA;BYZANTINE MUSICAL SYMBOL ARKTIKO VOU;So;0;L;;;;;N;;;;; +1D0EB;BYZANTINE MUSICAL SYMBOL ARKTIKO GA;So;0;L;;;;;N;;;;; +1D0EC;BYZANTINE MUSICAL SYMBOL ARKTIKO DI;So;0;L;;;;;N;;;;; +1D0ED;BYZANTINE MUSICAL SYMBOL ARKTIKO KE;So;0;L;;;;;N;;;;; +1D0EE;BYZANTINE MUSICAL SYMBOL ARKTIKO ZO;So;0;L;;;;;N;;;;; +1D0EF;BYZANTINE MUSICAL SYMBOL ARKTIKO NI;So;0;L;;;;;N;;;;; +1D0F0;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO MESO;So;0;L;;;;;N;;;;; +1D0F1;BYZANTINE MUSICAL SYMBOL KENTIMA NEO MESO;So;0;L;;;;;N;;;;; +1D0F2;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO KATO;So;0;L;;;;;N;;;;; +1D0F3;BYZANTINE MUSICAL SYMBOL KENTIMA NEO KATO;So;0;L;;;;;N;;;;; +1D0F4;BYZANTINE MUSICAL SYMBOL KLASMA KATO;So;0;L;;;;;N;;;;; +1D0F5;BYZANTINE MUSICAL SYMBOL GORGON NEO KATO;So;0;L;;;;;N;;;;; +1D100;MUSICAL SYMBOL SINGLE BARLINE;So;0;L;;;;;N;;;;; +1D101;MUSICAL SYMBOL DOUBLE BARLINE;So;0;L;;;;;N;;;;; +1D102;MUSICAL SYMBOL FINAL BARLINE;So;0;L;;;;;N;;;;; +1D103;MUSICAL SYMBOL REVERSE FINAL BARLINE;So;0;L;;;;;N;;;;; +1D104;MUSICAL SYMBOL DASHED BARLINE;So;0;L;;;;;N;;;;; +1D105;MUSICAL SYMBOL SHORT BARLINE;So;0;L;;;;;N;;;;; +1D106;MUSICAL SYMBOL LEFT REPEAT SIGN;So;0;L;;;;;N;;;;; +1D107;MUSICAL SYMBOL RIGHT REPEAT SIGN;So;0;L;;;;;N;;;;; +1D108;MUSICAL SYMBOL REPEAT DOTS;So;0;L;;;;;N;;;;; +1D109;MUSICAL SYMBOL DAL SEGNO;So;0;L;;;;;N;;;;; +1D10A;MUSICAL SYMBOL DA CAPO;So;0;L;;;;;N;;;;; +1D10B;MUSICAL SYMBOL SEGNO;So;0;L;;;;;N;;;;; +1D10C;MUSICAL SYMBOL CODA;So;0;L;;;;;N;;;;; +1D10D;MUSICAL SYMBOL REPEATED FIGURE-1;So;0;L;;;;;N;;;;; +1D10E;MUSICAL SYMBOL REPEATED FIGURE-2;So;0;L;;;;;N;;;;; +1D10F;MUSICAL SYMBOL REPEATED FIGURE-3;So;0;L;;;;;N;;;;; +1D110;MUSICAL SYMBOL FERMATA;So;0;L;;;;;N;;;;; +1D111;MUSICAL SYMBOL FERMATA BELOW;So;0;L;;;;;N;;;;; +1D112;MUSICAL SYMBOL BREATH MARK;So;0;L;;;;;N;;;;; +1D113;MUSICAL SYMBOL CAESURA;So;0;L;;;;;N;;;;; +1D114;MUSICAL SYMBOL BRACE;So;0;L;;;;;N;;;;; +1D115;MUSICAL SYMBOL BRACKET;So;0;L;;;;;N;;;;; +1D116;MUSICAL SYMBOL ONE-LINE STAFF;So;0;L;;;;;N;;;;; +1D117;MUSICAL SYMBOL TWO-LINE STAFF;So;0;L;;;;;N;;;;; +1D118;MUSICAL SYMBOL THREE-LINE STAFF;So;0;L;;;;;N;;;;; +1D119;MUSICAL SYMBOL FOUR-LINE STAFF;So;0;L;;;;;N;;;;; +1D11A;MUSICAL SYMBOL FIVE-LINE STAFF;So;0;L;;;;;N;;;;; +1D11B;MUSICAL SYMBOL SIX-LINE STAFF;So;0;L;;;;;N;;;;; +1D11C;MUSICAL SYMBOL SIX-STRING FRETBOARD;So;0;L;;;;;N;;;;; +1D11D;MUSICAL SYMBOL FOUR-STRING FRETBOARD;So;0;L;;;;;N;;;;; +1D11E;MUSICAL SYMBOL G CLEF;So;0;L;;;;;N;;;;; +1D11F;MUSICAL SYMBOL G CLEF OTTAVA ALTA;So;0;L;;;;;N;;;;; +1D120;MUSICAL SYMBOL G CLEF OTTAVA BASSA;So;0;L;;;;;N;;;;; +1D121;MUSICAL SYMBOL C CLEF;So;0;L;;;;;N;;;;; +1D122;MUSICAL SYMBOL F CLEF;So;0;L;;;;;N;;;;; +1D123;MUSICAL SYMBOL F CLEF OTTAVA ALTA;So;0;L;;;;;N;;;;; +1D124;MUSICAL SYMBOL F CLEF OTTAVA BASSA;So;0;L;;;;;N;;;;; +1D125;MUSICAL SYMBOL DRUM CLEF-1;So;0;L;;;;;N;;;;; +1D126;MUSICAL SYMBOL DRUM CLEF-2;So;0;L;;;;;N;;;;; +1D12A;MUSICAL SYMBOL DOUBLE SHARP;So;0;L;;;;;N;;;;; +1D12B;MUSICAL SYMBOL DOUBLE FLAT;So;0;L;;;;;N;;;;; +1D12C;MUSICAL SYMBOL FLAT UP;So;0;L;;;;;N;;;;; +1D12D;MUSICAL SYMBOL FLAT DOWN;So;0;L;;;;;N;;;;; +1D12E;MUSICAL SYMBOL NATURAL UP;So;0;L;;;;;N;;;;; +1D12F;MUSICAL SYMBOL NATURAL DOWN;So;0;L;;;;;N;;;;; +1D130;MUSICAL SYMBOL SHARP UP;So;0;L;;;;;N;;;;; +1D131;MUSICAL SYMBOL SHARP DOWN;So;0;L;;;;;N;;;;; +1D132;MUSICAL SYMBOL QUARTER TONE SHARP;So;0;L;;;;;N;;;;; +1D133;MUSICAL SYMBOL QUARTER TONE FLAT;So;0;L;;;;;N;;;;; +1D134;MUSICAL SYMBOL COMMON TIME;So;0;L;;;;;N;;;;; +1D135;MUSICAL SYMBOL CUT TIME;So;0;L;;;;;N;;;;; +1D136;MUSICAL SYMBOL OTTAVA ALTA;So;0;L;;;;;N;;;;; +1D137;MUSICAL SYMBOL OTTAVA BASSA;So;0;L;;;;;N;;;;; +1D138;MUSICAL SYMBOL QUINDICESIMA ALTA;So;0;L;;;;;N;;;;; +1D139;MUSICAL SYMBOL QUINDICESIMA BASSA;So;0;L;;;;;N;;;;; +1D13A;MUSICAL SYMBOL MULTI REST;So;0;L;;;;;N;;;;; +1D13B;MUSICAL SYMBOL WHOLE REST;So;0;L;;;;;N;;;;; +1D13C;MUSICAL SYMBOL HALF REST;So;0;L;;;;;N;;;;; +1D13D;MUSICAL SYMBOL QUARTER REST;So;0;L;;;;;N;;;;; +1D13E;MUSICAL SYMBOL EIGHTH REST;So;0;L;;;;;N;;;;; +1D13F;MUSICAL SYMBOL SIXTEENTH REST;So;0;L;;;;;N;;;;; +1D140;MUSICAL SYMBOL THIRTY-SECOND REST;So;0;L;;;;;N;;;;; +1D141;MUSICAL SYMBOL SIXTY-FOURTH REST;So;0;L;;;;;N;;;;; +1D142;MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH REST;So;0;L;;;;;N;;;;; +1D143;MUSICAL SYMBOL X NOTEHEAD;So;0;L;;;;;N;;;;; +1D144;MUSICAL SYMBOL PLUS NOTEHEAD;So;0;L;;;;;N;;;;; +1D145;MUSICAL SYMBOL CIRCLE X NOTEHEAD;So;0;L;;;;;N;;;;; +1D146;MUSICAL SYMBOL SQUARE NOTEHEAD WHITE;So;0;L;;;;;N;;;;; +1D147;MUSICAL SYMBOL SQUARE NOTEHEAD BLACK;So;0;L;;;;;N;;;;; +1D148;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP WHITE;So;0;L;;;;;N;;;;; +1D149;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP BLACK;So;0;L;;;;;N;;;;; +1D14A;MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT WHITE;So;0;L;;;;;N;;;;; +1D14B;MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT BLACK;So;0;L;;;;;N;;;;; +1D14C;MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT WHITE;So;0;L;;;;;N;;;;; +1D14D;MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT BLACK;So;0;L;;;;;N;;;;; +1D14E;MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN WHITE;So;0;L;;;;;N;;;;; +1D14F;MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN BLACK;So;0;L;;;;;N;;;;; +1D150;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT WHITE;So;0;L;;;;;N;;;;; +1D151;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT BLACK;So;0;L;;;;;N;;;;; +1D152;MUSICAL SYMBOL MOON NOTEHEAD WHITE;So;0;L;;;;;N;;;;; +1D153;MUSICAL SYMBOL MOON NOTEHEAD BLACK;So;0;L;;;;;N;;;;; +1D154;MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN WHITE;So;0;L;;;;;N;;;;; +1D155;MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN BLACK;So;0;L;;;;;N;;;;; +1D156;MUSICAL SYMBOL PARENTHESIS NOTEHEAD;So;0;L;;;;;N;;;;; +1D157;MUSICAL SYMBOL VOID NOTEHEAD;So;0;L;;;;;N;;;;; +1D158;MUSICAL SYMBOL NOTEHEAD BLACK;So;0;L;;;;;N;;;;; +1D159;MUSICAL SYMBOL NULL NOTEHEAD;So;0;L;;;;;N;;;;; +1D15A;MUSICAL SYMBOL CLUSTER NOTEHEAD WHITE;So;0;L;;;;;N;;;;; +1D15B;MUSICAL SYMBOL CLUSTER NOTEHEAD BLACK;So;0;L;;;;;N;;;;; +1D15C;MUSICAL SYMBOL BREVE;So;0;L;;;;;N;;;;; +1D15D;MUSICAL SYMBOL WHOLE NOTE;So;0;L;;;;;N;;;;; +1D15E;MUSICAL SYMBOL HALF NOTE;So;0;L;1D157 1D165;;;;N;;;;; +1D15F;MUSICAL SYMBOL QUARTER NOTE;So;0;L;1D158 1D165;;;;N;;;;; +1D160;MUSICAL SYMBOL EIGHTH NOTE;So;0;L;1D15F 1D16E;;;;N;;;;; +1D161;MUSICAL SYMBOL SIXTEENTH NOTE;So;0;L;1D15F 1D16F;;;;N;;;;; +1D162;MUSICAL SYMBOL THIRTY-SECOND NOTE;So;0;L;1D15F 1D170;;;;N;;;;; +1D163;MUSICAL SYMBOL SIXTY-FOURTH NOTE;So;0;L;1D15F 1D171;;;;N;;;;; +1D164;MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE;So;0;L;1D15F 1D172;;;;N;;;;; +1D165;MUSICAL SYMBOL COMBINING STEM;Mc;216;L;;;;;N;;;;; +1D166;MUSICAL SYMBOL COMBINING SPRECHGESANG STEM;Mc;216;L;;;;;N;;;;; +1D167;MUSICAL SYMBOL COMBINING TREMOLO-1;Mn;1;NSM;;;;;N;;;;; +1D168;MUSICAL SYMBOL COMBINING TREMOLO-2;Mn;1;NSM;;;;;N;;;;; +1D169;MUSICAL SYMBOL COMBINING TREMOLO-3;Mn;1;NSM;;;;;N;;;;; +1D16A;MUSICAL SYMBOL FINGERED TREMOLO-1;So;0;L;;;;;N;;;;; +1D16B;MUSICAL SYMBOL FINGERED TREMOLO-2;So;0;L;;;;;N;;;;; +1D16C;MUSICAL SYMBOL FINGERED TREMOLO-3;So;0;L;;;;;N;;;;; +1D16D;MUSICAL SYMBOL COMBINING AUGMENTATION DOT;Mc;226;L;;;;;N;;;;; +1D16E;MUSICAL SYMBOL COMBINING FLAG-1;Mc;216;L;;;;;N;;;;; +1D16F;MUSICAL SYMBOL COMBINING FLAG-2;Mc;216;L;;;;;N;;;;; +1D170;MUSICAL SYMBOL COMBINING FLAG-3;Mc;216;L;;;;;N;;;;; +1D171;MUSICAL SYMBOL COMBINING FLAG-4;Mc;216;L;;;;;N;;;;; +1D172;MUSICAL SYMBOL COMBINING FLAG-5;Mc;216;L;;;;;N;;;;; +1D173;MUSICAL SYMBOL BEGIN BEAM;Cf;0;BN;;;;;N;;;;; +1D174;MUSICAL SYMBOL END BEAM;Cf;0;BN;;;;;N;;;;; +1D175;MUSICAL SYMBOL BEGIN TIE;Cf;0;BN;;;;;N;;;;; +1D176;MUSICAL SYMBOL END TIE;Cf;0;BN;;;;;N;;;;; +1D177;MUSICAL SYMBOL BEGIN SLUR;Cf;0;BN;;;;;N;;;;; +1D178;MUSICAL SYMBOL END SLUR;Cf;0;BN;;;;;N;;;;; +1D179;MUSICAL SYMBOL BEGIN PHRASE;Cf;0;BN;;;;;N;;;;; +1D17A;MUSICAL SYMBOL END PHRASE;Cf;0;BN;;;;;N;;;;; +1D17B;MUSICAL SYMBOL COMBINING ACCENT;Mn;220;NSM;;;;;N;;;;; +1D17C;MUSICAL SYMBOL COMBINING STACCATO;Mn;220;NSM;;;;;N;;;;; +1D17D;MUSICAL SYMBOL COMBINING TENUTO;Mn;220;NSM;;;;;N;;;;; +1D17E;MUSICAL SYMBOL COMBINING STACCATISSIMO;Mn;220;NSM;;;;;N;;;;; +1D17F;MUSICAL SYMBOL COMBINING MARCATO;Mn;220;NSM;;;;;N;;;;; +1D180;MUSICAL SYMBOL COMBINING MARCATO-STACCATO;Mn;220;NSM;;;;;N;;;;; +1D181;MUSICAL SYMBOL COMBINING ACCENT-STACCATO;Mn;220;NSM;;;;;N;;;;; +1D182;MUSICAL SYMBOL COMBINING LOURE;Mn;220;NSM;;;;;N;;;;; +1D183;MUSICAL SYMBOL ARPEGGIATO UP;So;0;L;;;;;N;;;;; +1D184;MUSICAL SYMBOL ARPEGGIATO DOWN;So;0;L;;;;;N;;;;; +1D185;MUSICAL SYMBOL COMBINING DOIT;Mn;230;NSM;;;;;N;;;;; +1D186;MUSICAL SYMBOL COMBINING RIP;Mn;230;NSM;;;;;N;;;;; +1D187;MUSICAL SYMBOL COMBINING FLIP;Mn;230;NSM;;;;;N;;;;; +1D188;MUSICAL SYMBOL COMBINING SMEAR;Mn;230;NSM;;;;;N;;;;; +1D189;MUSICAL SYMBOL COMBINING BEND;Mn;230;NSM;;;;;N;;;;; +1D18A;MUSICAL SYMBOL COMBINING DOUBLE TONGUE;Mn;220;NSM;;;;;N;;;;; +1D18B;MUSICAL SYMBOL COMBINING TRIPLE TONGUE;Mn;220;NSM;;;;;N;;;;; +1D18C;MUSICAL SYMBOL RINFORZANDO;So;0;L;;;;;N;;;;; +1D18D;MUSICAL SYMBOL SUBITO;So;0;L;;;;;N;;;;; +1D18E;MUSICAL SYMBOL Z;So;0;L;;;;;N;;;;; +1D18F;MUSICAL SYMBOL PIANO;So;0;L;;;;;N;;;;; +1D190;MUSICAL SYMBOL MEZZO;So;0;L;;;;;N;;;;; +1D191;MUSICAL SYMBOL FORTE;So;0;L;;;;;N;;;;; +1D192;MUSICAL SYMBOL CRESCENDO;So;0;L;;;;;N;;;;; +1D193;MUSICAL SYMBOL DECRESCENDO;So;0;L;;;;;N;;;;; +1D194;MUSICAL SYMBOL GRACE NOTE SLASH;So;0;L;;;;;N;;;;; +1D195;MUSICAL SYMBOL GRACE NOTE NO SLASH;So;0;L;;;;;N;;;;; +1D196;MUSICAL SYMBOL TR;So;0;L;;;;;N;;;;; +1D197;MUSICAL SYMBOL TURN;So;0;L;;;;;N;;;;; +1D198;MUSICAL SYMBOL INVERTED TURN;So;0;L;;;;;N;;;;; +1D199;MUSICAL SYMBOL TURN SLASH;So;0;L;;;;;N;;;;; +1D19A;MUSICAL SYMBOL TURN UP;So;0;L;;;;;N;;;;; +1D19B;MUSICAL SYMBOL ORNAMENT STROKE-1;So;0;L;;;;;N;;;;; +1D19C;MUSICAL SYMBOL ORNAMENT STROKE-2;So;0;L;;;;;N;;;;; +1D19D;MUSICAL SYMBOL ORNAMENT STROKE-3;So;0;L;;;;;N;;;;; +1D19E;MUSICAL SYMBOL ORNAMENT STROKE-4;So;0;L;;;;;N;;;;; +1D19F;MUSICAL SYMBOL ORNAMENT STROKE-5;So;0;L;;;;;N;;;;; +1D1A0;MUSICAL SYMBOL ORNAMENT STROKE-6;So;0;L;;;;;N;;;;; +1D1A1;MUSICAL SYMBOL ORNAMENT STROKE-7;So;0;L;;;;;N;;;;; +1D1A2;MUSICAL SYMBOL ORNAMENT STROKE-8;So;0;L;;;;;N;;;;; +1D1A3;MUSICAL SYMBOL ORNAMENT STROKE-9;So;0;L;;;;;N;;;;; +1D1A4;MUSICAL SYMBOL ORNAMENT STROKE-10;So;0;L;;;;;N;;;;; +1D1A5;MUSICAL SYMBOL ORNAMENT STROKE-11;So;0;L;;;;;N;;;;; +1D1A6;MUSICAL SYMBOL HAUPTSTIMME;So;0;L;;;;;N;;;;; +1D1A7;MUSICAL SYMBOL NEBENSTIMME;So;0;L;;;;;N;;;;; +1D1A8;MUSICAL SYMBOL END OF STIMME;So;0;L;;;;;N;;;;; +1D1A9;MUSICAL SYMBOL DEGREE SLASH;So;0;L;;;;;N;;;;; +1D1AA;MUSICAL SYMBOL COMBINING DOWN BOW;Mn;230;NSM;;;;;N;;;;; +1D1AB;MUSICAL SYMBOL COMBINING UP BOW;Mn;230;NSM;;;;;N;;;;; +1D1AC;MUSICAL SYMBOL COMBINING HARMONIC;Mn;230;NSM;;;;;N;;;;; +1D1AD;MUSICAL SYMBOL COMBINING SNAP PIZZICATO;Mn;230;NSM;;;;;N;;;;; +1D1AE;MUSICAL SYMBOL PEDAL MARK;So;0;L;;;;;N;;;;; +1D1AF;MUSICAL SYMBOL PEDAL UP MARK;So;0;L;;;;;N;;;;; +1D1B0;MUSICAL SYMBOL HALF PEDAL MARK;So;0;L;;;;;N;;;;; +1D1B1;MUSICAL SYMBOL GLISSANDO UP;So;0;L;;;;;N;;;;; +1D1B2;MUSICAL SYMBOL GLISSANDO DOWN;So;0;L;;;;;N;;;;; +1D1B3;MUSICAL SYMBOL WITH FINGERNAILS;So;0;L;;;;;N;;;;; +1D1B4;MUSICAL SYMBOL DAMP;So;0;L;;;;;N;;;;; +1D1B5;MUSICAL SYMBOL DAMP ALL;So;0;L;;;;;N;;;;; +1D1B6;MUSICAL SYMBOL MAXIMA;So;0;L;;;;;N;;;;; +1D1B7;MUSICAL SYMBOL LONGA;So;0;L;;;;;N;;;;; +1D1B8;MUSICAL SYMBOL BREVIS;So;0;L;;;;;N;;;;; +1D1B9;MUSICAL SYMBOL SEMIBREVIS WHITE;So;0;L;;;;;N;;;;; +1D1BA;MUSICAL SYMBOL SEMIBREVIS BLACK;So;0;L;;;;;N;;;;; +1D1BB;MUSICAL SYMBOL MINIMA;So;0;L;1D1B9 1D165;;;;N;;;;; +1D1BC;MUSICAL SYMBOL MINIMA BLACK;So;0;L;1D1BA 1D165;;;;N;;;;; +1D1BD;MUSICAL SYMBOL SEMIMINIMA WHITE;So;0;L;1D1BB 1D16E;;;;N;;;;; +1D1BE;MUSICAL SYMBOL SEMIMINIMA BLACK;So;0;L;1D1BC 1D16E;;;;N;;;;; +1D1BF;MUSICAL SYMBOL FUSA WHITE;So;0;L;1D1BB 1D16F;;;;N;;;;; +1D1C0;MUSICAL SYMBOL FUSA BLACK;So;0;L;1D1BC 1D16F;;;;N;;;;; +1D1C1;MUSICAL SYMBOL LONGA PERFECTA REST;So;0;L;;;;;N;;;;; +1D1C2;MUSICAL SYMBOL LONGA IMPERFECTA REST;So;0;L;;;;;N;;;;; +1D1C3;MUSICAL SYMBOL BREVIS REST;So;0;L;;;;;N;;;;; +1D1C4;MUSICAL SYMBOL SEMIBREVIS REST;So;0;L;;;;;N;;;;; +1D1C5;MUSICAL SYMBOL MINIMA REST;So;0;L;;;;;N;;;;; +1D1C6;MUSICAL SYMBOL SEMIMINIMA REST;So;0;L;;;;;N;;;;; +1D1C7;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA;So;0;L;;;;;N;;;;; +1D1C8;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE IMPERFECTA;So;0;L;;;;;N;;;;; +1D1C9;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA DIMINUTION-1;So;0;L;;;;;N;;;;; +1D1CA;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE PERFECTA;So;0;L;;;;;N;;;;; +1D1CB;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA;So;0;L;;;;;N;;;;; +1D1CC;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-1;So;0;L;;;;;N;;;;; +1D1CD;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-2;So;0;L;;;;;N;;;;; +1D1CE;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-3;So;0;L;;;;;N;;;;; +1D1CF;MUSICAL SYMBOL CROIX;So;0;L;;;;;N;;;;; +1D1D0;MUSICAL SYMBOL GREGORIAN C CLEF;So;0;L;;;;;N;;;;; +1D1D1;MUSICAL SYMBOL GREGORIAN F CLEF;So;0;L;;;;;N;;;;; +1D1D2;MUSICAL SYMBOL SQUARE B;So;0;L;;;;;N;;;;; +1D1D3;MUSICAL SYMBOL VIRGA;So;0;L;;;;;N;;;;; +1D1D4;MUSICAL SYMBOL PODATUS;So;0;L;;;;;N;;;;; +1D1D5;MUSICAL SYMBOL CLIVIS;So;0;L;;;;;N;;;;; +1D1D6;MUSICAL SYMBOL SCANDICUS;So;0;L;;;;;N;;;;; +1D1D7;MUSICAL SYMBOL CLIMACUS;So;0;L;;;;;N;;;;; +1D1D8;MUSICAL SYMBOL TORCULUS;So;0;L;;;;;N;;;;; +1D1D9;MUSICAL SYMBOL PORRECTUS;So;0;L;;;;;N;;;;; +1D1DA;MUSICAL SYMBOL PORRECTUS FLEXUS;So;0;L;;;;;N;;;;; +1D1DB;MUSICAL SYMBOL SCANDICUS FLEXUS;So;0;L;;;;;N;;;;; +1D1DC;MUSICAL SYMBOL TORCULUS RESUPINUS;So;0;L;;;;;N;;;;; +1D1DD;MUSICAL SYMBOL PES SUBPUNCTIS;So;0;L;;;;;N;;;;; +1D400;MATHEMATICAL BOLD CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D401;MATHEMATICAL BOLD CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D402;MATHEMATICAL BOLD CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D403;MATHEMATICAL BOLD CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D404;MATHEMATICAL BOLD CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D405;MATHEMATICAL BOLD CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D406;MATHEMATICAL BOLD CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D407;MATHEMATICAL BOLD CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D408;MATHEMATICAL BOLD CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D409;MATHEMATICAL BOLD CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D40A;MATHEMATICAL BOLD CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D40B;MATHEMATICAL BOLD CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D40C;MATHEMATICAL BOLD CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D40D;MATHEMATICAL BOLD CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D40E;MATHEMATICAL BOLD CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D40F;MATHEMATICAL BOLD CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D410;MATHEMATICAL BOLD CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D411;MATHEMATICAL BOLD CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D412;MATHEMATICAL BOLD CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D413;MATHEMATICAL BOLD CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D414;MATHEMATICAL BOLD CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D415;MATHEMATICAL BOLD CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D416;MATHEMATICAL BOLD CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D417;MATHEMATICAL BOLD CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D418;MATHEMATICAL BOLD CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D419;MATHEMATICAL BOLD CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D41A;MATHEMATICAL BOLD SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D41B;MATHEMATICAL BOLD SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D41C;MATHEMATICAL BOLD SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D41D;MATHEMATICAL BOLD SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D41E;MATHEMATICAL BOLD SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D41F;MATHEMATICAL BOLD SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D420;MATHEMATICAL BOLD SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D421;MATHEMATICAL BOLD SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D422;MATHEMATICAL BOLD SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D423;MATHEMATICAL BOLD SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D424;MATHEMATICAL BOLD SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D425;MATHEMATICAL BOLD SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D426;MATHEMATICAL BOLD SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D427;MATHEMATICAL BOLD SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D428;MATHEMATICAL BOLD SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D429;MATHEMATICAL BOLD SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D42A;MATHEMATICAL BOLD SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D42B;MATHEMATICAL BOLD SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D42C;MATHEMATICAL BOLD SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D42D;MATHEMATICAL BOLD SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D42E;MATHEMATICAL BOLD SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D42F;MATHEMATICAL BOLD SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D430;MATHEMATICAL BOLD SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D431;MATHEMATICAL BOLD SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D432;MATHEMATICAL BOLD SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D433;MATHEMATICAL BOLD SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D434;MATHEMATICAL ITALIC CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D435;MATHEMATICAL ITALIC CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D436;MATHEMATICAL ITALIC CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D437;MATHEMATICAL ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D438;MATHEMATICAL ITALIC CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D439;MATHEMATICAL ITALIC CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D43A;MATHEMATICAL ITALIC CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D43B;MATHEMATICAL ITALIC CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D43C;MATHEMATICAL ITALIC CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D43D;MATHEMATICAL ITALIC CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D43E;MATHEMATICAL ITALIC CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D43F;MATHEMATICAL ITALIC CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D440;MATHEMATICAL ITALIC CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D441;MATHEMATICAL ITALIC CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D442;MATHEMATICAL ITALIC CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D443;MATHEMATICAL ITALIC CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D444;MATHEMATICAL ITALIC CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D445;MATHEMATICAL ITALIC CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D446;MATHEMATICAL ITALIC CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D447;MATHEMATICAL ITALIC CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D448;MATHEMATICAL ITALIC CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D449;MATHEMATICAL ITALIC CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D44A;MATHEMATICAL ITALIC CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D44B;MATHEMATICAL ITALIC CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D44C;MATHEMATICAL ITALIC CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D44D;MATHEMATICAL ITALIC CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D44E;MATHEMATICAL ITALIC SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D44F;MATHEMATICAL ITALIC SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D450;MATHEMATICAL ITALIC SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D451;MATHEMATICAL ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D452;MATHEMATICAL ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D453;MATHEMATICAL ITALIC SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D454;MATHEMATICAL ITALIC SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D456;MATHEMATICAL ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D457;MATHEMATICAL ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D458;MATHEMATICAL ITALIC SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D459;MATHEMATICAL ITALIC SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D45A;MATHEMATICAL ITALIC SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D45B;MATHEMATICAL ITALIC SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D45C;MATHEMATICAL ITALIC SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D45D;MATHEMATICAL ITALIC SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D45E;MATHEMATICAL ITALIC SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D45F;MATHEMATICAL ITALIC SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D460;MATHEMATICAL ITALIC SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D461;MATHEMATICAL ITALIC SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D462;MATHEMATICAL ITALIC SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D463;MATHEMATICAL ITALIC SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D464;MATHEMATICAL ITALIC SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D465;MATHEMATICAL ITALIC SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D466;MATHEMATICAL ITALIC SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D467;MATHEMATICAL ITALIC SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D468;MATHEMATICAL BOLD ITALIC CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D469;MATHEMATICAL BOLD ITALIC CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D46A;MATHEMATICAL BOLD ITALIC CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D46B;MATHEMATICAL BOLD ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D46C;MATHEMATICAL BOLD ITALIC CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D46D;MATHEMATICAL BOLD ITALIC CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D46E;MATHEMATICAL BOLD ITALIC CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D46F;MATHEMATICAL BOLD ITALIC CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D470;MATHEMATICAL BOLD ITALIC CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D471;MATHEMATICAL BOLD ITALIC CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D472;MATHEMATICAL BOLD ITALIC CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D473;MATHEMATICAL BOLD ITALIC CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D474;MATHEMATICAL BOLD ITALIC CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D475;MATHEMATICAL BOLD ITALIC CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D476;MATHEMATICAL BOLD ITALIC CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D477;MATHEMATICAL BOLD ITALIC CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D478;MATHEMATICAL BOLD ITALIC CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D479;MATHEMATICAL BOLD ITALIC CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D47A;MATHEMATICAL BOLD ITALIC CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D47B;MATHEMATICAL BOLD ITALIC CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D47C;MATHEMATICAL BOLD ITALIC CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D47D;MATHEMATICAL BOLD ITALIC CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D47E;MATHEMATICAL BOLD ITALIC CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D47F;MATHEMATICAL BOLD ITALIC CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D480;MATHEMATICAL BOLD ITALIC CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D481;MATHEMATICAL BOLD ITALIC CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D482;MATHEMATICAL BOLD ITALIC SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D483;MATHEMATICAL BOLD ITALIC SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D484;MATHEMATICAL BOLD ITALIC SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D485;MATHEMATICAL BOLD ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D486;MATHEMATICAL BOLD ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D487;MATHEMATICAL BOLD ITALIC SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D488;MATHEMATICAL BOLD ITALIC SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D489;MATHEMATICAL BOLD ITALIC SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D48A;MATHEMATICAL BOLD ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D48B;MATHEMATICAL BOLD ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D48C;MATHEMATICAL BOLD ITALIC SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D48D;MATHEMATICAL BOLD ITALIC SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D48E;MATHEMATICAL BOLD ITALIC SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D48F;MATHEMATICAL BOLD ITALIC SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D490;MATHEMATICAL BOLD ITALIC SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D491;MATHEMATICAL BOLD ITALIC SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D492;MATHEMATICAL BOLD ITALIC SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D493;MATHEMATICAL BOLD ITALIC SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D494;MATHEMATICAL BOLD ITALIC SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D495;MATHEMATICAL BOLD ITALIC SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D496;MATHEMATICAL BOLD ITALIC SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D497;MATHEMATICAL BOLD ITALIC SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D498;MATHEMATICAL BOLD ITALIC SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D499;MATHEMATICAL BOLD ITALIC SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D49A;MATHEMATICAL BOLD ITALIC SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D49B;MATHEMATICAL BOLD ITALIC SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D49C;MATHEMATICAL SCRIPT CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D49E;MATHEMATICAL SCRIPT CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D49F;MATHEMATICAL SCRIPT CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D4A2;MATHEMATICAL SCRIPT CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D4A5;MATHEMATICAL SCRIPT CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D4A6;MATHEMATICAL SCRIPT CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D4A9;MATHEMATICAL SCRIPT CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D4AA;MATHEMATICAL SCRIPT CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D4AB;MATHEMATICAL SCRIPT CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D4AC;MATHEMATICAL SCRIPT CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D4AE;MATHEMATICAL SCRIPT CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D4AF;MATHEMATICAL SCRIPT CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D4B0;MATHEMATICAL SCRIPT CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D4B1;MATHEMATICAL SCRIPT CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D4B2;MATHEMATICAL SCRIPT CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D4B3;MATHEMATICAL SCRIPT CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D4B4;MATHEMATICAL SCRIPT CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D4B5;MATHEMATICAL SCRIPT CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D4B6;MATHEMATICAL SCRIPT SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D4B7;MATHEMATICAL SCRIPT SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D4B8;MATHEMATICAL SCRIPT SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D4B9;MATHEMATICAL SCRIPT SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D4BB;MATHEMATICAL SCRIPT SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D4BD;MATHEMATICAL SCRIPT SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D4BE;MATHEMATICAL SCRIPT SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D4BF;MATHEMATICAL SCRIPT SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D4C0;MATHEMATICAL SCRIPT SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D4C2;MATHEMATICAL SCRIPT SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D4C3;MATHEMATICAL SCRIPT SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D4C5;MATHEMATICAL SCRIPT SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D4C6;MATHEMATICAL SCRIPT SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D4C7;MATHEMATICAL SCRIPT SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D4C8;MATHEMATICAL SCRIPT SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D4C9;MATHEMATICAL SCRIPT SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D4CA;MATHEMATICAL SCRIPT SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D4CB;MATHEMATICAL SCRIPT SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D4CC;MATHEMATICAL SCRIPT SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D4CD;MATHEMATICAL SCRIPT SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D4CE;MATHEMATICAL SCRIPT SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D4CF;MATHEMATICAL SCRIPT SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D4D0;MATHEMATICAL BOLD SCRIPT CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D4D1;MATHEMATICAL BOLD SCRIPT CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D4D2;MATHEMATICAL BOLD SCRIPT CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D4D3;MATHEMATICAL BOLD SCRIPT CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D4D4;MATHEMATICAL BOLD SCRIPT CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D4D5;MATHEMATICAL BOLD SCRIPT CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D4D6;MATHEMATICAL BOLD SCRIPT CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D4D7;MATHEMATICAL BOLD SCRIPT CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D4D8;MATHEMATICAL BOLD SCRIPT CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D4D9;MATHEMATICAL BOLD SCRIPT CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D4DA;MATHEMATICAL BOLD SCRIPT CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D4DB;MATHEMATICAL BOLD SCRIPT CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D4DC;MATHEMATICAL BOLD SCRIPT CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D4DD;MATHEMATICAL BOLD SCRIPT CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D4DE;MATHEMATICAL BOLD SCRIPT CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D4DF;MATHEMATICAL BOLD SCRIPT CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D4E0;MATHEMATICAL BOLD SCRIPT CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D4E1;MATHEMATICAL BOLD SCRIPT CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D4E2;MATHEMATICAL BOLD SCRIPT CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D4E3;MATHEMATICAL BOLD SCRIPT CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D4E4;MATHEMATICAL BOLD SCRIPT CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D4E5;MATHEMATICAL BOLD SCRIPT CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D4E6;MATHEMATICAL BOLD SCRIPT CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D4E7;MATHEMATICAL BOLD SCRIPT CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D4E8;MATHEMATICAL BOLD SCRIPT CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D4E9;MATHEMATICAL BOLD SCRIPT CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D4EA;MATHEMATICAL BOLD SCRIPT SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D4EB;MATHEMATICAL BOLD SCRIPT SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D4EC;MATHEMATICAL BOLD SCRIPT SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D4ED;MATHEMATICAL BOLD SCRIPT SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D4EE;MATHEMATICAL BOLD SCRIPT SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D4EF;MATHEMATICAL BOLD SCRIPT SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D4F0;MATHEMATICAL BOLD SCRIPT SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D4F1;MATHEMATICAL BOLD SCRIPT SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D4F2;MATHEMATICAL BOLD SCRIPT SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D4F3;MATHEMATICAL BOLD SCRIPT SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D4F4;MATHEMATICAL BOLD SCRIPT SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D4F5;MATHEMATICAL BOLD SCRIPT SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D4F6;MATHEMATICAL BOLD SCRIPT SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D4F7;MATHEMATICAL BOLD SCRIPT SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D4F8;MATHEMATICAL BOLD SCRIPT SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D4F9;MATHEMATICAL BOLD SCRIPT SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D4FA;MATHEMATICAL BOLD SCRIPT SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D4FB;MATHEMATICAL BOLD SCRIPT SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D4FC;MATHEMATICAL BOLD SCRIPT SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D4FD;MATHEMATICAL BOLD SCRIPT SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D4FE;MATHEMATICAL BOLD SCRIPT SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D4FF;MATHEMATICAL BOLD SCRIPT SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D500;MATHEMATICAL BOLD SCRIPT SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D501;MATHEMATICAL BOLD SCRIPT SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D502;MATHEMATICAL BOLD SCRIPT SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D503;MATHEMATICAL BOLD SCRIPT SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D504;MATHEMATICAL FRAKTUR CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D505;MATHEMATICAL FRAKTUR CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D507;MATHEMATICAL FRAKTUR CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D508;MATHEMATICAL FRAKTUR CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D509;MATHEMATICAL FRAKTUR CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D50A;MATHEMATICAL FRAKTUR CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D50D;MATHEMATICAL FRAKTUR CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D50E;MATHEMATICAL FRAKTUR CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D50F;MATHEMATICAL FRAKTUR CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D510;MATHEMATICAL FRAKTUR CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D511;MATHEMATICAL FRAKTUR CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D512;MATHEMATICAL FRAKTUR CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D513;MATHEMATICAL FRAKTUR CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D514;MATHEMATICAL FRAKTUR CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D516;MATHEMATICAL FRAKTUR CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D517;MATHEMATICAL FRAKTUR CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D518;MATHEMATICAL FRAKTUR CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D519;MATHEMATICAL FRAKTUR CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D51A;MATHEMATICAL FRAKTUR CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D51B;MATHEMATICAL FRAKTUR CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D51C;MATHEMATICAL FRAKTUR CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D51E;MATHEMATICAL FRAKTUR SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D51F;MATHEMATICAL FRAKTUR SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D520;MATHEMATICAL FRAKTUR SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D521;MATHEMATICAL FRAKTUR SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D522;MATHEMATICAL FRAKTUR SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D523;MATHEMATICAL FRAKTUR SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D524;MATHEMATICAL FRAKTUR SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D525;MATHEMATICAL FRAKTUR SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D526;MATHEMATICAL FRAKTUR SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D527;MATHEMATICAL FRAKTUR SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D528;MATHEMATICAL FRAKTUR SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D529;MATHEMATICAL FRAKTUR SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D52A;MATHEMATICAL FRAKTUR SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D52B;MATHEMATICAL FRAKTUR SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D52C;MATHEMATICAL FRAKTUR SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D52D;MATHEMATICAL FRAKTUR SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D52E;MATHEMATICAL FRAKTUR SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D52F;MATHEMATICAL FRAKTUR SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D530;MATHEMATICAL FRAKTUR SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D531;MATHEMATICAL FRAKTUR SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D532;MATHEMATICAL FRAKTUR SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D533;MATHEMATICAL FRAKTUR SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D534;MATHEMATICAL FRAKTUR SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D535;MATHEMATICAL FRAKTUR SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D536;MATHEMATICAL FRAKTUR SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D537;MATHEMATICAL FRAKTUR SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D538;MATHEMATICAL DOUBLE-STRUCK CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D539;MATHEMATICAL DOUBLE-STRUCK CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D53B;MATHEMATICAL DOUBLE-STRUCK CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D53C;MATHEMATICAL DOUBLE-STRUCK CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D53D;MATHEMATICAL DOUBLE-STRUCK CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D53E;MATHEMATICAL DOUBLE-STRUCK CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D540;MATHEMATICAL DOUBLE-STRUCK CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D541;MATHEMATICAL DOUBLE-STRUCK CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D542;MATHEMATICAL DOUBLE-STRUCK CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D543;MATHEMATICAL DOUBLE-STRUCK CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D544;MATHEMATICAL DOUBLE-STRUCK CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D546;MATHEMATICAL DOUBLE-STRUCK CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D54A;MATHEMATICAL DOUBLE-STRUCK CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D54B;MATHEMATICAL DOUBLE-STRUCK CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D54C;MATHEMATICAL DOUBLE-STRUCK CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D54D;MATHEMATICAL DOUBLE-STRUCK CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D54E;MATHEMATICAL DOUBLE-STRUCK CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D54F;MATHEMATICAL DOUBLE-STRUCK CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D550;MATHEMATICAL DOUBLE-STRUCK CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D552;MATHEMATICAL DOUBLE-STRUCK SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D553;MATHEMATICAL DOUBLE-STRUCK SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D554;MATHEMATICAL DOUBLE-STRUCK SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D555;MATHEMATICAL DOUBLE-STRUCK SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D556;MATHEMATICAL DOUBLE-STRUCK SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D557;MATHEMATICAL DOUBLE-STRUCK SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D558;MATHEMATICAL DOUBLE-STRUCK SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D559;MATHEMATICAL DOUBLE-STRUCK SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D55A;MATHEMATICAL DOUBLE-STRUCK SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D55B;MATHEMATICAL DOUBLE-STRUCK SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D55C;MATHEMATICAL DOUBLE-STRUCK SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D55D;MATHEMATICAL DOUBLE-STRUCK SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D55E;MATHEMATICAL DOUBLE-STRUCK SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D55F;MATHEMATICAL DOUBLE-STRUCK SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D560;MATHEMATICAL DOUBLE-STRUCK SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D561;MATHEMATICAL DOUBLE-STRUCK SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D562;MATHEMATICAL DOUBLE-STRUCK SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D563;MATHEMATICAL DOUBLE-STRUCK SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D564;MATHEMATICAL DOUBLE-STRUCK SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D565;MATHEMATICAL DOUBLE-STRUCK SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D566;MATHEMATICAL DOUBLE-STRUCK SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D567;MATHEMATICAL DOUBLE-STRUCK SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D568;MATHEMATICAL DOUBLE-STRUCK SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D569;MATHEMATICAL DOUBLE-STRUCK SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D56A;MATHEMATICAL DOUBLE-STRUCK SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D56B;MATHEMATICAL DOUBLE-STRUCK SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D56C;MATHEMATICAL BOLD FRAKTUR CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D56D;MATHEMATICAL BOLD FRAKTUR CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D56E;MATHEMATICAL BOLD FRAKTUR CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D56F;MATHEMATICAL BOLD FRAKTUR CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D570;MATHEMATICAL BOLD FRAKTUR CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D571;MATHEMATICAL BOLD FRAKTUR CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D572;MATHEMATICAL BOLD FRAKTUR CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D573;MATHEMATICAL BOLD FRAKTUR CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D574;MATHEMATICAL BOLD FRAKTUR CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D575;MATHEMATICAL BOLD FRAKTUR CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D576;MATHEMATICAL BOLD FRAKTUR CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D577;MATHEMATICAL BOLD FRAKTUR CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D578;MATHEMATICAL BOLD FRAKTUR CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D579;MATHEMATICAL BOLD FRAKTUR CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D57A;MATHEMATICAL BOLD FRAKTUR CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D57B;MATHEMATICAL BOLD FRAKTUR CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D57C;MATHEMATICAL BOLD FRAKTUR CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D57D;MATHEMATICAL BOLD FRAKTUR CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D57E;MATHEMATICAL BOLD FRAKTUR CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D57F;MATHEMATICAL BOLD FRAKTUR CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D580;MATHEMATICAL BOLD FRAKTUR CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D581;MATHEMATICAL BOLD FRAKTUR CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D582;MATHEMATICAL BOLD FRAKTUR CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D583;MATHEMATICAL BOLD FRAKTUR CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D584;MATHEMATICAL BOLD FRAKTUR CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D585;MATHEMATICAL BOLD FRAKTUR CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D586;MATHEMATICAL BOLD FRAKTUR SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D587;MATHEMATICAL BOLD FRAKTUR SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D588;MATHEMATICAL BOLD FRAKTUR SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D589;MATHEMATICAL BOLD FRAKTUR SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D58A;MATHEMATICAL BOLD FRAKTUR SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D58B;MATHEMATICAL BOLD FRAKTUR SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D58C;MATHEMATICAL BOLD FRAKTUR SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D58D;MATHEMATICAL BOLD FRAKTUR SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D58E;MATHEMATICAL BOLD FRAKTUR SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D58F;MATHEMATICAL BOLD FRAKTUR SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D590;MATHEMATICAL BOLD FRAKTUR SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D591;MATHEMATICAL BOLD FRAKTUR SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D592;MATHEMATICAL BOLD FRAKTUR SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D593;MATHEMATICAL BOLD FRAKTUR SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D594;MATHEMATICAL BOLD FRAKTUR SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D595;MATHEMATICAL BOLD FRAKTUR SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D596;MATHEMATICAL BOLD FRAKTUR SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D597;MATHEMATICAL BOLD FRAKTUR SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D598;MATHEMATICAL BOLD FRAKTUR SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D599;MATHEMATICAL BOLD FRAKTUR SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D59A;MATHEMATICAL BOLD FRAKTUR SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D59B;MATHEMATICAL BOLD FRAKTUR SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D59C;MATHEMATICAL BOLD FRAKTUR SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D59D;MATHEMATICAL BOLD FRAKTUR SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D59E;MATHEMATICAL BOLD FRAKTUR SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D59F;MATHEMATICAL BOLD FRAKTUR SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D5A0;MATHEMATICAL SANS-SERIF CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D5A1;MATHEMATICAL SANS-SERIF CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D5A2;MATHEMATICAL SANS-SERIF CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D5A3;MATHEMATICAL SANS-SERIF CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D5A4;MATHEMATICAL SANS-SERIF CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D5A5;MATHEMATICAL SANS-SERIF CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D5A6;MATHEMATICAL SANS-SERIF CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D5A7;MATHEMATICAL SANS-SERIF CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D5A8;MATHEMATICAL SANS-SERIF CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D5A9;MATHEMATICAL SANS-SERIF CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D5AA;MATHEMATICAL SANS-SERIF CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D5AB;MATHEMATICAL SANS-SERIF CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D5AC;MATHEMATICAL SANS-SERIF CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D5AD;MATHEMATICAL SANS-SERIF CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D5AE;MATHEMATICAL SANS-SERIF CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D5AF;MATHEMATICAL SANS-SERIF CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D5B0;MATHEMATICAL SANS-SERIF CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D5B1;MATHEMATICAL SANS-SERIF CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D5B2;MATHEMATICAL SANS-SERIF CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D5B3;MATHEMATICAL SANS-SERIF CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D5B4;MATHEMATICAL SANS-SERIF CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D5B5;MATHEMATICAL SANS-SERIF CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D5B6;MATHEMATICAL SANS-SERIF CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D5B7;MATHEMATICAL SANS-SERIF CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D5B8;MATHEMATICAL SANS-SERIF CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D5B9;MATHEMATICAL SANS-SERIF CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D5BA;MATHEMATICAL SANS-SERIF SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D5BB;MATHEMATICAL SANS-SERIF SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D5BC;MATHEMATICAL SANS-SERIF SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D5BD;MATHEMATICAL SANS-SERIF SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D5BE;MATHEMATICAL SANS-SERIF SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D5BF;MATHEMATICAL SANS-SERIF SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D5C0;MATHEMATICAL SANS-SERIF SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D5C1;MATHEMATICAL SANS-SERIF SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D5C2;MATHEMATICAL SANS-SERIF SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D5C3;MATHEMATICAL SANS-SERIF SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D5C4;MATHEMATICAL SANS-SERIF SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D5C5;MATHEMATICAL SANS-SERIF SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D5C6;MATHEMATICAL SANS-SERIF SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D5C7;MATHEMATICAL SANS-SERIF SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D5C8;MATHEMATICAL SANS-SERIF SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D5C9;MATHEMATICAL SANS-SERIF SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D5CA;MATHEMATICAL SANS-SERIF SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D5CB;MATHEMATICAL SANS-SERIF SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D5CC;MATHEMATICAL SANS-SERIF SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D5CD;MATHEMATICAL SANS-SERIF SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D5CE;MATHEMATICAL SANS-SERIF SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D5CF;MATHEMATICAL SANS-SERIF SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D5D0;MATHEMATICAL SANS-SERIF SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D5D1;MATHEMATICAL SANS-SERIF SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D5D2;MATHEMATICAL SANS-SERIF SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D5D3;MATHEMATICAL SANS-SERIF SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D5D4;MATHEMATICAL SANS-SERIF BOLD CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D5D5;MATHEMATICAL SANS-SERIF BOLD CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D5D6;MATHEMATICAL SANS-SERIF BOLD CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D5D7;MATHEMATICAL SANS-SERIF BOLD CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D5D8;MATHEMATICAL SANS-SERIF BOLD CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D5D9;MATHEMATICAL SANS-SERIF BOLD CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D5DA;MATHEMATICAL SANS-SERIF BOLD CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D5DB;MATHEMATICAL SANS-SERIF BOLD CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D5DC;MATHEMATICAL SANS-SERIF BOLD CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D5DD;MATHEMATICAL SANS-SERIF BOLD CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D5DE;MATHEMATICAL SANS-SERIF BOLD CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D5DF;MATHEMATICAL SANS-SERIF BOLD CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D5E0;MATHEMATICAL SANS-SERIF BOLD CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D5E1;MATHEMATICAL SANS-SERIF BOLD CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D5E2;MATHEMATICAL SANS-SERIF BOLD CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D5E3;MATHEMATICAL SANS-SERIF BOLD CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D5E4;MATHEMATICAL SANS-SERIF BOLD CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D5E5;MATHEMATICAL SANS-SERIF BOLD CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D5E6;MATHEMATICAL SANS-SERIF BOLD CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D5E7;MATHEMATICAL SANS-SERIF BOLD CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D5E8;MATHEMATICAL SANS-SERIF BOLD CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D5E9;MATHEMATICAL SANS-SERIF BOLD CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D5EA;MATHEMATICAL SANS-SERIF BOLD CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D5EB;MATHEMATICAL SANS-SERIF BOLD CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D5EC;MATHEMATICAL SANS-SERIF BOLD CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D5ED;MATHEMATICAL SANS-SERIF BOLD CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D5EE;MATHEMATICAL SANS-SERIF BOLD SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D5EF;MATHEMATICAL SANS-SERIF BOLD SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D5F0;MATHEMATICAL SANS-SERIF BOLD SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D5F1;MATHEMATICAL SANS-SERIF BOLD SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D5F2;MATHEMATICAL SANS-SERIF BOLD SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D5F3;MATHEMATICAL SANS-SERIF BOLD SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D5F4;MATHEMATICAL SANS-SERIF BOLD SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D5F5;MATHEMATICAL SANS-SERIF BOLD SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D5F6;MATHEMATICAL SANS-SERIF BOLD SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D5F7;MATHEMATICAL SANS-SERIF BOLD SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D5F8;MATHEMATICAL SANS-SERIF BOLD SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D5F9;MATHEMATICAL SANS-SERIF BOLD SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D5FA;MATHEMATICAL SANS-SERIF BOLD SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D5FB;MATHEMATICAL SANS-SERIF BOLD SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D5FC;MATHEMATICAL SANS-SERIF BOLD SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D5FD;MATHEMATICAL SANS-SERIF BOLD SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D5FE;MATHEMATICAL SANS-SERIF BOLD SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D5FF;MATHEMATICAL SANS-SERIF BOLD SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D600;MATHEMATICAL SANS-SERIF BOLD SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D601;MATHEMATICAL SANS-SERIF BOLD SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D602;MATHEMATICAL SANS-SERIF BOLD SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D603;MATHEMATICAL SANS-SERIF BOLD SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D604;MATHEMATICAL SANS-SERIF BOLD SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D605;MATHEMATICAL SANS-SERIF BOLD SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D606;MATHEMATICAL SANS-SERIF BOLD SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D607;MATHEMATICAL SANS-SERIF BOLD SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D608;MATHEMATICAL SANS-SERIF ITALIC CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D609;MATHEMATICAL SANS-SERIF ITALIC CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D60A;MATHEMATICAL SANS-SERIF ITALIC CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D60B;MATHEMATICAL SANS-SERIF ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D60C;MATHEMATICAL SANS-SERIF ITALIC CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D60D;MATHEMATICAL SANS-SERIF ITALIC CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D60E;MATHEMATICAL SANS-SERIF ITALIC CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D60F;MATHEMATICAL SANS-SERIF ITALIC CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D610;MATHEMATICAL SANS-SERIF ITALIC CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D611;MATHEMATICAL SANS-SERIF ITALIC CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D612;MATHEMATICAL SANS-SERIF ITALIC CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D613;MATHEMATICAL SANS-SERIF ITALIC CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D614;MATHEMATICAL SANS-SERIF ITALIC CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D615;MATHEMATICAL SANS-SERIF ITALIC CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D616;MATHEMATICAL SANS-SERIF ITALIC CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D617;MATHEMATICAL SANS-SERIF ITALIC CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D618;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D619;MATHEMATICAL SANS-SERIF ITALIC CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D61A;MATHEMATICAL SANS-SERIF ITALIC CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D61B;MATHEMATICAL SANS-SERIF ITALIC CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D61C;MATHEMATICAL SANS-SERIF ITALIC CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D61D;MATHEMATICAL SANS-SERIF ITALIC CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D61E;MATHEMATICAL SANS-SERIF ITALIC CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D61F;MATHEMATICAL SANS-SERIF ITALIC CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D620;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D621;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D622;MATHEMATICAL SANS-SERIF ITALIC SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D623;MATHEMATICAL SANS-SERIF ITALIC SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D624;MATHEMATICAL SANS-SERIF ITALIC SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D625;MATHEMATICAL SANS-SERIF ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D626;MATHEMATICAL SANS-SERIF ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D627;MATHEMATICAL SANS-SERIF ITALIC SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D628;MATHEMATICAL SANS-SERIF ITALIC SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D629;MATHEMATICAL SANS-SERIF ITALIC SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D62A;MATHEMATICAL SANS-SERIF ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D62B;MATHEMATICAL SANS-SERIF ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D62C;MATHEMATICAL SANS-SERIF ITALIC SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D62D;MATHEMATICAL SANS-SERIF ITALIC SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D62E;MATHEMATICAL SANS-SERIF ITALIC SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D62F;MATHEMATICAL SANS-SERIF ITALIC SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D630;MATHEMATICAL SANS-SERIF ITALIC SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D631;MATHEMATICAL SANS-SERIF ITALIC SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D632;MATHEMATICAL SANS-SERIF ITALIC SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D633;MATHEMATICAL SANS-SERIF ITALIC SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D634;MATHEMATICAL SANS-SERIF ITALIC SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D635;MATHEMATICAL SANS-SERIF ITALIC SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D636;MATHEMATICAL SANS-SERIF ITALIC SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D637;MATHEMATICAL SANS-SERIF ITALIC SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D638;MATHEMATICAL SANS-SERIF ITALIC SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D639;MATHEMATICAL SANS-SERIF ITALIC SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D63A;MATHEMATICAL SANS-SERIF ITALIC SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D63B;MATHEMATICAL SANS-SERIF ITALIC SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D63C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D63D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D63E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D63F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D640;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D641;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D642;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D643;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D644;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D645;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D646;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D647;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D648;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D649;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D64A;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D64B;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D64C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D64D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D64E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D64F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D650;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D651;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D652;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D653;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D654;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D655;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D656;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D657;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D658;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D659;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D65A;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D65B;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D65C;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D65D;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D65E;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D65F;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D660;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D661;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D662;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D663;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D664;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D665;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D666;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D667;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D668;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D669;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D66A;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D66B;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D66C;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D66D;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D66E;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D66F;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D670;MATHEMATICAL MONOSPACE CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D671;MATHEMATICAL MONOSPACE CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D672;MATHEMATICAL MONOSPACE CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D673;MATHEMATICAL MONOSPACE CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D674;MATHEMATICAL MONOSPACE CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D675;MATHEMATICAL MONOSPACE CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D676;MATHEMATICAL MONOSPACE CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D677;MATHEMATICAL MONOSPACE CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D678;MATHEMATICAL MONOSPACE CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D679;MATHEMATICAL MONOSPACE CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D67A;MATHEMATICAL MONOSPACE CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D67B;MATHEMATICAL MONOSPACE CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D67C;MATHEMATICAL MONOSPACE CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D67D;MATHEMATICAL MONOSPACE CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D67E;MATHEMATICAL MONOSPACE CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D67F;MATHEMATICAL MONOSPACE CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D680;MATHEMATICAL MONOSPACE CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D681;MATHEMATICAL MONOSPACE CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D682;MATHEMATICAL MONOSPACE CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D683;MATHEMATICAL MONOSPACE CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D684;MATHEMATICAL MONOSPACE CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D685;MATHEMATICAL MONOSPACE CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D686;MATHEMATICAL MONOSPACE CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D687;MATHEMATICAL MONOSPACE CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D688;MATHEMATICAL MONOSPACE CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D689;MATHEMATICAL MONOSPACE CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D68A;MATHEMATICAL MONOSPACE SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D68B;MATHEMATICAL MONOSPACE SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D68C;MATHEMATICAL MONOSPACE SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D68D;MATHEMATICAL MONOSPACE SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D68E;MATHEMATICAL MONOSPACE SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D68F;MATHEMATICAL MONOSPACE SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D690;MATHEMATICAL MONOSPACE SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D691;MATHEMATICAL MONOSPACE SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D692;MATHEMATICAL MONOSPACE SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D693;MATHEMATICAL MONOSPACE SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D694;MATHEMATICAL MONOSPACE SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D695;MATHEMATICAL MONOSPACE SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D696;MATHEMATICAL MONOSPACE SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D697;MATHEMATICAL MONOSPACE SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D698;MATHEMATICAL MONOSPACE SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D699;MATHEMATICAL MONOSPACE SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D69A;MATHEMATICAL MONOSPACE SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D69B;MATHEMATICAL MONOSPACE SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D69C;MATHEMATICAL MONOSPACE SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D69D;MATHEMATICAL MONOSPACE SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D69E;MATHEMATICAL MONOSPACE SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D69F;MATHEMATICAL MONOSPACE SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D6A0;MATHEMATICAL MONOSPACE SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D6A1;MATHEMATICAL MONOSPACE SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D6A2;MATHEMATICAL MONOSPACE SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D6A3;MATHEMATICAL MONOSPACE SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D6A8;MATHEMATICAL BOLD CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; +1D6A9;MATHEMATICAL BOLD CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; +1D6AA;MATHEMATICAL BOLD CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +1D6AB;MATHEMATICAL BOLD CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; +1D6AC;MATHEMATICAL BOLD CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; +1D6AD;MATHEMATICAL BOLD CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; +1D6AE;MATHEMATICAL BOLD CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; +1D6AF;MATHEMATICAL BOLD CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; +1D6B0;MATHEMATICAL BOLD CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; +1D6B1;MATHEMATICAL BOLD CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; +1D6B2;MATHEMATICAL BOLD CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; +1D6B3;MATHEMATICAL BOLD CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; +1D6B4;MATHEMATICAL BOLD CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; +1D6B5;MATHEMATICAL BOLD CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; +1D6B6;MATHEMATICAL BOLD CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; +1D6B7;MATHEMATICAL BOLD CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +1D6B8;MATHEMATICAL BOLD CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; +1D6B9;MATHEMATICAL BOLD CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; +1D6BA;MATHEMATICAL BOLD CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; +1D6BB;MATHEMATICAL BOLD CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; +1D6BC;MATHEMATICAL BOLD CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; +1D6BD;MATHEMATICAL BOLD CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; +1D6BE;MATHEMATICAL BOLD CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; +1D6BF;MATHEMATICAL BOLD CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; +1D6C0;MATHEMATICAL BOLD CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; +1D6C1;MATHEMATICAL BOLD NABLA;Sm;0;L; 2207;;;;N;;;;; +1D6C2;MATHEMATICAL BOLD SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; +1D6C3;MATHEMATICAL BOLD SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; +1D6C4;MATHEMATICAL BOLD SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D6C5;MATHEMATICAL BOLD SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; +1D6C6;MATHEMATICAL BOLD SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; +1D6C7;MATHEMATICAL BOLD SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; +1D6C8;MATHEMATICAL BOLD SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; +1D6C9;MATHEMATICAL BOLD SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; +1D6CA;MATHEMATICAL BOLD SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; +1D6CB;MATHEMATICAL BOLD SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; +1D6CC;MATHEMATICAL BOLD SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; +1D6CD;MATHEMATICAL BOLD SMALL MU;Ll;0;L; 03BC;;;;N;;;;; +1D6CE;MATHEMATICAL BOLD SMALL NU;Ll;0;L; 03BD;;;;N;;;;; +1D6CF;MATHEMATICAL BOLD SMALL XI;Ll;0;L; 03BE;;;;N;;;;; +1D6D0;MATHEMATICAL BOLD SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; +1D6D1;MATHEMATICAL BOLD SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +1D6D2;MATHEMATICAL BOLD SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; +1D6D3;MATHEMATICAL BOLD SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; +1D6D4;MATHEMATICAL BOLD SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; +1D6D5;MATHEMATICAL BOLD SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; +1D6D6;MATHEMATICAL BOLD SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; +1D6D7;MATHEMATICAL BOLD SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; +1D6D8;MATHEMATICAL BOLD SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; +1D6D9;MATHEMATICAL BOLD SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; +1D6DA;MATHEMATICAL BOLD SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; +1D6DB;MATHEMATICAL BOLD PARTIAL DIFFERENTIAL;Sm;0;L; 2202;;;;N;;;;; +1D6DC;MATHEMATICAL BOLD EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; +1D6DD;MATHEMATICAL BOLD THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; +1D6DE;MATHEMATICAL BOLD KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; +1D6DF;MATHEMATICAL BOLD PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; +1D6E0;MATHEMATICAL BOLD RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; +1D6E1;MATHEMATICAL BOLD PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; +1D6E2;MATHEMATICAL ITALIC CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; +1D6E3;MATHEMATICAL ITALIC CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; +1D6E4;MATHEMATICAL ITALIC CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +1D6E5;MATHEMATICAL ITALIC CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; +1D6E6;MATHEMATICAL ITALIC CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; +1D6E7;MATHEMATICAL ITALIC CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; +1D6E8;MATHEMATICAL ITALIC CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; +1D6E9;MATHEMATICAL ITALIC CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; +1D6EA;MATHEMATICAL ITALIC CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; +1D6EB;MATHEMATICAL ITALIC CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; +1D6EC;MATHEMATICAL ITALIC CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; +1D6ED;MATHEMATICAL ITALIC CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; +1D6EE;MATHEMATICAL ITALIC CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; +1D6EF;MATHEMATICAL ITALIC CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; +1D6F0;MATHEMATICAL ITALIC CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; +1D6F1;MATHEMATICAL ITALIC CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +1D6F2;MATHEMATICAL ITALIC CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; +1D6F3;MATHEMATICAL ITALIC CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; +1D6F4;MATHEMATICAL ITALIC CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; +1D6F5;MATHEMATICAL ITALIC CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; +1D6F6;MATHEMATICAL ITALIC CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; +1D6F7;MATHEMATICAL ITALIC CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; +1D6F8;MATHEMATICAL ITALIC CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; +1D6F9;MATHEMATICAL ITALIC CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; +1D6FA;MATHEMATICAL ITALIC CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; +1D6FB;MATHEMATICAL ITALIC NABLA;Sm;0;L; 2207;;;;N;;;;; +1D6FC;MATHEMATICAL ITALIC SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; +1D6FD;MATHEMATICAL ITALIC SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; +1D6FE;MATHEMATICAL ITALIC SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D6FF;MATHEMATICAL ITALIC SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; +1D700;MATHEMATICAL ITALIC SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; +1D701;MATHEMATICAL ITALIC SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; +1D702;MATHEMATICAL ITALIC SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; +1D703;MATHEMATICAL ITALIC SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; +1D704;MATHEMATICAL ITALIC SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; +1D705;MATHEMATICAL ITALIC SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; +1D706;MATHEMATICAL ITALIC SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; +1D707;MATHEMATICAL ITALIC SMALL MU;Ll;0;L; 03BC;;;;N;;;;; +1D708;MATHEMATICAL ITALIC SMALL NU;Ll;0;L; 03BD;;;;N;;;;; +1D709;MATHEMATICAL ITALIC SMALL XI;Ll;0;L; 03BE;;;;N;;;;; +1D70A;MATHEMATICAL ITALIC SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; +1D70B;MATHEMATICAL ITALIC SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +1D70C;MATHEMATICAL ITALIC SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; +1D70D;MATHEMATICAL ITALIC SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; +1D70E;MATHEMATICAL ITALIC SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; +1D70F;MATHEMATICAL ITALIC SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; +1D710;MATHEMATICAL ITALIC SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; +1D711;MATHEMATICAL ITALIC SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; +1D712;MATHEMATICAL ITALIC SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; +1D713;MATHEMATICAL ITALIC SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; +1D714;MATHEMATICAL ITALIC SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; +1D715;MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL;Sm;0;L; 2202;;;;N;;;;; +1D716;MATHEMATICAL ITALIC EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; +1D717;MATHEMATICAL ITALIC THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; +1D718;MATHEMATICAL ITALIC KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; +1D719;MATHEMATICAL ITALIC PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; +1D71A;MATHEMATICAL ITALIC RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; +1D71B;MATHEMATICAL ITALIC PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; +1D71C;MATHEMATICAL BOLD ITALIC CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; +1D71D;MATHEMATICAL BOLD ITALIC CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; +1D71E;MATHEMATICAL BOLD ITALIC CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +1D71F;MATHEMATICAL BOLD ITALIC CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; +1D720;MATHEMATICAL BOLD ITALIC CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; +1D721;MATHEMATICAL BOLD ITALIC CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; +1D722;MATHEMATICAL BOLD ITALIC CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; +1D723;MATHEMATICAL BOLD ITALIC CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; +1D724;MATHEMATICAL BOLD ITALIC CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; +1D725;MATHEMATICAL BOLD ITALIC CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; +1D726;MATHEMATICAL BOLD ITALIC CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; +1D727;MATHEMATICAL BOLD ITALIC CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; +1D728;MATHEMATICAL BOLD ITALIC CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; +1D729;MATHEMATICAL BOLD ITALIC CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; +1D72A;MATHEMATICAL BOLD ITALIC CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; +1D72B;MATHEMATICAL BOLD ITALIC CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +1D72C;MATHEMATICAL BOLD ITALIC CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; +1D72D;MATHEMATICAL BOLD ITALIC CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; +1D72E;MATHEMATICAL BOLD ITALIC CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; +1D72F;MATHEMATICAL BOLD ITALIC CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; +1D730;MATHEMATICAL BOLD ITALIC CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; +1D731;MATHEMATICAL BOLD ITALIC CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; +1D732;MATHEMATICAL BOLD ITALIC CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; +1D733;MATHEMATICAL BOLD ITALIC CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; +1D734;MATHEMATICAL BOLD ITALIC CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; +1D735;MATHEMATICAL BOLD ITALIC NABLA;Sm;0;L; 2207;;;;N;;;;; +1D736;MATHEMATICAL BOLD ITALIC SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; +1D737;MATHEMATICAL BOLD ITALIC SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; +1D738;MATHEMATICAL BOLD ITALIC SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D739;MATHEMATICAL BOLD ITALIC SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; +1D73A;MATHEMATICAL BOLD ITALIC SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; +1D73B;MATHEMATICAL BOLD ITALIC SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; +1D73C;MATHEMATICAL BOLD ITALIC SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; +1D73D;MATHEMATICAL BOLD ITALIC SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; +1D73E;MATHEMATICAL BOLD ITALIC SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; +1D73F;MATHEMATICAL BOLD ITALIC SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; +1D740;MATHEMATICAL BOLD ITALIC SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; +1D741;MATHEMATICAL BOLD ITALIC SMALL MU;Ll;0;L; 03BC;;;;N;;;;; +1D742;MATHEMATICAL BOLD ITALIC SMALL NU;Ll;0;L; 03BD;;;;N;;;;; +1D743;MATHEMATICAL BOLD ITALIC SMALL XI;Ll;0;L; 03BE;;;;N;;;;; +1D744;MATHEMATICAL BOLD ITALIC SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; +1D745;MATHEMATICAL BOLD ITALIC SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +1D746;MATHEMATICAL BOLD ITALIC SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; +1D747;MATHEMATICAL BOLD ITALIC SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; +1D748;MATHEMATICAL BOLD ITALIC SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; +1D749;MATHEMATICAL BOLD ITALIC SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; +1D74A;MATHEMATICAL BOLD ITALIC SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; +1D74B;MATHEMATICAL BOLD ITALIC SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; +1D74C;MATHEMATICAL BOLD ITALIC SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; +1D74D;MATHEMATICAL BOLD ITALIC SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; +1D74E;MATHEMATICAL BOLD ITALIC SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; +1D74F;MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;L; 2202;;;;N;;;;; +1D750;MATHEMATICAL BOLD ITALIC EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; +1D751;MATHEMATICAL BOLD ITALIC THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; +1D752;MATHEMATICAL BOLD ITALIC KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; +1D753;MATHEMATICAL BOLD ITALIC PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; +1D754;MATHEMATICAL BOLD ITALIC RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; +1D755;MATHEMATICAL BOLD ITALIC PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; +1D756;MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; +1D757;MATHEMATICAL SANS-SERIF BOLD CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; +1D758;MATHEMATICAL SANS-SERIF BOLD CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +1D759;MATHEMATICAL SANS-SERIF BOLD CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; +1D75A;MATHEMATICAL SANS-SERIF BOLD CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; +1D75B;MATHEMATICAL SANS-SERIF BOLD CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; +1D75C;MATHEMATICAL SANS-SERIF BOLD CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; +1D75D;MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; +1D75E;MATHEMATICAL SANS-SERIF BOLD CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; +1D75F;MATHEMATICAL SANS-SERIF BOLD CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; +1D760;MATHEMATICAL SANS-SERIF BOLD CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; +1D761;MATHEMATICAL SANS-SERIF BOLD CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; +1D762;MATHEMATICAL SANS-SERIF BOLD CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; +1D763;MATHEMATICAL SANS-SERIF BOLD CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; +1D764;MATHEMATICAL SANS-SERIF BOLD CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; +1D765;MATHEMATICAL SANS-SERIF BOLD CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +1D766;MATHEMATICAL SANS-SERIF BOLD CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; +1D767;MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; +1D768;MATHEMATICAL SANS-SERIF BOLD CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; +1D769;MATHEMATICAL SANS-SERIF BOLD CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; +1D76A;MATHEMATICAL SANS-SERIF BOLD CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; +1D76B;MATHEMATICAL SANS-SERIF BOLD CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; +1D76C;MATHEMATICAL SANS-SERIF BOLD CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; +1D76D;MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; +1D76E;MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; +1D76F;MATHEMATICAL SANS-SERIF BOLD NABLA;Sm;0;L; 2207;;;;N;;;;; +1D770;MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; +1D771;MATHEMATICAL SANS-SERIF BOLD SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; +1D772;MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D773;MATHEMATICAL SANS-SERIF BOLD SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; +1D774;MATHEMATICAL SANS-SERIF BOLD SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; +1D775;MATHEMATICAL SANS-SERIF BOLD SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; +1D776;MATHEMATICAL SANS-SERIF BOLD SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; +1D777;MATHEMATICAL SANS-SERIF BOLD SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; +1D778;MATHEMATICAL SANS-SERIF BOLD SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; +1D779;MATHEMATICAL SANS-SERIF BOLD SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; +1D77A;MATHEMATICAL SANS-SERIF BOLD SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; +1D77B;MATHEMATICAL SANS-SERIF BOLD SMALL MU;Ll;0;L; 03BC;;;;N;;;;; +1D77C;MATHEMATICAL SANS-SERIF BOLD SMALL NU;Ll;0;L; 03BD;;;;N;;;;; +1D77D;MATHEMATICAL SANS-SERIF BOLD SMALL XI;Ll;0;L; 03BE;;;;N;;;;; +1D77E;MATHEMATICAL SANS-SERIF BOLD SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; +1D77F;MATHEMATICAL SANS-SERIF BOLD SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +1D780;MATHEMATICAL SANS-SERIF BOLD SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; +1D781;MATHEMATICAL SANS-SERIF BOLD SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; +1D782;MATHEMATICAL SANS-SERIF BOLD SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; +1D783;MATHEMATICAL SANS-SERIF BOLD SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; +1D784;MATHEMATICAL SANS-SERIF BOLD SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; +1D785;MATHEMATICAL SANS-SERIF BOLD SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; +1D786;MATHEMATICAL SANS-SERIF BOLD SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; +1D787;MATHEMATICAL SANS-SERIF BOLD SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; +1D788;MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; +1D789;MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL;Sm;0;L; 2202;;;;N;;;;; +1D78A;MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; +1D78B;MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; +1D78C;MATHEMATICAL SANS-SERIF BOLD KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; +1D78D;MATHEMATICAL SANS-SERIF BOLD PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; +1D78E;MATHEMATICAL SANS-SERIF BOLD RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; +1D78F;MATHEMATICAL SANS-SERIF BOLD PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; +1D790;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; +1D791;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; +1D792;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +1D793;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; +1D794;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; +1D795;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; +1D796;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; +1D797;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; +1D798;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; +1D799;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; +1D79A;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; +1D79B;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; +1D79C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; +1D79D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; +1D79E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; +1D79F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +1D7A0;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; +1D7A1;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; +1D7A2;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; +1D7A3;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; +1D7A4;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; +1D7A5;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; +1D7A6;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; +1D7A7;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; +1D7A8;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; +1D7A9;MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA;Sm;0;L; 2207;;;;N;;;;; +1D7AA;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; +1D7AB;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; +1D7AC;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D7AD;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; +1D7AE;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; +1D7AF;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; +1D7B0;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; +1D7B1;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; +1D7B2;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; +1D7B3;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; +1D7B4;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; +1D7B5;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL MU;Ll;0;L; 03BC;;;;N;;;;; +1D7B6;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL NU;Ll;0;L; 03BD;;;;N;;;;; +1D7B7;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL XI;Ll;0;L; 03BE;;;;N;;;;; +1D7B8;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; +1D7B9;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +1D7BA;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; +1D7BB;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; +1D7BC;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; +1D7BD;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; +1D7BE;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; +1D7BF;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; +1D7C0;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; +1D7C1;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; +1D7C2;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; +1D7C3;MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;L; 2202;;;;N;;;;; +1D7C4;MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; +1D7C5;MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; +1D7C6;MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; +1D7C7;MATHEMATICAL SANS-SERIF BOLD ITALIC PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; +1D7C8;MATHEMATICAL SANS-SERIF BOLD ITALIC RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; +1D7C9;MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; +1D7CE;MATHEMATICAL BOLD DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +1D7CF;MATHEMATICAL BOLD DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +1D7D0;MATHEMATICAL BOLD DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +1D7D1;MATHEMATICAL BOLD DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +1D7D2;MATHEMATICAL BOLD DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +1D7D3;MATHEMATICAL BOLD DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +1D7D4;MATHEMATICAL BOLD DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +1D7D5;MATHEMATICAL BOLD DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +1D7D6;MATHEMATICAL BOLD DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +1D7D7;MATHEMATICAL BOLD DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +1D7D8;MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +1D7D9;MATHEMATICAL DOUBLE-STRUCK DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +1D7DA;MATHEMATICAL DOUBLE-STRUCK DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +1D7DB;MATHEMATICAL DOUBLE-STRUCK DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +1D7DC;MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +1D7DD;MATHEMATICAL DOUBLE-STRUCK DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +1D7DE;MATHEMATICAL DOUBLE-STRUCK DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +1D7DF;MATHEMATICAL DOUBLE-STRUCK DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +1D7E0;MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +1D7E1;MATHEMATICAL DOUBLE-STRUCK DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +1D7E2;MATHEMATICAL SANS-SERIF DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +1D7E3;MATHEMATICAL SANS-SERIF DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +1D7E4;MATHEMATICAL SANS-SERIF DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +1D7E5;MATHEMATICAL SANS-SERIF DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +1D7E6;MATHEMATICAL SANS-SERIF DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +1D7E7;MATHEMATICAL SANS-SERIF DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +1D7E8;MATHEMATICAL SANS-SERIF DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +1D7E9;MATHEMATICAL SANS-SERIF DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +1D7EA;MATHEMATICAL SANS-SERIF DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +1D7EB;MATHEMATICAL SANS-SERIF DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +1D7EC;MATHEMATICAL SANS-SERIF BOLD DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +1D7ED;MATHEMATICAL SANS-SERIF BOLD DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +1D7EE;MATHEMATICAL SANS-SERIF BOLD DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +1D7EF;MATHEMATICAL SANS-SERIF BOLD DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +1D7F0;MATHEMATICAL SANS-SERIF BOLD DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +1D7F1;MATHEMATICAL SANS-SERIF BOLD DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +1D7F2;MATHEMATICAL SANS-SERIF BOLD DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +1D7F3;MATHEMATICAL SANS-SERIF BOLD DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +1D7F4;MATHEMATICAL SANS-SERIF BOLD DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +1D7F5;MATHEMATICAL SANS-SERIF BOLD DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +1D7F6;MATHEMATICAL MONOSPACE DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +1D7F7;MATHEMATICAL MONOSPACE DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +1D7F8;MATHEMATICAL MONOSPACE DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +1D7F9;MATHEMATICAL MONOSPACE DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +1D7FA;MATHEMATICAL MONOSPACE DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +1D7FB;MATHEMATICAL MONOSPACE DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +1D7FC;MATHEMATICAL MONOSPACE DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +1D7FD;MATHEMATICAL MONOSPACE DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +1D7FE;MATHEMATICAL MONOSPACE DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +1D7FF;MATHEMATICAL MONOSPACE DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +20000;;Lo;0;L;;;;;N;;;;; +2A6D6;;Lo;0;L;;;;;N;;;;; +2F800;CJK COMPATIBILITY IDEOGRAPH-2F800;Lo;0;L;4E3D;;;;N;;;;; +2F801;CJK COMPATIBILITY IDEOGRAPH-2F801;Lo;0;L;4E38;;;;N;;;;; +2F802;CJK COMPATIBILITY IDEOGRAPH-2F802;Lo;0;L;4E41;;;;N;;;;; +2F803;CJK COMPATIBILITY IDEOGRAPH-2F803;Lo;0;L;20122;;;;N;;;;; +2F804;CJK COMPATIBILITY IDEOGRAPH-2F804;Lo;0;L;4F60;;;;N;;;;; +2F805;CJK COMPATIBILITY IDEOGRAPH-2F805;Lo;0;L;4FAE;;;;N;;;;; +2F806;CJK COMPATIBILITY IDEOGRAPH-2F806;Lo;0;L;4FBB;;;;N;;;;; +2F807;CJK COMPATIBILITY IDEOGRAPH-2F807;Lo;0;L;5002;;;;N;;;;; +2F808;CJK COMPATIBILITY IDEOGRAPH-2F808;Lo;0;L;507A;;;;N;;;;; +2F809;CJK COMPATIBILITY IDEOGRAPH-2F809;Lo;0;L;5099;;;;N;;;;; +2F80A;CJK COMPATIBILITY IDEOGRAPH-2F80A;Lo;0;L;50E7;;;;N;;;;; +2F80B;CJK COMPATIBILITY IDEOGRAPH-2F80B;Lo;0;L;50CF;;;;N;;;;; +2F80C;CJK COMPATIBILITY IDEOGRAPH-2F80C;Lo;0;L;349E;;;;N;;;;; +2F80D;CJK COMPATIBILITY IDEOGRAPH-2F80D;Lo;0;L;2063A;;;;N;;;;; +2F80E;CJK COMPATIBILITY IDEOGRAPH-2F80E;Lo;0;L;514D;;;;N;;;;; +2F80F;CJK COMPATIBILITY IDEOGRAPH-2F80F;Lo;0;L;5154;;;;N;;;;; +2F810;CJK COMPATIBILITY IDEOGRAPH-2F810;Lo;0;L;5164;;;;N;;;;; +2F811;CJK COMPATIBILITY IDEOGRAPH-2F811;Lo;0;L;5177;;;;N;;;;; +2F812;CJK COMPATIBILITY IDEOGRAPH-2F812;Lo;0;L;2051C;;;;N;;;;; +2F813;CJK COMPATIBILITY IDEOGRAPH-2F813;Lo;0;L;34B9;;;;N;;;;; +2F814;CJK COMPATIBILITY IDEOGRAPH-2F814;Lo;0;L;5167;;;;N;;;;; +2F815;CJK COMPATIBILITY IDEOGRAPH-2F815;Lo;0;L;518D;;;;N;;;;; +2F816;CJK COMPATIBILITY IDEOGRAPH-2F816;Lo;0;L;2054B;;;;N;;;;; +2F817;CJK COMPATIBILITY IDEOGRAPH-2F817;Lo;0;L;5197;;;;N;;;;; +2F818;CJK COMPATIBILITY IDEOGRAPH-2F818;Lo;0;L;51A4;;;;N;;;;; +2F819;CJK COMPATIBILITY IDEOGRAPH-2F819;Lo;0;L;4ECC;;;;N;;;;; +2F81A;CJK COMPATIBILITY IDEOGRAPH-2F81A;Lo;0;L;51AC;;;;N;;;;; +2F81B;CJK COMPATIBILITY IDEOGRAPH-2F81B;Lo;0;L;51B5;;;;N;;;;; +2F81C;CJK COMPATIBILITY IDEOGRAPH-2F81C;Lo;0;L;291DF;;;;N;;;;; +2F81D;CJK COMPATIBILITY IDEOGRAPH-2F81D;Lo;0;L;51F5;;;;N;;;;; +2F81E;CJK COMPATIBILITY IDEOGRAPH-2F81E;Lo;0;L;5203;;;;N;;;;; +2F81F;CJK COMPATIBILITY IDEOGRAPH-2F81F;Lo;0;L;34DF;;;;N;;;;; +2F820;CJK COMPATIBILITY IDEOGRAPH-2F820;Lo;0;L;523B;;;;N;;;;; +2F821;CJK COMPATIBILITY IDEOGRAPH-2F821;Lo;0;L;5246;;;;N;;;;; +2F822;CJK COMPATIBILITY IDEOGRAPH-2F822;Lo;0;L;5272;;;;N;;;;; +2F823;CJK COMPATIBILITY IDEOGRAPH-2F823;Lo;0;L;5277;;;;N;;;;; +2F824;CJK COMPATIBILITY IDEOGRAPH-2F824;Lo;0;L;3515;;;;N;;;;; +2F825;CJK COMPATIBILITY IDEOGRAPH-2F825;Lo;0;L;52C7;;;;N;;;;; +2F826;CJK COMPATIBILITY IDEOGRAPH-2F826;Lo;0;L;52C9;;;;N;;;;; +2F827;CJK COMPATIBILITY IDEOGRAPH-2F827;Lo;0;L;52E4;;;;N;;;;; +2F828;CJK COMPATIBILITY IDEOGRAPH-2F828;Lo;0;L;52FA;;;;N;;;;; +2F829;CJK COMPATIBILITY IDEOGRAPH-2F829;Lo;0;L;5305;;;;N;;;;; +2F82A;CJK COMPATIBILITY IDEOGRAPH-2F82A;Lo;0;L;5306;;;;N;;;;; +2F82B;CJK COMPATIBILITY IDEOGRAPH-2F82B;Lo;0;L;5317;;;;N;;;;; +2F82C;CJK COMPATIBILITY IDEOGRAPH-2F82C;Lo;0;L;5349;;;;N;;;;; +2F82D;CJK COMPATIBILITY IDEOGRAPH-2F82D;Lo;0;L;5351;;;;N;;;;; +2F82E;CJK COMPATIBILITY IDEOGRAPH-2F82E;Lo;0;L;535A;;;;N;;;;; +2F82F;CJK COMPATIBILITY IDEOGRAPH-2F82F;Lo;0;L;5373;;;;N;;;;; +2F830;CJK COMPATIBILITY IDEOGRAPH-2F830;Lo;0;L;537D;;;;N;;;;; +2F831;CJK COMPATIBILITY IDEOGRAPH-2F831;Lo;0;L;537F;;;;N;;;;; +2F832;CJK COMPATIBILITY IDEOGRAPH-2F832;Lo;0;L;537F;;;;N;;;;; +2F833;CJK COMPATIBILITY IDEOGRAPH-2F833;Lo;0;L;537F;;;;N;;;;; +2F834;CJK COMPATIBILITY IDEOGRAPH-2F834;Lo;0;L;20A2C;;;;N;;;;; +2F835;CJK COMPATIBILITY IDEOGRAPH-2F835;Lo;0;L;7070;;;;N;;;;; +2F836;CJK COMPATIBILITY IDEOGRAPH-2F836;Lo;0;L;53CA;;;;N;;;;; +2F837;CJK COMPATIBILITY IDEOGRAPH-2F837;Lo;0;L;53DF;;;;N;;;;; +2F838;CJK COMPATIBILITY IDEOGRAPH-2F838;Lo;0;L;20B63;;;;N;;;;; +2F839;CJK COMPATIBILITY IDEOGRAPH-2F839;Lo;0;L;53EB;;;;N;;;;; +2F83A;CJK COMPATIBILITY IDEOGRAPH-2F83A;Lo;0;L;53F1;;;;N;;;;; +2F83B;CJK COMPATIBILITY IDEOGRAPH-2F83B;Lo;0;L;5406;;;;N;;;;; +2F83C;CJK COMPATIBILITY IDEOGRAPH-2F83C;Lo;0;L;549E;;;;N;;;;; +2F83D;CJK COMPATIBILITY IDEOGRAPH-2F83D;Lo;0;L;5438;;;;N;;;;; +2F83E;CJK COMPATIBILITY IDEOGRAPH-2F83E;Lo;0;L;5448;;;;N;;;;; +2F83F;CJK COMPATIBILITY IDEOGRAPH-2F83F;Lo;0;L;5468;;;;N;;;;; +2F840;CJK COMPATIBILITY IDEOGRAPH-2F840;Lo;0;L;54A2;;;;N;;;;; +2F841;CJK COMPATIBILITY IDEOGRAPH-2F841;Lo;0;L;54F6;;;;N;;;;; +2F842;CJK COMPATIBILITY IDEOGRAPH-2F842;Lo;0;L;5510;;;;N;;;;; +2F843;CJK COMPATIBILITY IDEOGRAPH-2F843;Lo;0;L;5553;;;;N;;;;; +2F844;CJK COMPATIBILITY IDEOGRAPH-2F844;Lo;0;L;5563;;;;N;;;;; +2F845;CJK COMPATIBILITY IDEOGRAPH-2F845;Lo;0;L;5584;;;;N;;;;; +2F846;CJK COMPATIBILITY IDEOGRAPH-2F846;Lo;0;L;5584;;;;N;;;;; +2F847;CJK COMPATIBILITY IDEOGRAPH-2F847;Lo;0;L;5599;;;;N;;;;; +2F848;CJK COMPATIBILITY IDEOGRAPH-2F848;Lo;0;L;55AB;;;;N;;;;; +2F849;CJK COMPATIBILITY IDEOGRAPH-2F849;Lo;0;L;55B3;;;;N;;;;; +2F84A;CJK COMPATIBILITY IDEOGRAPH-2F84A;Lo;0;L;55C2;;;;N;;;;; +2F84B;CJK COMPATIBILITY IDEOGRAPH-2F84B;Lo;0;L;5716;;;;N;;;;; +2F84C;CJK COMPATIBILITY IDEOGRAPH-2F84C;Lo;0;L;5606;;;;N;;;;; +2F84D;CJK COMPATIBILITY IDEOGRAPH-2F84D;Lo;0;L;5717;;;;N;;;;; +2F84E;CJK COMPATIBILITY IDEOGRAPH-2F84E;Lo;0;L;5651;;;;N;;;;; +2F84F;CJK COMPATIBILITY IDEOGRAPH-2F84F;Lo;0;L;5674;;;;N;;;;; +2F850;CJK COMPATIBILITY IDEOGRAPH-2F850;Lo;0;L;5207;;;;N;;;;; +2F851;CJK COMPATIBILITY IDEOGRAPH-2F851;Lo;0;L;58EE;;;;N;;;;; +2F852;CJK COMPATIBILITY IDEOGRAPH-2F852;Lo;0;L;57CE;;;;N;;;;; +2F853;CJK COMPATIBILITY IDEOGRAPH-2F853;Lo;0;L;57F4;;;;N;;;;; +2F854;CJK COMPATIBILITY IDEOGRAPH-2F854;Lo;0;L;580D;;;;N;;;;; +2F855;CJK COMPATIBILITY IDEOGRAPH-2F855;Lo;0;L;578B;;;;N;;;;; +2F856;CJK COMPATIBILITY IDEOGRAPH-2F856;Lo;0;L;5832;;;;N;;;;; +2F857;CJK COMPATIBILITY IDEOGRAPH-2F857;Lo;0;L;5831;;;;N;;;;; +2F858;CJK COMPATIBILITY IDEOGRAPH-2F858;Lo;0;L;58AC;;;;N;;;;; +2F859;CJK COMPATIBILITY IDEOGRAPH-2F859;Lo;0;L;214E4;;;;N;;;;; +2F85A;CJK COMPATIBILITY IDEOGRAPH-2F85A;Lo;0;L;58F2;;;;N;;;;; +2F85B;CJK COMPATIBILITY IDEOGRAPH-2F85B;Lo;0;L;58F7;;;;N;;;;; +2F85C;CJK COMPATIBILITY IDEOGRAPH-2F85C;Lo;0;L;5906;;;;N;;;;; +2F85D;CJK COMPATIBILITY IDEOGRAPH-2F85D;Lo;0;L;591A;;;;N;;;;; +2F85E;CJK COMPATIBILITY IDEOGRAPH-2F85E;Lo;0;L;5922;;;;N;;;;; +2F85F;CJK COMPATIBILITY IDEOGRAPH-2F85F;Lo;0;L;5962;;;;N;;;;; +2F860;CJK COMPATIBILITY IDEOGRAPH-2F860;Lo;0;L;216A8;;;;N;;;;; +2F861;CJK COMPATIBILITY IDEOGRAPH-2F861;Lo;0;L;216EA;;;;N;;;;; +2F862;CJK COMPATIBILITY IDEOGRAPH-2F862;Lo;0;L;59EC;;;;N;;;;; +2F863;CJK COMPATIBILITY IDEOGRAPH-2F863;Lo;0;L;5A1B;;;;N;;;;; +2F864;CJK COMPATIBILITY IDEOGRAPH-2F864;Lo;0;L;5A27;;;;N;;;;; +2F865;CJK COMPATIBILITY IDEOGRAPH-2F865;Lo;0;L;59D8;;;;N;;;;; +2F866;CJK COMPATIBILITY IDEOGRAPH-2F866;Lo;0;L;5A66;;;;N;;;;; +2F867;CJK COMPATIBILITY IDEOGRAPH-2F867;Lo;0;L;36EE;;;;N;;;;; +2F868;CJK COMPATIBILITY IDEOGRAPH-2F868;Lo;0;L;2136A;;;;N;;;;; +2F869;CJK COMPATIBILITY IDEOGRAPH-2F869;Lo;0;L;5B08;;;;N;;;;; +2F86A;CJK COMPATIBILITY IDEOGRAPH-2F86A;Lo;0;L;5B3E;;;;N;;;;; +2F86B;CJK COMPATIBILITY IDEOGRAPH-2F86B;Lo;0;L;5B3E;;;;N;;;;; +2F86C;CJK COMPATIBILITY IDEOGRAPH-2F86C;Lo;0;L;219C8;;;;N;;;;; +2F86D;CJK COMPATIBILITY IDEOGRAPH-2F86D;Lo;0;L;5BC3;;;;N;;;;; +2F86E;CJK COMPATIBILITY IDEOGRAPH-2F86E;Lo;0;L;5BD8;;;;N;;;;; +2F86F;CJK COMPATIBILITY IDEOGRAPH-2F86F;Lo;0;L;5BE7;;;;N;;;;; +2F870;CJK COMPATIBILITY IDEOGRAPH-2F870;Lo;0;L;5BF3;;;;N;;;;; +2F871;CJK COMPATIBILITY IDEOGRAPH-2F871;Lo;0;L;21B18;;;;N;;;;; +2F872;CJK COMPATIBILITY IDEOGRAPH-2F872;Lo;0;L;5BFF;;;;N;;;;; +2F873;CJK COMPATIBILITY IDEOGRAPH-2F873;Lo;0;L;5C06;;;;N;;;;; +2F874;CJK COMPATIBILITY IDEOGRAPH-2F874;Lo;0;L;5F33;;;;N;;;;; +2F875;CJK COMPATIBILITY IDEOGRAPH-2F875;Lo;0;L;5C22;;;;N;;;;; +2F876;CJK COMPATIBILITY IDEOGRAPH-2F876;Lo;0;L;3781;;;;N;;;;; +2F877;CJK COMPATIBILITY IDEOGRAPH-2F877;Lo;0;L;5C60;;;;N;;;;; +2F878;CJK COMPATIBILITY IDEOGRAPH-2F878;Lo;0;L;5C6E;;;;N;;;;; +2F879;CJK COMPATIBILITY IDEOGRAPH-2F879;Lo;0;L;5CC0;;;;N;;;;; +2F87A;CJK COMPATIBILITY IDEOGRAPH-2F87A;Lo;0;L;5C8D;;;;N;;;;; +2F87B;CJK COMPATIBILITY IDEOGRAPH-2F87B;Lo;0;L;21DE4;;;;N;;;;; +2F87C;CJK COMPATIBILITY IDEOGRAPH-2F87C;Lo;0;L;5D43;;;;N;;;;; +2F87D;CJK COMPATIBILITY IDEOGRAPH-2F87D;Lo;0;L;21DE6;;;;N;;;;; +2F87E;CJK COMPATIBILITY IDEOGRAPH-2F87E;Lo;0;L;5D6E;;;;N;;;;; +2F87F;CJK COMPATIBILITY IDEOGRAPH-2F87F;Lo;0;L;5D6B;;;;N;;;;; +2F880;CJK COMPATIBILITY IDEOGRAPH-2F880;Lo;0;L;5D7C;;;;N;;;;; +2F881;CJK COMPATIBILITY IDEOGRAPH-2F881;Lo;0;L;5DE1;;;;N;;;;; +2F882;CJK COMPATIBILITY IDEOGRAPH-2F882;Lo;0;L;5DE2;;;;N;;;;; +2F883;CJK COMPATIBILITY IDEOGRAPH-2F883;Lo;0;L;382F;;;;N;;;;; +2F884;CJK COMPATIBILITY IDEOGRAPH-2F884;Lo;0;L;5DFD;;;;N;;;;; +2F885;CJK COMPATIBILITY IDEOGRAPH-2F885;Lo;0;L;5E28;;;;N;;;;; +2F886;CJK COMPATIBILITY IDEOGRAPH-2F886;Lo;0;L;5E3D;;;;N;;;;; +2F887;CJK COMPATIBILITY IDEOGRAPH-2F887;Lo;0;L;5E69;;;;N;;;;; +2F888;CJK COMPATIBILITY IDEOGRAPH-2F888;Lo;0;L;3862;;;;N;;;;; +2F889;CJK COMPATIBILITY IDEOGRAPH-2F889;Lo;0;L;22183;;;;N;;;;; +2F88A;CJK COMPATIBILITY IDEOGRAPH-2F88A;Lo;0;L;387C;;;;N;;;;; +2F88B;CJK COMPATIBILITY IDEOGRAPH-2F88B;Lo;0;L;5EB0;;;;N;;;;; +2F88C;CJK COMPATIBILITY IDEOGRAPH-2F88C;Lo;0;L;5EB3;;;;N;;;;; +2F88D;CJK COMPATIBILITY IDEOGRAPH-2F88D;Lo;0;L;5EB6;;;;N;;;;; +2F88E;CJK COMPATIBILITY IDEOGRAPH-2F88E;Lo;0;L;5ECA;;;;N;;;;; +2F88F;CJK COMPATIBILITY IDEOGRAPH-2F88F;Lo;0;L;2A392;;;;N;;;;; +2F890;CJK COMPATIBILITY IDEOGRAPH-2F890;Lo;0;L;5EFE;;;;N;;;;; +2F891;CJK COMPATIBILITY IDEOGRAPH-2F891;Lo;0;L;22331;;;;N;;;;; +2F892;CJK COMPATIBILITY IDEOGRAPH-2F892;Lo;0;L;22331;;;;N;;;;; +2F893;CJK COMPATIBILITY IDEOGRAPH-2F893;Lo;0;L;8201;;;;N;;;;; +2F894;CJK COMPATIBILITY IDEOGRAPH-2F894;Lo;0;L;5F22;;;;N;;;;; +2F895;CJK COMPATIBILITY IDEOGRAPH-2F895;Lo;0;L;5F22;;;;N;;;;; +2F896;CJK COMPATIBILITY IDEOGRAPH-2F896;Lo;0;L;38C7;;;;N;;;;; +2F897;CJK COMPATIBILITY IDEOGRAPH-2F897;Lo;0;L;232B8;;;;N;;;;; +2F898;CJK COMPATIBILITY IDEOGRAPH-2F898;Lo;0;L;261DA;;;;N;;;;; +2F899;CJK COMPATIBILITY IDEOGRAPH-2F899;Lo;0;L;5F62;;;;N;;;;; +2F89A;CJK COMPATIBILITY IDEOGRAPH-2F89A;Lo;0;L;5F6B;;;;N;;;;; +2F89B;CJK COMPATIBILITY IDEOGRAPH-2F89B;Lo;0;L;38E3;;;;N;;;;; +2F89C;CJK COMPATIBILITY IDEOGRAPH-2F89C;Lo;0;L;5F9A;;;;N;;;;; +2F89D;CJK COMPATIBILITY IDEOGRAPH-2F89D;Lo;0;L;5FCD;;;;N;;;;; +2F89E;CJK COMPATIBILITY IDEOGRAPH-2F89E;Lo;0;L;5FD7;;;;N;;;;; +2F89F;CJK COMPATIBILITY IDEOGRAPH-2F89F;Lo;0;L;5FF9;;;;N;;;;; +2F8A0;CJK COMPATIBILITY IDEOGRAPH-2F8A0;Lo;0;L;6081;;;;N;;;;; +2F8A1;CJK COMPATIBILITY IDEOGRAPH-2F8A1;Lo;0;L;393A;;;;N;;;;; +2F8A2;CJK COMPATIBILITY IDEOGRAPH-2F8A2;Lo;0;L;391C;;;;N;;;;; +2F8A3;CJK COMPATIBILITY IDEOGRAPH-2F8A3;Lo;0;L;6094;;;;N;;;;; +2F8A4;CJK COMPATIBILITY IDEOGRAPH-2F8A4;Lo;0;L;226D4;;;;N;;;;; +2F8A5;CJK COMPATIBILITY IDEOGRAPH-2F8A5;Lo;0;L;60C7;;;;N;;;;; +2F8A6;CJK COMPATIBILITY IDEOGRAPH-2F8A6;Lo;0;L;6148;;;;N;;;;; +2F8A7;CJK COMPATIBILITY IDEOGRAPH-2F8A7;Lo;0;L;614C;;;;N;;;;; +2F8A8;CJK COMPATIBILITY IDEOGRAPH-2F8A8;Lo;0;L;614E;;;;N;;;;; +2F8A9;CJK COMPATIBILITY IDEOGRAPH-2F8A9;Lo;0;L;614C;;;;N;;;;; +2F8AA;CJK COMPATIBILITY IDEOGRAPH-2F8AA;Lo;0;L;617A;;;;N;;;;; +2F8AB;CJK COMPATIBILITY IDEOGRAPH-2F8AB;Lo;0;L;618E;;;;N;;;;; +2F8AC;CJK COMPATIBILITY IDEOGRAPH-2F8AC;Lo;0;L;61B2;;;;N;;;;; +2F8AD;CJK COMPATIBILITY IDEOGRAPH-2F8AD;Lo;0;L;61A4;;;;N;;;;; +2F8AE;CJK COMPATIBILITY IDEOGRAPH-2F8AE;Lo;0;L;61AF;;;;N;;;;; +2F8AF;CJK COMPATIBILITY IDEOGRAPH-2F8AF;Lo;0;L;61DE;;;;N;;;;; +2F8B0;CJK COMPATIBILITY IDEOGRAPH-2F8B0;Lo;0;L;61F2;;;;N;;;;; +2F8B1;CJK COMPATIBILITY IDEOGRAPH-2F8B1;Lo;0;L;61F6;;;;N;;;;; +2F8B2;CJK COMPATIBILITY IDEOGRAPH-2F8B2;Lo;0;L;6210;;;;N;;;;; +2F8B3;CJK COMPATIBILITY IDEOGRAPH-2F8B3;Lo;0;L;621B;;;;N;;;;; +2F8B4;CJK COMPATIBILITY IDEOGRAPH-2F8B4;Lo;0;L;625D;;;;N;;;;; +2F8B5;CJK COMPATIBILITY IDEOGRAPH-2F8B5;Lo;0;L;62B1;;;;N;;;;; +2F8B6;CJK COMPATIBILITY IDEOGRAPH-2F8B6;Lo;0;L;62D4;;;;N;;;;; +2F8B7;CJK COMPATIBILITY IDEOGRAPH-2F8B7;Lo;0;L;6350;;;;N;;;;; +2F8B8;CJK COMPATIBILITY IDEOGRAPH-2F8B8;Lo;0;L;22B0C;;;;N;;;;; +2F8B9;CJK COMPATIBILITY IDEOGRAPH-2F8B9;Lo;0;L;633D;;;;N;;;;; +2F8BA;CJK COMPATIBILITY IDEOGRAPH-2F8BA;Lo;0;L;62FC;;;;N;;;;; +2F8BB;CJK COMPATIBILITY IDEOGRAPH-2F8BB;Lo;0;L;6368;;;;N;;;;; +2F8BC;CJK COMPATIBILITY IDEOGRAPH-2F8BC;Lo;0;L;6383;;;;N;;;;; +2F8BD;CJK COMPATIBILITY IDEOGRAPH-2F8BD;Lo;0;L;63E4;;;;N;;;;; +2F8BE;CJK COMPATIBILITY IDEOGRAPH-2F8BE;Lo;0;L;22BF1;;;;N;;;;; +2F8BF;CJK COMPATIBILITY IDEOGRAPH-2F8BF;Lo;0;L;6422;;;;N;;;;; +2F8C0;CJK COMPATIBILITY IDEOGRAPH-2F8C0;Lo;0;L;63C5;;;;N;;;;; +2F8C1;CJK COMPATIBILITY IDEOGRAPH-2F8C1;Lo;0;L;63A9;;;;N;;;;; +2F8C2;CJK COMPATIBILITY IDEOGRAPH-2F8C2;Lo;0;L;3A2E;;;;N;;;;; +2F8C3;CJK COMPATIBILITY IDEOGRAPH-2F8C3;Lo;0;L;6469;;;;N;;;;; +2F8C4;CJK COMPATIBILITY IDEOGRAPH-2F8C4;Lo;0;L;647E;;;;N;;;;; +2F8C5;CJK COMPATIBILITY IDEOGRAPH-2F8C5;Lo;0;L;649D;;;;N;;;;; +2F8C6;CJK COMPATIBILITY IDEOGRAPH-2F8C6;Lo;0;L;6477;;;;N;;;;; +2F8C7;CJK COMPATIBILITY IDEOGRAPH-2F8C7;Lo;0;L;3A6C;;;;N;;;;; +2F8C8;CJK COMPATIBILITY IDEOGRAPH-2F8C8;Lo;0;L;654F;;;;N;;;;; +2F8C9;CJK COMPATIBILITY IDEOGRAPH-2F8C9;Lo;0;L;656C;;;;N;;;;; +2F8CA;CJK COMPATIBILITY IDEOGRAPH-2F8CA;Lo;0;L;2300A;;;;N;;;;; +2F8CB;CJK COMPATIBILITY IDEOGRAPH-2F8CB;Lo;0;L;65E3;;;;N;;;;; +2F8CC;CJK COMPATIBILITY IDEOGRAPH-2F8CC;Lo;0;L;66F8;;;;N;;;;; +2F8CD;CJK COMPATIBILITY IDEOGRAPH-2F8CD;Lo;0;L;6649;;;;N;;;;; +2F8CE;CJK COMPATIBILITY IDEOGRAPH-2F8CE;Lo;0;L;3B19;;;;N;;;;; +2F8CF;CJK COMPATIBILITY IDEOGRAPH-2F8CF;Lo;0;L;6691;;;;N;;;;; +2F8D0;CJK COMPATIBILITY IDEOGRAPH-2F8D0;Lo;0;L;3B08;;;;N;;;;; +2F8D1;CJK COMPATIBILITY IDEOGRAPH-2F8D1;Lo;0;L;3AE4;;;;N;;;;; +2F8D2;CJK COMPATIBILITY IDEOGRAPH-2F8D2;Lo;0;L;5192;;;;N;;;;; +2F8D3;CJK COMPATIBILITY IDEOGRAPH-2F8D3;Lo;0;L;5195;;;;N;;;;; +2F8D4;CJK COMPATIBILITY IDEOGRAPH-2F8D4;Lo;0;L;6700;;;;N;;;;; +2F8D5;CJK COMPATIBILITY IDEOGRAPH-2F8D5;Lo;0;L;669C;;;;N;;;;; +2F8D6;CJK COMPATIBILITY IDEOGRAPH-2F8D6;Lo;0;L;80AD;;;;N;;;;; +2F8D7;CJK COMPATIBILITY IDEOGRAPH-2F8D7;Lo;0;L;43D9;;;;N;;;;; +2F8D8;CJK COMPATIBILITY IDEOGRAPH-2F8D8;Lo;0;L;6717;;;;N;;;;; +2F8D9;CJK COMPATIBILITY IDEOGRAPH-2F8D9;Lo;0;L;671B;;;;N;;;;; +2F8DA;CJK COMPATIBILITY IDEOGRAPH-2F8DA;Lo;0;L;6721;;;;N;;;;; +2F8DB;CJK COMPATIBILITY IDEOGRAPH-2F8DB;Lo;0;L;675E;;;;N;;;;; +2F8DC;CJK COMPATIBILITY IDEOGRAPH-2F8DC;Lo;0;L;6753;;;;N;;;;; +2F8DD;CJK COMPATIBILITY IDEOGRAPH-2F8DD;Lo;0;L;233C3;;;;N;;;;; +2F8DE;CJK COMPATIBILITY IDEOGRAPH-2F8DE;Lo;0;L;3B49;;;;N;;;;; +2F8DF;CJK COMPATIBILITY IDEOGRAPH-2F8DF;Lo;0;L;67FA;;;;N;;;;; +2F8E0;CJK COMPATIBILITY IDEOGRAPH-2F8E0;Lo;0;L;6785;;;;N;;;;; +2F8E1;CJK COMPATIBILITY IDEOGRAPH-2F8E1;Lo;0;L;6852;;;;N;;;;; +2F8E2;CJK COMPATIBILITY IDEOGRAPH-2F8E2;Lo;0;L;6885;;;;N;;;;; +2F8E3;CJK COMPATIBILITY IDEOGRAPH-2F8E3;Lo;0;L;2346D;;;;N;;;;; +2F8E4;CJK COMPATIBILITY IDEOGRAPH-2F8E4;Lo;0;L;688E;;;;N;;;;; +2F8E5;CJK COMPATIBILITY IDEOGRAPH-2F8E5;Lo;0;L;681F;;;;N;;;;; +2F8E6;CJK COMPATIBILITY IDEOGRAPH-2F8E6;Lo;0;L;6914;;;;N;;;;; +2F8E7;CJK COMPATIBILITY IDEOGRAPH-2F8E7;Lo;0;L;3B9D;;;;N;;;;; +2F8E8;CJK COMPATIBILITY IDEOGRAPH-2F8E8;Lo;0;L;6942;;;;N;;;;; +2F8E9;CJK COMPATIBILITY IDEOGRAPH-2F8E9;Lo;0;L;69A3;;;;N;;;;; +2F8EA;CJK COMPATIBILITY IDEOGRAPH-2F8EA;Lo;0;L;69EA;;;;N;;;;; +2F8EB;CJK COMPATIBILITY IDEOGRAPH-2F8EB;Lo;0;L;6AA8;;;;N;;;;; +2F8EC;CJK COMPATIBILITY IDEOGRAPH-2F8EC;Lo;0;L;236A3;;;;N;;;;; +2F8ED;CJK COMPATIBILITY IDEOGRAPH-2F8ED;Lo;0;L;6ADB;;;;N;;;;; +2F8EE;CJK COMPATIBILITY IDEOGRAPH-2F8EE;Lo;0;L;3C18;;;;N;;;;; +2F8EF;CJK COMPATIBILITY IDEOGRAPH-2F8EF;Lo;0;L;6B21;;;;N;;;;; +2F8F0;CJK COMPATIBILITY IDEOGRAPH-2F8F0;Lo;0;L;238A7;;;;N;;;;; +2F8F1;CJK COMPATIBILITY IDEOGRAPH-2F8F1;Lo;0;L;6B54;;;;N;;;;; +2F8F2;CJK COMPATIBILITY IDEOGRAPH-2F8F2;Lo;0;L;3C4E;;;;N;;;;; +2F8F3;CJK COMPATIBILITY IDEOGRAPH-2F8F3;Lo;0;L;6B72;;;;N;;;;; +2F8F4;CJK COMPATIBILITY IDEOGRAPH-2F8F4;Lo;0;L;6B9F;;;;N;;;;; +2F8F5;CJK COMPATIBILITY IDEOGRAPH-2F8F5;Lo;0;L;6BBA;;;;N;;;;; +2F8F6;CJK COMPATIBILITY IDEOGRAPH-2F8F6;Lo;0;L;6BBB;;;;N;;;;; +2F8F7;CJK COMPATIBILITY IDEOGRAPH-2F8F7;Lo;0;L;23A8D;;;;N;;;;; +2F8F8;CJK COMPATIBILITY IDEOGRAPH-2F8F8;Lo;0;L;21D0B;;;;N;;;;; +2F8F9;CJK COMPATIBILITY IDEOGRAPH-2F8F9;Lo;0;L;23AFA;;;;N;;;;; +2F8FA;CJK COMPATIBILITY IDEOGRAPH-2F8FA;Lo;0;L;6C4E;;;;N;;;;; +2F8FB;CJK COMPATIBILITY IDEOGRAPH-2F8FB;Lo;0;L;23CBC;;;;N;;;;; +2F8FC;CJK COMPATIBILITY IDEOGRAPH-2F8FC;Lo;0;L;6CBF;;;;N;;;;; +2F8FD;CJK COMPATIBILITY IDEOGRAPH-2F8FD;Lo;0;L;6CCD;;;;N;;;;; +2F8FE;CJK COMPATIBILITY IDEOGRAPH-2F8FE;Lo;0;L;6C67;;;;N;;;;; +2F8FF;CJK COMPATIBILITY IDEOGRAPH-2F8FF;Lo;0;L;6D16;;;;N;;;;; +2F900;CJK COMPATIBILITY IDEOGRAPH-2F900;Lo;0;L;6D3E;;;;N;;;;; +2F901;CJK COMPATIBILITY IDEOGRAPH-2F901;Lo;0;L;6D77;;;;N;;;;; +2F902;CJK COMPATIBILITY IDEOGRAPH-2F902;Lo;0;L;6D41;;;;N;;;;; +2F903;CJK COMPATIBILITY IDEOGRAPH-2F903;Lo;0;L;6D69;;;;N;;;;; +2F904;CJK COMPATIBILITY IDEOGRAPH-2F904;Lo;0;L;6D78;;;;N;;;;; +2F905;CJK COMPATIBILITY IDEOGRAPH-2F905;Lo;0;L;6D85;;;;N;;;;; +2F906;CJK COMPATIBILITY IDEOGRAPH-2F906;Lo;0;L;23D1E;;;;N;;;;; +2F907;CJK COMPATIBILITY IDEOGRAPH-2F907;Lo;0;L;6D34;;;;N;;;;; +2F908;CJK COMPATIBILITY IDEOGRAPH-2F908;Lo;0;L;6E2F;;;;N;;;;; +2F909;CJK COMPATIBILITY IDEOGRAPH-2F909;Lo;0;L;6E6E;;;;N;;;;; +2F90A;CJK COMPATIBILITY IDEOGRAPH-2F90A;Lo;0;L;3D33;;;;N;;;;; +2F90B;CJK COMPATIBILITY IDEOGRAPH-2F90B;Lo;0;L;6ECB;;;;N;;;;; +2F90C;CJK COMPATIBILITY IDEOGRAPH-2F90C;Lo;0;L;6EC7;;;;N;;;;; +2F90D;CJK COMPATIBILITY IDEOGRAPH-2F90D;Lo;0;L;23ED1;;;;N;;;;; +2F90E;CJK COMPATIBILITY IDEOGRAPH-2F90E;Lo;0;L;6DF9;;;;N;;;;; +2F90F;CJK COMPATIBILITY IDEOGRAPH-2F90F;Lo;0;L;6F6E;;;;N;;;;; +2F910;CJK COMPATIBILITY IDEOGRAPH-2F910;Lo;0;L;23F5E;;;;N;;;;; +2F911;CJK COMPATIBILITY IDEOGRAPH-2F911;Lo;0;L;23F8E;;;;N;;;;; +2F912;CJK COMPATIBILITY IDEOGRAPH-2F912;Lo;0;L;6FC6;;;;N;;;;; +2F913;CJK COMPATIBILITY IDEOGRAPH-2F913;Lo;0;L;7039;;;;N;;;;; +2F914;CJK COMPATIBILITY IDEOGRAPH-2F914;Lo;0;L;701E;;;;N;;;;; +2F915;CJK COMPATIBILITY IDEOGRAPH-2F915;Lo;0;L;701B;;;;N;;;;; +2F916;CJK COMPATIBILITY IDEOGRAPH-2F916;Lo;0;L;3D96;;;;N;;;;; +2F917;CJK COMPATIBILITY IDEOGRAPH-2F917;Lo;0;L;704A;;;;N;;;;; +2F918;CJK COMPATIBILITY IDEOGRAPH-2F918;Lo;0;L;707D;;;;N;;;;; +2F919;CJK COMPATIBILITY IDEOGRAPH-2F919;Lo;0;L;7077;;;;N;;;;; +2F91A;CJK COMPATIBILITY IDEOGRAPH-2F91A;Lo;0;L;70AD;;;;N;;;;; +2F91B;CJK COMPATIBILITY IDEOGRAPH-2F91B;Lo;0;L;20525;;;;N;;;;; +2F91C;CJK COMPATIBILITY IDEOGRAPH-2F91C;Lo;0;L;7145;;;;N;;;;; +2F91D;CJK COMPATIBILITY IDEOGRAPH-2F91D;Lo;0;L;24263;;;;N;;;;; +2F91E;CJK COMPATIBILITY IDEOGRAPH-2F91E;Lo;0;L;719C;;;;N;;;;; +2F91F;CJK COMPATIBILITY IDEOGRAPH-2F91F;Lo;0;L;43AB;;;;N;;;;; +2F920;CJK COMPATIBILITY IDEOGRAPH-2F920;Lo;0;L;7228;;;;N;;;;; +2F921;CJK COMPATIBILITY IDEOGRAPH-2F921;Lo;0;L;7235;;;;N;;;;; +2F922;CJK COMPATIBILITY IDEOGRAPH-2F922;Lo;0;L;7250;;;;N;;;;; +2F923;CJK COMPATIBILITY IDEOGRAPH-2F923;Lo;0;L;24608;;;;N;;;;; +2F924;CJK COMPATIBILITY IDEOGRAPH-2F924;Lo;0;L;7280;;;;N;;;;; +2F925;CJK COMPATIBILITY IDEOGRAPH-2F925;Lo;0;L;7295;;;;N;;;;; +2F926;CJK COMPATIBILITY IDEOGRAPH-2F926;Lo;0;L;24735;;;;N;;;;; +2F927;CJK COMPATIBILITY IDEOGRAPH-2F927;Lo;0;L;24814;;;;N;;;;; +2F928;CJK COMPATIBILITY IDEOGRAPH-2F928;Lo;0;L;737A;;;;N;;;;; +2F929;CJK COMPATIBILITY IDEOGRAPH-2F929;Lo;0;L;738B;;;;N;;;;; +2F92A;CJK COMPATIBILITY IDEOGRAPH-2F92A;Lo;0;L;3EAC;;;;N;;;;; +2F92B;CJK COMPATIBILITY IDEOGRAPH-2F92B;Lo;0;L;73A5;;;;N;;;;; +2F92C;CJK COMPATIBILITY IDEOGRAPH-2F92C;Lo;0;L;3EB8;;;;N;;;;; +2F92D;CJK COMPATIBILITY IDEOGRAPH-2F92D;Lo;0;L;3EB8;;;;N;;;;; +2F92E;CJK COMPATIBILITY IDEOGRAPH-2F92E;Lo;0;L;7447;;;;N;;;;; +2F92F;CJK COMPATIBILITY IDEOGRAPH-2F92F;Lo;0;L;745C;;;;N;;;;; +2F930;CJK COMPATIBILITY IDEOGRAPH-2F930;Lo;0;L;7471;;;;N;;;;; +2F931;CJK COMPATIBILITY IDEOGRAPH-2F931;Lo;0;L;7485;;;;N;;;;; +2F932;CJK COMPATIBILITY IDEOGRAPH-2F932;Lo;0;L;74CA;;;;N;;;;; +2F933;CJK COMPATIBILITY IDEOGRAPH-2F933;Lo;0;L;3F1B;;;;N;;;;; +2F934;CJK COMPATIBILITY IDEOGRAPH-2F934;Lo;0;L;7524;;;;N;;;;; +2F935;CJK COMPATIBILITY IDEOGRAPH-2F935;Lo;0;L;24C36;;;;N;;;;; +2F936;CJK COMPATIBILITY IDEOGRAPH-2F936;Lo;0;L;753E;;;;N;;;;; +2F937;CJK COMPATIBILITY IDEOGRAPH-2F937;Lo;0;L;24C92;;;;N;;;;; +2F938;CJK COMPATIBILITY IDEOGRAPH-2F938;Lo;0;L;7570;;;;N;;;;; +2F939;CJK COMPATIBILITY IDEOGRAPH-2F939;Lo;0;L;2219F;;;;N;;;;; +2F93A;CJK COMPATIBILITY IDEOGRAPH-2F93A;Lo;0;L;7610;;;;N;;;;; +2F93B;CJK COMPATIBILITY IDEOGRAPH-2F93B;Lo;0;L;24FA1;;;;N;;;;; +2F93C;CJK COMPATIBILITY IDEOGRAPH-2F93C;Lo;0;L;24FB8;;;;N;;;;; +2F93D;CJK COMPATIBILITY IDEOGRAPH-2F93D;Lo;0;L;25044;;;;N;;;;; +2F93E;CJK COMPATIBILITY IDEOGRAPH-2F93E;Lo;0;L;3FFC;;;;N;;;;; +2F93F;CJK COMPATIBILITY IDEOGRAPH-2F93F;Lo;0;L;4008;;;;N;;;;; +2F940;CJK COMPATIBILITY IDEOGRAPH-2F940;Lo;0;L;76F4;;;;N;;;;; +2F941;CJK COMPATIBILITY IDEOGRAPH-2F941;Lo;0;L;250F3;;;;N;;;;; +2F942;CJK COMPATIBILITY IDEOGRAPH-2F942;Lo;0;L;250F2;;;;N;;;;; +2F943;CJK COMPATIBILITY IDEOGRAPH-2F943;Lo;0;L;25119;;;;N;;;;; +2F944;CJK COMPATIBILITY IDEOGRAPH-2F944;Lo;0;L;25133;;;;N;;;;; +2F945;CJK COMPATIBILITY IDEOGRAPH-2F945;Lo;0;L;771E;;;;N;;;;; +2F946;CJK COMPATIBILITY IDEOGRAPH-2F946;Lo;0;L;771F;;;;N;;;;; +2F947;CJK COMPATIBILITY IDEOGRAPH-2F947;Lo;0;L;771F;;;;N;;;;; +2F948;CJK COMPATIBILITY IDEOGRAPH-2F948;Lo;0;L;774A;;;;N;;;;; +2F949;CJK COMPATIBILITY IDEOGRAPH-2F949;Lo;0;L;4039;;;;N;;;;; +2F94A;CJK COMPATIBILITY IDEOGRAPH-2F94A;Lo;0;L;778B;;;;N;;;;; +2F94B;CJK COMPATIBILITY IDEOGRAPH-2F94B;Lo;0;L;4046;;;;N;;;;; +2F94C;CJK COMPATIBILITY IDEOGRAPH-2F94C;Lo;0;L;4096;;;;N;;;;; +2F94D;CJK COMPATIBILITY IDEOGRAPH-2F94D;Lo;0;L;2541D;;;;N;;;;; +2F94E;CJK COMPATIBILITY IDEOGRAPH-2F94E;Lo;0;L;784E;;;;N;;;;; +2F94F;CJK COMPATIBILITY IDEOGRAPH-2F94F;Lo;0;L;788C;;;;N;;;;; +2F950;CJK COMPATIBILITY IDEOGRAPH-2F950;Lo;0;L;78CC;;;;N;;;;; +2F951;CJK COMPATIBILITY IDEOGRAPH-2F951;Lo;0;L;40E3;;;;N;;;;; +2F952;CJK COMPATIBILITY IDEOGRAPH-2F952;Lo;0;L;25626;;;;N;;;;; +2F953;CJK COMPATIBILITY IDEOGRAPH-2F953;Lo;0;L;7956;;;;N;;;;; +2F954;CJK COMPATIBILITY IDEOGRAPH-2F954;Lo;0;L;2569A;;;;N;;;;; +2F955;CJK COMPATIBILITY IDEOGRAPH-2F955;Lo;0;L;256C5;;;;N;;;;; +2F956;CJK COMPATIBILITY IDEOGRAPH-2F956;Lo;0;L;798F;;;;N;;;;; +2F957;CJK COMPATIBILITY IDEOGRAPH-2F957;Lo;0;L;79EB;;;;N;;;;; +2F958;CJK COMPATIBILITY IDEOGRAPH-2F958;Lo;0;L;412F;;;;N;;;;; +2F959;CJK COMPATIBILITY IDEOGRAPH-2F959;Lo;0;L;7A40;;;;N;;;;; +2F95A;CJK COMPATIBILITY IDEOGRAPH-2F95A;Lo;0;L;7A4A;;;;N;;;;; +2F95B;CJK COMPATIBILITY IDEOGRAPH-2F95B;Lo;0;L;7A4F;;;;N;;;;; +2F95C;CJK COMPATIBILITY IDEOGRAPH-2F95C;Lo;0;L;2597C;;;;N;;;;; +2F95D;CJK COMPATIBILITY IDEOGRAPH-2F95D;Lo;0;L;25AA7;;;;N;;;;; +2F95E;CJK COMPATIBILITY IDEOGRAPH-2F95E;Lo;0;L;25AA7;;;;N;;;;; +2F95F;CJK COMPATIBILITY IDEOGRAPH-2F95F;Lo;0;L;7AAE;;;;N;;;;; +2F960;CJK COMPATIBILITY IDEOGRAPH-2F960;Lo;0;L;4202;;;;N;;;;; +2F961;CJK COMPATIBILITY IDEOGRAPH-2F961;Lo;0;L;25BAB;;;;N;;;;; +2F962;CJK COMPATIBILITY IDEOGRAPH-2F962;Lo;0;L;7BC6;;;;N;;;;; +2F963;CJK COMPATIBILITY IDEOGRAPH-2F963;Lo;0;L;7BC9;;;;N;;;;; +2F964;CJK COMPATIBILITY IDEOGRAPH-2F964;Lo;0;L;4227;;;;N;;;;; +2F965;CJK COMPATIBILITY IDEOGRAPH-2F965;Lo;0;L;25C80;;;;N;;;;; +2F966;CJK COMPATIBILITY IDEOGRAPH-2F966;Lo;0;L;7CD2;;;;N;;;;; +2F967;CJK COMPATIBILITY IDEOGRAPH-2F967;Lo;0;L;42A0;;;;N;;;;; +2F968;CJK COMPATIBILITY IDEOGRAPH-2F968;Lo;0;L;7CE8;;;;N;;;;; +2F969;CJK COMPATIBILITY IDEOGRAPH-2F969;Lo;0;L;7CE3;;;;N;;;;; +2F96A;CJK COMPATIBILITY IDEOGRAPH-2F96A;Lo;0;L;7D00;;;;N;;;;; +2F96B;CJK COMPATIBILITY IDEOGRAPH-2F96B;Lo;0;L;25F86;;;;N;;;;; +2F96C;CJK COMPATIBILITY IDEOGRAPH-2F96C;Lo;0;L;7D63;;;;N;;;;; +2F96D;CJK COMPATIBILITY IDEOGRAPH-2F96D;Lo;0;L;4301;;;;N;;;;; +2F96E;CJK COMPATIBILITY IDEOGRAPH-2F96E;Lo;0;L;7DC7;;;;N;;;;; +2F96F;CJK COMPATIBILITY IDEOGRAPH-2F96F;Lo;0;L;7E02;;;;N;;;;; +2F970;CJK COMPATIBILITY IDEOGRAPH-2F970;Lo;0;L;7E45;;;;N;;;;; +2F971;CJK COMPATIBILITY IDEOGRAPH-2F971;Lo;0;L;4334;;;;N;;;;; +2F972;CJK COMPATIBILITY IDEOGRAPH-2F972;Lo;0;L;26228;;;;N;;;;; +2F973;CJK COMPATIBILITY IDEOGRAPH-2F973;Lo;0;L;26247;;;;N;;;;; +2F974;CJK COMPATIBILITY IDEOGRAPH-2F974;Lo;0;L;4359;;;;N;;;;; +2F975;CJK COMPATIBILITY IDEOGRAPH-2F975;Lo;0;L;262D9;;;;N;;;;; +2F976;CJK COMPATIBILITY IDEOGRAPH-2F976;Lo;0;L;7F7A;;;;N;;;;; +2F977;CJK COMPATIBILITY IDEOGRAPH-2F977;Lo;0;L;2633E;;;;N;;;;; +2F978;CJK COMPATIBILITY IDEOGRAPH-2F978;Lo;0;L;7F95;;;;N;;;;; +2F979;CJK COMPATIBILITY IDEOGRAPH-2F979;Lo;0;L;7FFA;;;;N;;;;; +2F97A;CJK COMPATIBILITY IDEOGRAPH-2F97A;Lo;0;L;8005;;;;N;;;;; +2F97B;CJK COMPATIBILITY IDEOGRAPH-2F97B;Lo;0;L;264DA;;;;N;;;;; +2F97C;CJK COMPATIBILITY IDEOGRAPH-2F97C;Lo;0;L;26523;;;;N;;;;; +2F97D;CJK COMPATIBILITY IDEOGRAPH-2F97D;Lo;0;L;8060;;;;N;;;;; +2F97E;CJK COMPATIBILITY IDEOGRAPH-2F97E;Lo;0;L;265A8;;;;N;;;;; +2F97F;CJK COMPATIBILITY IDEOGRAPH-2F97F;Lo;0;L;8070;;;;N;;;;; +2F980;CJK COMPATIBILITY IDEOGRAPH-2F980;Lo;0;L;2335F;;;;N;;;;; +2F981;CJK COMPATIBILITY IDEOGRAPH-2F981;Lo;0;L;43D5;;;;N;;;;; +2F982;CJK COMPATIBILITY IDEOGRAPH-2F982;Lo;0;L;80B2;;;;N;;;;; +2F983;CJK COMPATIBILITY IDEOGRAPH-2F983;Lo;0;L;8103;;;;N;;;;; +2F984;CJK COMPATIBILITY IDEOGRAPH-2F984;Lo;0;L;440B;;;;N;;;;; +2F985;CJK COMPATIBILITY IDEOGRAPH-2F985;Lo;0;L;813E;;;;N;;;;; +2F986;CJK COMPATIBILITY IDEOGRAPH-2F986;Lo;0;L;5AB5;;;;N;;;;; +2F987;CJK COMPATIBILITY IDEOGRAPH-2F987;Lo;0;L;267A7;;;;N;;;;; +2F988;CJK COMPATIBILITY IDEOGRAPH-2F988;Lo;0;L;267B5;;;;N;;;;; +2F989;CJK COMPATIBILITY IDEOGRAPH-2F989;Lo;0;L;23393;;;;N;;;;; +2F98A;CJK COMPATIBILITY IDEOGRAPH-2F98A;Lo;0;L;2339C;;;;N;;;;; +2F98B;CJK COMPATIBILITY IDEOGRAPH-2F98B;Lo;0;L;8201;;;;N;;;;; +2F98C;CJK COMPATIBILITY IDEOGRAPH-2F98C;Lo;0;L;8204;;;;N;;;;; +2F98D;CJK COMPATIBILITY IDEOGRAPH-2F98D;Lo;0;L;8F9E;;;;N;;;;; +2F98E;CJK COMPATIBILITY IDEOGRAPH-2F98E;Lo;0;L;446B;;;;N;;;;; +2F98F;CJK COMPATIBILITY IDEOGRAPH-2F98F;Lo;0;L;8291;;;;N;;;;; +2F990;CJK COMPATIBILITY IDEOGRAPH-2F990;Lo;0;L;828B;;;;N;;;;; +2F991;CJK COMPATIBILITY IDEOGRAPH-2F991;Lo;0;L;829D;;;;N;;;;; +2F992;CJK COMPATIBILITY IDEOGRAPH-2F992;Lo;0;L;52B3;;;;N;;;;; +2F993;CJK COMPATIBILITY IDEOGRAPH-2F993;Lo;0;L;82B1;;;;N;;;;; +2F994;CJK COMPATIBILITY IDEOGRAPH-2F994;Lo;0;L;82B3;;;;N;;;;; +2F995;CJK COMPATIBILITY IDEOGRAPH-2F995;Lo;0;L;82BD;;;;N;;;;; +2F996;CJK COMPATIBILITY IDEOGRAPH-2F996;Lo;0;L;82E6;;;;N;;;;; +2F997;CJK COMPATIBILITY IDEOGRAPH-2F997;Lo;0;L;26B3C;;;;N;;;;; +2F998;CJK COMPATIBILITY IDEOGRAPH-2F998;Lo;0;L;82E5;;;;N;;;;; +2F999;CJK COMPATIBILITY IDEOGRAPH-2F999;Lo;0;L;831D;;;;N;;;;; +2F99A;CJK COMPATIBILITY IDEOGRAPH-2F99A;Lo;0;L;8363;;;;N;;;;; +2F99B;CJK COMPATIBILITY IDEOGRAPH-2F99B;Lo;0;L;83AD;;;;N;;;;; +2F99C;CJK COMPATIBILITY IDEOGRAPH-2F99C;Lo;0;L;8323;;;;N;;;;; +2F99D;CJK COMPATIBILITY IDEOGRAPH-2F99D;Lo;0;L;83BD;;;;N;;;;; +2F99E;CJK COMPATIBILITY IDEOGRAPH-2F99E;Lo;0;L;83E7;;;;N;;;;; +2F99F;CJK COMPATIBILITY IDEOGRAPH-2F99F;Lo;0;L;8457;;;;N;;;;; +2F9A0;CJK COMPATIBILITY IDEOGRAPH-2F9A0;Lo;0;L;8353;;;;N;;;;; +2F9A1;CJK COMPATIBILITY IDEOGRAPH-2F9A1;Lo;0;L;83CA;;;;N;;;;; +2F9A2;CJK COMPATIBILITY IDEOGRAPH-2F9A2;Lo;0;L;83CC;;;;N;;;;; +2F9A3;CJK COMPATIBILITY IDEOGRAPH-2F9A3;Lo;0;L;83DC;;;;N;;;;; +2F9A4;CJK COMPATIBILITY IDEOGRAPH-2F9A4;Lo;0;L;26C36;;;;N;;;;; +2F9A5;CJK COMPATIBILITY IDEOGRAPH-2F9A5;Lo;0;L;26D6B;;;;N;;;;; +2F9A6;CJK COMPATIBILITY IDEOGRAPH-2F9A6;Lo;0;L;26CD5;;;;N;;;;; +2F9A7;CJK COMPATIBILITY IDEOGRAPH-2F9A7;Lo;0;L;452B;;;;N;;;;; +2F9A8;CJK COMPATIBILITY IDEOGRAPH-2F9A8;Lo;0;L;84F1;;;;N;;;;; +2F9A9;CJK COMPATIBILITY IDEOGRAPH-2F9A9;Lo;0;L;84F3;;;;N;;;;; +2F9AA;CJK COMPATIBILITY IDEOGRAPH-2F9AA;Lo;0;L;8516;;;;N;;;;; +2F9AB;CJK COMPATIBILITY IDEOGRAPH-2F9AB;Lo;0;L;273CA;;;;N;;;;; +2F9AC;CJK COMPATIBILITY IDEOGRAPH-2F9AC;Lo;0;L;8564;;;;N;;;;; +2F9AD;CJK COMPATIBILITY IDEOGRAPH-2F9AD;Lo;0;L;26F2C;;;;N;;;;; +2F9AE;CJK COMPATIBILITY IDEOGRAPH-2F9AE;Lo;0;L;455D;;;;N;;;;; +2F9AF;CJK COMPATIBILITY IDEOGRAPH-2F9AF;Lo;0;L;4561;;;;N;;;;; +2F9B0;CJK COMPATIBILITY IDEOGRAPH-2F9B0;Lo;0;L;26FB1;;;;N;;;;; +2F9B1;CJK COMPATIBILITY IDEOGRAPH-2F9B1;Lo;0;L;270D2;;;;N;;;;; +2F9B2;CJK COMPATIBILITY IDEOGRAPH-2F9B2;Lo;0;L;456B;;;;N;;;;; +2F9B3;CJK COMPATIBILITY IDEOGRAPH-2F9B3;Lo;0;L;8650;;;;N;;;;; +2F9B4;CJK COMPATIBILITY IDEOGRAPH-2F9B4;Lo;0;L;865C;;;;N;;;;; +2F9B5;CJK COMPATIBILITY IDEOGRAPH-2F9B5;Lo;0;L;8667;;;;N;;;;; +2F9B6;CJK COMPATIBILITY IDEOGRAPH-2F9B6;Lo;0;L;8669;;;;N;;;;; +2F9B7;CJK COMPATIBILITY IDEOGRAPH-2F9B7;Lo;0;L;86A9;;;;N;;;;; +2F9B8;CJK COMPATIBILITY IDEOGRAPH-2F9B8;Lo;0;L;8688;;;;N;;;;; +2F9B9;CJK COMPATIBILITY IDEOGRAPH-2F9B9;Lo;0;L;870E;;;;N;;;;; +2F9BA;CJK COMPATIBILITY IDEOGRAPH-2F9BA;Lo;0;L;86E2;;;;N;;;;; +2F9BB;CJK COMPATIBILITY IDEOGRAPH-2F9BB;Lo;0;L;8779;;;;N;;;;; +2F9BC;CJK COMPATIBILITY IDEOGRAPH-2F9BC;Lo;0;L;8728;;;;N;;;;; +2F9BD;CJK COMPATIBILITY IDEOGRAPH-2F9BD;Lo;0;L;876B;;;;N;;;;; +2F9BE;CJK COMPATIBILITY IDEOGRAPH-2F9BE;Lo;0;L;8786;;;;N;;;;; +2F9BF;CJK COMPATIBILITY IDEOGRAPH-2F9BF;Lo;0;L;4D57;;;;N;;;;; +2F9C0;CJK COMPATIBILITY IDEOGRAPH-2F9C0;Lo;0;L;87E1;;;;N;;;;; +2F9C1;CJK COMPATIBILITY IDEOGRAPH-2F9C1;Lo;0;L;8801;;;;N;;;;; +2F9C2;CJK COMPATIBILITY IDEOGRAPH-2F9C2;Lo;0;L;45F9;;;;N;;;;; +2F9C3;CJK COMPATIBILITY IDEOGRAPH-2F9C3;Lo;0;L;8860;;;;N;;;;; +2F9C4;CJK COMPATIBILITY IDEOGRAPH-2F9C4;Lo;0;L;8863;;;;N;;;;; +2F9C5;CJK COMPATIBILITY IDEOGRAPH-2F9C5;Lo;0;L;27667;;;;N;;;;; +2F9C6;CJK COMPATIBILITY IDEOGRAPH-2F9C6;Lo;0;L;88D7;;;;N;;;;; +2F9C7;CJK COMPATIBILITY IDEOGRAPH-2F9C7;Lo;0;L;88DE;;;;N;;;;; +2F9C8;CJK COMPATIBILITY IDEOGRAPH-2F9C8;Lo;0;L;4635;;;;N;;;;; +2F9C9;CJK COMPATIBILITY IDEOGRAPH-2F9C9;Lo;0;L;88FA;;;;N;;;;; +2F9CA;CJK COMPATIBILITY IDEOGRAPH-2F9CA;Lo;0;L;34BB;;;;N;;;;; +2F9CB;CJK COMPATIBILITY IDEOGRAPH-2F9CB;Lo;0;L;278AE;;;;N;;;;; +2F9CC;CJK COMPATIBILITY IDEOGRAPH-2F9CC;Lo;0;L;27966;;;;N;;;;; +2F9CD;CJK COMPATIBILITY IDEOGRAPH-2F9CD;Lo;0;L;46BE;;;;N;;;;; +2F9CE;CJK COMPATIBILITY IDEOGRAPH-2F9CE;Lo;0;L;46C7;;;;N;;;;; +2F9CF;CJK COMPATIBILITY IDEOGRAPH-2F9CF;Lo;0;L;8AA0;;;;N;;;;; +2F9D0;CJK COMPATIBILITY IDEOGRAPH-2F9D0;Lo;0;L;8AED;;;;N;;;;; +2F9D1;CJK COMPATIBILITY IDEOGRAPH-2F9D1;Lo;0;L;8B8A;;;;N;;;;; +2F9D2;CJK COMPATIBILITY IDEOGRAPH-2F9D2;Lo;0;L;8C55;;;;N;;;;; +2F9D3;CJK COMPATIBILITY IDEOGRAPH-2F9D3;Lo;0;L;27CA8;;;;N;;;;; +2F9D4;CJK COMPATIBILITY IDEOGRAPH-2F9D4;Lo;0;L;8CAB;;;;N;;;;; +2F9D5;CJK COMPATIBILITY IDEOGRAPH-2F9D5;Lo;0;L;8CC1;;;;N;;;;; +2F9D6;CJK COMPATIBILITY IDEOGRAPH-2F9D6;Lo;0;L;8D1B;;;;N;;;;; +2F9D7;CJK COMPATIBILITY IDEOGRAPH-2F9D7;Lo;0;L;8D77;;;;N;;;;; +2F9D8;CJK COMPATIBILITY IDEOGRAPH-2F9D8;Lo;0;L;27F2F;;;;N;;;;; +2F9D9;CJK COMPATIBILITY IDEOGRAPH-2F9D9;Lo;0;L;20804;;;;N;;;;; +2F9DA;CJK COMPATIBILITY IDEOGRAPH-2F9DA;Lo;0;L;8DCB;;;;N;;;;; +2F9DB;CJK COMPATIBILITY IDEOGRAPH-2F9DB;Lo;0;L;8DBC;;;;N;;;;; +2F9DC;CJK COMPATIBILITY IDEOGRAPH-2F9DC;Lo;0;L;8DF0;;;;N;;;;; +2F9DD;CJK COMPATIBILITY IDEOGRAPH-2F9DD;Lo;0;L;208DE;;;;N;;;;; +2F9DE;CJK COMPATIBILITY IDEOGRAPH-2F9DE;Lo;0;L;8ED4;;;;N;;;;; +2F9DF;CJK COMPATIBILITY IDEOGRAPH-2F9DF;Lo;0;L;8F38;;;;N;;;;; +2F9E0;CJK COMPATIBILITY IDEOGRAPH-2F9E0;Lo;0;L;285D2;;;;N;;;;; +2F9E1;CJK COMPATIBILITY IDEOGRAPH-2F9E1;Lo;0;L;285ED;;;;N;;;;; +2F9E2;CJK COMPATIBILITY IDEOGRAPH-2F9E2;Lo;0;L;9094;;;;N;;;;; +2F9E3;CJK COMPATIBILITY IDEOGRAPH-2F9E3;Lo;0;L;90F1;;;;N;;;;; +2F9E4;CJK COMPATIBILITY IDEOGRAPH-2F9E4;Lo;0;L;9111;;;;N;;;;; +2F9E5;CJK COMPATIBILITY IDEOGRAPH-2F9E5;Lo;0;L;2872E;;;;N;;;;; +2F9E6;CJK COMPATIBILITY IDEOGRAPH-2F9E6;Lo;0;L;911B;;;;N;;;;; +2F9E7;CJK COMPATIBILITY IDEOGRAPH-2F9E7;Lo;0;L;9238;;;;N;;;;; +2F9E8;CJK COMPATIBILITY IDEOGRAPH-2F9E8;Lo;0;L;92D7;;;;N;;;;; +2F9E9;CJK COMPATIBILITY IDEOGRAPH-2F9E9;Lo;0;L;92D8;;;;N;;;;; +2F9EA;CJK COMPATIBILITY IDEOGRAPH-2F9EA;Lo;0;L;927C;;;;N;;;;; +2F9EB;CJK COMPATIBILITY IDEOGRAPH-2F9EB;Lo;0;L;93F9;;;;N;;;;; +2F9EC;CJK COMPATIBILITY IDEOGRAPH-2F9EC;Lo;0;L;9415;;;;N;;;;; +2F9ED;CJK COMPATIBILITY IDEOGRAPH-2F9ED;Lo;0;L;28BFA;;;;N;;;;; +2F9EE;CJK COMPATIBILITY IDEOGRAPH-2F9EE;Lo;0;L;958B;;;;N;;;;; +2F9EF;CJK COMPATIBILITY IDEOGRAPH-2F9EF;Lo;0;L;4995;;;;N;;;;; +2F9F0;CJK COMPATIBILITY IDEOGRAPH-2F9F0;Lo;0;L;95B7;;;;N;;;;; +2F9F1;CJK COMPATIBILITY IDEOGRAPH-2F9F1;Lo;0;L;28D77;;;;N;;;;; +2F9F2;CJK COMPATIBILITY IDEOGRAPH-2F9F2;Lo;0;L;49E6;;;;N;;;;; +2F9F3;CJK COMPATIBILITY IDEOGRAPH-2F9F3;Lo;0;L;96C3;;;;N;;;;; +2F9F4;CJK COMPATIBILITY IDEOGRAPH-2F9F4;Lo;0;L;5DB2;;;;N;;;;; +2F9F5;CJK COMPATIBILITY IDEOGRAPH-2F9F5;Lo;0;L;9723;;;;N;;;;; +2F9F6;CJK COMPATIBILITY IDEOGRAPH-2F9F6;Lo;0;L;29145;;;;N;;;;; +2F9F7;CJK COMPATIBILITY IDEOGRAPH-2F9F7;Lo;0;L;2921A;;;;N;;;;; +2F9F8;CJK COMPATIBILITY IDEOGRAPH-2F9F8;Lo;0;L;4A6E;;;;N;;;;; +2F9F9;CJK COMPATIBILITY IDEOGRAPH-2F9F9;Lo;0;L;4A76;;;;N;;;;; +2F9FA;CJK COMPATIBILITY IDEOGRAPH-2F9FA;Lo;0;L;97E0;;;;N;;;;; +2F9FB;CJK COMPATIBILITY IDEOGRAPH-2F9FB;Lo;0;L;2940A;;;;N;;;;; +2F9FC;CJK COMPATIBILITY IDEOGRAPH-2F9FC;Lo;0;L;4AB2;;;;N;;;;; +2F9FD;CJK COMPATIBILITY IDEOGRAPH-2F9FD;Lo;0;L;29496;;;;N;;;;; +2F9FE;CJK COMPATIBILITY IDEOGRAPH-2F9FE;Lo;0;L;980B;;;;N;;;;; +2F9FF;CJK COMPATIBILITY IDEOGRAPH-2F9FF;Lo;0;L;980B;;;;N;;;;; +2FA00;CJK COMPATIBILITY IDEOGRAPH-2FA00;Lo;0;L;9829;;;;N;;;;; +2FA01;CJK COMPATIBILITY IDEOGRAPH-2FA01;Lo;0;L;295B6;;;;N;;;;; +2FA02;CJK COMPATIBILITY IDEOGRAPH-2FA02;Lo;0;L;98E2;;;;N;;;;; +2FA03;CJK COMPATIBILITY IDEOGRAPH-2FA03;Lo;0;L;4B33;;;;N;;;;; +2FA04;CJK COMPATIBILITY IDEOGRAPH-2FA04;Lo;0;L;9929;;;;N;;;;; +2FA05;CJK COMPATIBILITY IDEOGRAPH-2FA05;Lo;0;L;99A7;;;;N;;;;; +2FA06;CJK COMPATIBILITY IDEOGRAPH-2FA06;Lo;0;L;99C2;;;;N;;;;; +2FA07;CJK COMPATIBILITY IDEOGRAPH-2FA07;Lo;0;L;99FE;;;;N;;;;; +2FA08;CJK COMPATIBILITY IDEOGRAPH-2FA08;Lo;0;L;4BCE;;;;N;;;;; +2FA09;CJK COMPATIBILITY IDEOGRAPH-2FA09;Lo;0;L;29B30;;;;N;;;;; +2FA0A;CJK COMPATIBILITY IDEOGRAPH-2FA0A;Lo;0;L;9B12;;;;N;;;;; +2FA0B;CJK COMPATIBILITY IDEOGRAPH-2FA0B;Lo;0;L;9C40;;;;N;;;;; +2FA0C;CJK COMPATIBILITY IDEOGRAPH-2FA0C;Lo;0;L;9CFD;;;;N;;;;; +2FA0D;CJK COMPATIBILITY IDEOGRAPH-2FA0D;Lo;0;L;4CCE;;;;N;;;;; +2FA0E;CJK COMPATIBILITY IDEOGRAPH-2FA0E;Lo;0;L;4CED;;;;N;;;;; +2FA0F;CJK COMPATIBILITY IDEOGRAPH-2FA0F;Lo;0;L;9D67;;;;N;;;;; +2FA10;CJK COMPATIBILITY IDEOGRAPH-2FA10;Lo;0;L;2A0CE;;;;N;;;;; +2FA11;CJK COMPATIBILITY IDEOGRAPH-2FA11;Lo;0;L;4CF8;;;;N;;;;; +2FA12;CJK COMPATIBILITY IDEOGRAPH-2FA12;Lo;0;L;2A105;;;;N;;;;; +2FA13;CJK COMPATIBILITY IDEOGRAPH-2FA13;Lo;0;L;2A20E;;;;N;;;;; +2FA14;CJK COMPATIBILITY IDEOGRAPH-2FA14;Lo;0;L;2A291;;;;N;;;;; +2FA15;CJK COMPATIBILITY IDEOGRAPH-2FA15;Lo;0;L;9EBB;;;;N;;;;; +2FA16;CJK COMPATIBILITY IDEOGRAPH-2FA16;Lo;0;L;4D56;;;;N;;;;; +2FA17;CJK COMPATIBILITY IDEOGRAPH-2FA17;Lo;0;L;9EF9;;;;N;;;;; +2FA18;CJK COMPATIBILITY IDEOGRAPH-2FA18;Lo;0;L;9EFE;;;;N;;;;; +2FA19;CJK COMPATIBILITY IDEOGRAPH-2FA19;Lo;0;L;9F05;;;;N;;;;; +2FA1A;CJK COMPATIBILITY IDEOGRAPH-2FA1A;Lo;0;L;9F0F;;;;N;;;;; +2FA1B;CJK COMPATIBILITY IDEOGRAPH-2FA1B;Lo;0;L;9F16;;;;N;;;;; +2FA1C;CJK COMPATIBILITY IDEOGRAPH-2FA1C;Lo;0;L;9F3B;;;;N;;;;; +2FA1D;CJK COMPATIBILITY IDEOGRAPH-2FA1D;Lo;0;L;2A600;;;;N;;;;; +E0001;LANGUAGE TAG;Cf;0;BN;;;;;N;;;;; +E0020;TAG SPACE;Cf;0;BN;;;;;N;;;;; +E0021;TAG EXCLAMATION MARK;Cf;0;BN;;;;;N;;;;; +E0022;TAG QUOTATION MARK;Cf;0;BN;;;;;N;;;;; +E0023;TAG NUMBER SIGN;Cf;0;BN;;;;;N;;;;; +E0024;TAG DOLLAR SIGN;Cf;0;BN;;;;;N;;;;; +E0025;TAG PERCENT SIGN;Cf;0;BN;;;;;N;;;;; +E0026;TAG AMPERSAND;Cf;0;BN;;;;;N;;;;; +E0027;TAG APOSTROPHE;Cf;0;BN;;;;;N;;;;; +E0028;TAG LEFT PARENTHESIS;Cf;0;BN;;;;;N;;;;; +E0029;TAG RIGHT PARENTHESIS;Cf;0;BN;;;;;N;;;;; +E002A;TAG ASTERISK;Cf;0;BN;;;;;N;;;;; +E002B;TAG PLUS SIGN;Cf;0;BN;;;;;N;;;;; +E002C;TAG COMMA;Cf;0;BN;;;;;N;;;;; +E002D;TAG HYPHEN-MINUS;Cf;0;BN;;;;;N;;;;; +E002E;TAG FULL STOP;Cf;0;BN;;;;;N;;;;; +E002F;TAG SOLIDUS;Cf;0;BN;;;;;N;;;;; +E0030;TAG DIGIT ZERO;Cf;0;BN;;;;;N;;;;; +E0031;TAG DIGIT ONE;Cf;0;BN;;;;;N;;;;; +E0032;TAG DIGIT TWO;Cf;0;BN;;;;;N;;;;; +E0033;TAG DIGIT THREE;Cf;0;BN;;;;;N;;;;; +E0034;TAG DIGIT FOUR;Cf;0;BN;;;;;N;;;;; +E0035;TAG DIGIT FIVE;Cf;0;BN;;;;;N;;;;; +E0036;TAG DIGIT SIX;Cf;0;BN;;;;;N;;;;; +E0037;TAG DIGIT SEVEN;Cf;0;BN;;;;;N;;;;; +E0038;TAG DIGIT EIGHT;Cf;0;BN;;;;;N;;;;; +E0039;TAG DIGIT NINE;Cf;0;BN;;;;;N;;;;; +E003A;TAG COLON;Cf;0;BN;;;;;N;;;;; +E003B;TAG SEMICOLON;Cf;0;BN;;;;;N;;;;; +E003C;TAG LESS-THAN SIGN;Cf;0;BN;;;;;N;;;;; +E003D;TAG EQUALS SIGN;Cf;0;BN;;;;;N;;;;; +E003E;TAG GREATER-THAN SIGN;Cf;0;BN;;;;;N;;;;; +E003F;TAG QUESTION MARK;Cf;0;BN;;;;;N;;;;; +E0040;TAG COMMERCIAL AT;Cf;0;BN;;;;;N;;;;; +E0041;TAG LATIN CAPITAL LETTER A;Cf;0;BN;;;;;N;;;;; +E0042;TAG LATIN CAPITAL LETTER B;Cf;0;BN;;;;;N;;;;; +E0043;TAG LATIN CAPITAL LETTER C;Cf;0;BN;;;;;N;;;;; +E0044;TAG LATIN CAPITAL LETTER D;Cf;0;BN;;;;;N;;;;; +E0045;TAG LATIN CAPITAL LETTER E;Cf;0;BN;;;;;N;;;;; +E0046;TAG LATIN CAPITAL LETTER F;Cf;0;BN;;;;;N;;;;; +E0047;TAG LATIN CAPITAL LETTER G;Cf;0;BN;;;;;N;;;;; +E0048;TAG LATIN CAPITAL LETTER H;Cf;0;BN;;;;;N;;;;; +E0049;TAG LATIN CAPITAL LETTER I;Cf;0;BN;;;;;N;;;;; +E004A;TAG LATIN CAPITAL LETTER J;Cf;0;BN;;;;;N;;;;; +E004B;TAG LATIN CAPITAL LETTER K;Cf;0;BN;;;;;N;;;;; +E004C;TAG LATIN CAPITAL LETTER L;Cf;0;BN;;;;;N;;;;; +E004D;TAG LATIN CAPITAL LETTER M;Cf;0;BN;;;;;N;;;;; +E004E;TAG LATIN CAPITAL LETTER N;Cf;0;BN;;;;;N;;;;; +E004F;TAG LATIN CAPITAL LETTER O;Cf;0;BN;;;;;N;;;;; +E0050;TAG LATIN CAPITAL LETTER P;Cf;0;BN;;;;;N;;;;; +E0051;TAG LATIN CAPITAL LETTER Q;Cf;0;BN;;;;;N;;;;; +E0052;TAG LATIN CAPITAL LETTER R;Cf;0;BN;;;;;N;;;;; +E0053;TAG LATIN CAPITAL LETTER S;Cf;0;BN;;;;;N;;;;; +E0054;TAG LATIN CAPITAL LETTER T;Cf;0;BN;;;;;N;;;;; +E0055;TAG LATIN CAPITAL LETTER U;Cf;0;BN;;;;;N;;;;; +E0056;TAG LATIN CAPITAL LETTER V;Cf;0;BN;;;;;N;;;;; +E0057;TAG LATIN CAPITAL LETTER W;Cf;0;BN;;;;;N;;;;; +E0058;TAG LATIN CAPITAL LETTER X;Cf;0;BN;;;;;N;;;;; +E0059;TAG LATIN CAPITAL LETTER Y;Cf;0;BN;;;;;N;;;;; +E005A;TAG LATIN CAPITAL LETTER Z;Cf;0;BN;;;;;N;;;;; +E005B;TAG LEFT SQUARE BRACKET;Cf;0;BN;;;;;N;;;;; +E005C;TAG REVERSE SOLIDUS;Cf;0;BN;;;;;N;;;;; +E005D;TAG RIGHT SQUARE BRACKET;Cf;0;BN;;;;;N;;;;; +E005E;TAG CIRCUMFLEX ACCENT;Cf;0;BN;;;;;N;;;;; +E005F;TAG LOW LINE;Cf;0;BN;;;;;N;;;;; +E0060;TAG GRAVE ACCENT;Cf;0;BN;;;;;N;;;;; +E0061;TAG LATIN SMALL LETTER A;Cf;0;BN;;;;;N;;;;; +E0062;TAG LATIN SMALL LETTER B;Cf;0;BN;;;;;N;;;;; +E0063;TAG LATIN SMALL LETTER C;Cf;0;BN;;;;;N;;;;; +E0064;TAG LATIN SMALL LETTER D;Cf;0;BN;;;;;N;;;;; +E0065;TAG LATIN SMALL LETTER E;Cf;0;BN;;;;;N;;;;; +E0066;TAG LATIN SMALL LETTER F;Cf;0;BN;;;;;N;;;;; +E0067;TAG LATIN SMALL LETTER G;Cf;0;BN;;;;;N;;;;; +E0068;TAG LATIN SMALL LETTER H;Cf;0;BN;;;;;N;;;;; +E0069;TAG LATIN SMALL LETTER I;Cf;0;BN;;;;;N;;;;; +E006A;TAG LATIN SMALL LETTER J;Cf;0;BN;;;;;N;;;;; +E006B;TAG LATIN SMALL LETTER K;Cf;0;BN;;;;;N;;;;; +E006C;TAG LATIN SMALL LETTER L;Cf;0;BN;;;;;N;;;;; +E006D;TAG LATIN SMALL LETTER M;Cf;0;BN;;;;;N;;;;; +E006E;TAG LATIN SMALL LETTER N;Cf;0;BN;;;;;N;;;;; +E006F;TAG LATIN SMALL LETTER O;Cf;0;BN;;;;;N;;;;; +E0070;TAG LATIN SMALL LETTER P;Cf;0;BN;;;;;N;;;;; +E0071;TAG LATIN SMALL LETTER Q;Cf;0;BN;;;;;N;;;;; +E0072;TAG LATIN SMALL LETTER R;Cf;0;BN;;;;;N;;;;; +E0073;TAG LATIN SMALL LETTER S;Cf;0;BN;;;;;N;;;;; +E0074;TAG LATIN SMALL LETTER T;Cf;0;BN;;;;;N;;;;; +E0075;TAG LATIN SMALL LETTER U;Cf;0;BN;;;;;N;;;;; +E0076;TAG LATIN SMALL LETTER V;Cf;0;BN;;;;;N;;;;; +E0077;TAG LATIN SMALL LETTER W;Cf;0;BN;;;;;N;;;;; +E0078;TAG LATIN SMALL LETTER X;Cf;0;BN;;;;;N;;;;; +E0079;TAG LATIN SMALL LETTER Y;Cf;0;BN;;;;;N;;;;; +E007A;TAG LATIN SMALL LETTER Z;Cf;0;BN;;;;;N;;;;; +E007B;TAG LEFT CURLY BRACKET;Cf;0;BN;;;;;N;;;;; +E007C;TAG VERTICAL LINE;Cf;0;BN;;;;;N;;;;; +E007D;TAG RIGHT CURLY BRACKET;Cf;0;BN;;;;;N;;;;; +E007E;TAG TILDE;Cf;0;BN;;;;;N;;;;; +E007F;CANCEL TAG;Cf;0;BN;;;;;N;;;;; +F0000;;Co;0;L;;;;;N;;;;; +FFFFD;;Co;0;L;;;;;N;;;;; +100000;;Co;0;L;;;;;N;;;;; +10FFFD;;Co;0;L;;;;;N;;;;; diff --git a/crates/vm/src/buffer.rs b/crates/vm/src/buffer.rs index 038e7cae9f3..b1de6eafbe2 100644 --- a/crates/vm/src/buffer.rs +++ b/crates/vm/src/buffer.rs @@ -1,5 +1,5 @@ use crate::{ - PyObjectRef, PyResult, TryFromObject, VirtualMachine, + AsObject, PyObjectRef, PyResult, TryFromObject, VirtualMachine, builtins::{PyBaseExceptionRef, PyBytesRef, PyTuple, PyTupleRef, PyTypeRef}, common::{static_cell, str::wchar_t}, convert::ToPyObject, @@ -16,9 +16,62 @@ use malachite_bigint::BigInt; use num_traits::{PrimInt, ToPrimitive}; use std::os::raw; -type PackFunc = fn(&VirtualMachine, FormatType, PyObjectRef, &mut [u8]) -> PyResult<()>; +type PackFunc = fn(&VirtualMachine, FormatType, PyObjectRef, &mut [u8]) -> Result<(), PackError>; type UnpackFunc = fn(&VirtualMachine, &[u8]) -> PyObjectRef; +/// Why a value could not be packed. +/// +/// `struct` reports both as `struct.error`, so the kind travels beside the +/// exception rather than in it; `memoryview`, which reports them as TypeError +/// and ValueError, is what needs to tell them apart. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum PackErrorKind { + /// The value was not the kind of thing the format takes. + Type, + /// The value was the right kind, and the format has no room for it. + Value, + /// The value's own code raised, and that error is the answer as it is. + Raised, +} + +pub struct PackError { + pub kind: PackErrorKind, + pub exception: PyBaseExceptionRef, +} + +impl PackError { + fn new>(kind: PackErrorKind, vm: &VirtualMachine, msg: T) -> Self { + Self { + kind, + exception: new_struct_error(vm, msg), + } + } + + /// An error raised by something other than the packing itself, such as a + /// conversion running the value's own code. + fn from_exception(exception: PyBaseExceptionRef, vm: &VirtualMachine) -> Self { + let kind = if exception.fast_isinstance(vm.ctx.exceptions.type_error) { + PackErrorKind::Type + } else if exception.fast_isinstance(vm.ctx.exceptions.overflow_error) + || exception.fast_isinstance(vm.ctx.exceptions.value_error) + { + PackErrorKind::Value + } else { + PackErrorKind::Raised + }; + Self { kind, exception } + } + + /// An error that is the answer exactly as it was raised. `pack_single()` + /// leaves `'?'` to `PyObject_IsTrue()` this way, with no message of its own. + fn raised(exception: PyBaseExceptionRef) -> Self { + Self { + kind: PackErrorKind::Raised, + exception, + } + } +} + static OVERFLOW_MSG: &str = "total struct size too long"; // not a const to reduce code size #[derive(Clone, Copy, Debug, Eq, PartialEq)] @@ -438,22 +491,45 @@ impl FormatSpec { } pub fn pack(&self, args: Vec, vm: &VirtualMachine) -> PyResult> { + self.try_pack(args, vm).map_err(|e| e.exception) + } + + /// [`Self::pack`], keeping why a value could not be packed. + pub fn try_pack( + &self, + args: Vec, + vm: &VirtualMachine, + ) -> Result, PackError> { // Create data vector: - let mut data = vec![0; self.size]; + let mut data = vm + .new_zeroed_bytes(self.size) + .map_err(|e| PackError::from_exception(e, vm))?; - self.pack_into(&mut data, args, vm)?; + self.try_pack_into(&mut data, args, vm)?; Ok(data) } pub fn pack_into( &self, - mut buffer: &mut [u8], + buffer: &mut [u8], args: Vec, vm: &VirtualMachine, ) -> PyResult<()> { + self.try_pack_into(buffer, args, vm) + .map_err(|e| e.exception) + } + + /// [`Self::pack_into`], keeping why a value could not be packed. + pub fn try_pack_into( + &self, + mut buffer: &mut [u8], + args: Vec, + vm: &VirtualMachine, + ) -> Result<(), PackError> { if self.arg_count != args.len() { - return Err(new_struct_error( + return Err(PackError::new( + PackErrorKind::Type, vm, format!( "pack expected {} items for packing (got {})", @@ -471,12 +547,14 @@ impl FormatSpec { match code.code { FormatType::Str => { let (buf, rest) = buffer.split_at_mut(code.repeat); - pack_string(vm, args.next().unwrap(), buf)?; + pack_string(vm, args.next().unwrap(), buf) + .map_err(|e| PackError::from_exception(e, vm))?; buffer = rest; } FormatType::Pascal => { let (buf, rest) = buffer.split_at_mut(code.repeat); - pack_pascal(vm, args.next().unwrap(), buf)?; + pack_pascal(vm, args.next().unwrap(), buf) + .map_err(|e| PackError::from_exception(e, vm))?; buffer = rest; } FormatType::Pad => { @@ -554,7 +632,7 @@ trait Packable { code: FormatType, arg: PyObjectRef, data: &mut [u8], - ) -> PyResult<()>; + ) -> Result<(), PackError>; fn unpack(vm: &VirtualMachine, data: &[u8]) -> PyObjectRef; } @@ -584,7 +662,7 @@ macro_rules! make_pack_prim_int { code: FormatType, arg: PyObjectRef, data: &mut [u8], - ) -> PyResult<()> { + ) -> Result<(), PackError> { let i: $T = get_int_or_index(vm, code, arg)?; i.pack_int::(data); Ok(()) @@ -598,13 +676,25 @@ macro_rules! make_pack_prim_int { }; } -fn get_int_or_index(vm: &VirtualMachine, code: FormatType, arg: PyObjectRef) -> PyResult +fn get_int_or_index( + vm: &VirtualMachine, + code: FormatType, + arg: PyObjectRef, +) -> Result where T: PrimInt + fmt::Display + for<'a> TryFrom<&'a BigInt>, { - let index = arg - .try_index_opt(vm) - .unwrap_or_else(|| Err(new_struct_error(vm, "required argument is not an integer")))?; + let index = match arg.try_index_opt(vm) { + None => { + return Err(PackError::new( + PackErrorKind::Type, + vm, + "required argument is not an integer", + )); + } + Some(Err(e)) => return Err(PackError::from_exception(e, vm)), + Some(Ok(index)) => index, + }; index.try_to_primitive(vm).map_err(|_| { // A pointer is converted rather than checked against the range of a // named format, so what it reports is the conversion failing. @@ -618,7 +708,7 @@ where T::max_value() ) }; - new_struct_error(vm, msg) + PackError::new(PackErrorKind::Value, vm, msg) }) } @@ -641,15 +731,20 @@ macro_rules! make_pack_float { _code: FormatType, arg: PyObjectRef, data: &mut [u8], - ) -> PyResult<()> { - let f_64 = ArgIntoFloat::try_from_object(vm, arg)?.into_float(); + ) -> Result<(), PackError> { + let f_64 = ArgIntoFloat::try_from_object(vm, arg) + .map_err(|e| PackError::from_exception(e, vm))? + .into_float(); let f = f_64 as $T; if f.is_infinite() != f_64.is_infinite() { - return Err(vm.new_overflow_error(concat!( - "float too large to pack with ", - $fmt, - " format" - ))); + return Err(PackError { + kind: PackErrorKind::Value, + exception: vm.new_overflow_error(concat!( + "float too large to pack with ", + $fmt, + " format" + )), + }); } f.to_bits().pack_int::(data); Ok(()) @@ -672,12 +767,17 @@ impl Packable for f16 { _code: FormatType, arg: PyObjectRef, data: &mut [u8], - ) -> PyResult<()> { - let f_64 = ArgIntoFloat::try_from_object(vm, arg)?.into_float(); + ) -> Result<(), PackError> { + let f_64 = ArgIntoFloat::try_from_object(vm, arg) + .map_err(|e| PackError::from_exception(e, vm))? + .into_float(); // "from_f64 should be preferred in any non-`const` context" except it gives the wrong result :/ let f_16 = Self::from_f64_const(f_64); if f_16.is_infinite() != f_64.is_infinite() { - return Err(vm.new_overflow_error("float too large to pack with e format")); + return Err(PackError { + kind: PackErrorKind::Value, + exception: vm.new_overflow_error("float too large to pack with e format"), + }); } f_16.to_bits().pack_int::(data); Ok(()) @@ -695,7 +795,7 @@ impl Packable for *mut raw::c_void { code: FormatType, arg: PyObjectRef, data: &mut [u8], - ) -> PyResult<()> { + ) -> Result<(), PackError> { usize::pack::(vm, code, arg, data) } @@ -710,8 +810,10 @@ impl Packable for bool { _code: FormatType, arg: PyObjectRef, data: &mut [u8], - ) -> PyResult<()> { - let v = ArgIntoBool::try_from_object(vm, arg)?.into_bool() as u8; + ) -> Result<(), PackError> { + let v = ArgIntoBool::try_from_object(vm, arg) + .map_err(PackError::raised)? + .into_bool() as u8; v.pack_int::(data); Ok(()) } @@ -727,13 +829,15 @@ fn pack_char( _code: FormatType, arg: PyObjectRef, data: &mut [u8], -) -> PyResult<()> { - let v = PyBytesRef::try_from_object(vm, arg)?; - let ch = *v - .as_bytes() - .iter() - .exactly_one() - .map_err(|_| new_struct_error(vm, "char format requires a bytes object of length 1"))?; +) -> Result<(), PackError> { + let v = PyBytesRef::try_from_object(vm, arg).map_err(|e| PackError::from_exception(e, vm))?; + let ch = *v.as_bytes().iter().exactly_one().map_err(|_| { + PackError::new( + PackErrorKind::Value, + vm, + "char format requires a bytes object of length 1", + ) + })?; data[0] = ch; Ok(()) } diff --git a/crates/vm/src/builtins/bytearray.rs b/crates/vm/src/builtins/bytearray.rs index c8782127b3f..594ecc569d8 100644 --- a/crates/vm/src/builtins/bytearray.rs +++ b/crates/vm/src/builtins/bytearray.rs @@ -1,14 +1,14 @@ //! Implementation of the python bytearray object. use super::{ PositionIterInternal, PyBytes, PyDictRef, PyGenericAlias, PyStrRef, PyTuple, PyTupleRef, - PyType, PyTypeRef, iter::builtins_iter, + PyType, PyTypeRef, iter::builtins_iter, locked_next, }; use crate::{ AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine, anystr::{self, AnyStr}, atomic_func, - byte::{bytes_from_object, value_from_object}, + byte::{bytearray_extend_from_object, bytearray_from_object, value_from_object}, bytes_inner::{ ByteInnerFindOptions, ByteInnerHexOptions, ByteInnerNewOptions, ByteInnerPaddingOptions, ByteInnerSplitOptions, ByteInnerSub, ByteInnerTranslateOptions, DecodeArgs, PyBytesInner, @@ -115,7 +115,7 @@ impl PyByteArray { let items = if zelf.is(&value) { zelf.borrow_buf().to_vec() } else { - bytes_from_object(vm, &value)? + bytearray_from_object(vm, &value)? }; if let Some(mut w) = zelf.try_resizable_opt() { w.elements.setitem_by_slice(vm, slice, &items) @@ -643,7 +643,7 @@ impl Py { vm.new_buffer_error("non-contiguous buffer is not a bytes-like object") })? .to_vec(), - None => bytes_from_object(vm, &object)?, + None => bytearray_extend_from_object(vm, &object)?, }; self.try_resizable(vm)?.elements.extend(items); Ok(()) @@ -716,7 +716,7 @@ impl Initializer for PyByteArray { fn init(zelf: PyRef, options: Self::Args, vm: &VirtualMachine) -> PyResult<()> { // First unpack bytearray and *then* get a lock to set it. - let mut inner = options.get_bytearray_inner(vm)?; + let mut inner = options.get_inner(bytearray_from_object, vm)?; core::mem::swap(&mut *zelf.inner_mut(), &mut inner); Ok(()) } @@ -936,7 +936,7 @@ impl PyByteArrayIterator { impl SelfIter for PyByteArrayIterator {} impl IterNext for PyByteArrayIterator { fn next(zelf: &Py, vm: &VirtualMachine) -> PyResult { - zelf.internal.lock().next(|bytearray, pos| { + locked_next(&zelf.internal, |bytearray, pos| { let buf = bytearray.borrow_buf(); Ok(PyIterReturn::from_result( buf.get(pos).map(|&x| vm.new_pyobj(x)).ok_or(None), diff --git a/crates/vm/src/builtins/bytes.rs b/crates/vm/src/builtins/bytes.rs index bfa2fd3545b..e611e1929f0 100644 --- a/crates/vm/src/builtins/bytes.rs +++ b/crates/vm/src/builtins/bytes.rs @@ -1,6 +1,6 @@ use super::{ PositionIterInternal, PyDictRef, PyGenericAlias, PyStrRef, PyTuple, PyTupleRef, PyType, - PyTypeRef, iter::builtins_iter, + PyTypeRef, iter::builtins_iter, locked_next, }; use crate::common::lock::LazyLock; use crate::{ @@ -8,6 +8,7 @@ use crate::{ TryFromBorrowedObject, VirtualMachine, anystr::{self, AnyStr}, atomic_func, + byte::bytes_from_object, bytes_inner::{ ByteInnerFindOptions, ByteInnerHexOptions, ByteInnerNewOptions, ByteInnerPaddingOptions, ByteInnerSplitOptions, ByteInnerSub, ByteInnerTranslateOptions, DecodeArgs, PyBytesInner, @@ -138,8 +139,7 @@ impl Constructor for PyBytes { return payload.into_ref_with_type(vm, cls).map(Into::into); } - // Fallback to get_bytearray_inner - let elements = options.get_bytearray_inner(vm)?.elements; + let elements = options.get_inner(bytes_from_object, vm)?.elements; // Return empty bytes singleton for exact bytes types if elements.is_empty() && cls.is(vm.ctx.types.bytes_type) { @@ -797,7 +797,7 @@ impl PyBytesIterator { impl SelfIter for PyBytesIterator {} impl IterNext for PyBytesIterator { fn next(zelf: &Py, vm: &VirtualMachine) -> PyResult { - zelf.internal.lock().next(|bytes, pos| { + locked_next(&zelf.internal, |bytes, pos| { Ok(PyIterReturn::from_result( bytes .as_bytes() diff --git a/crates/vm/src/builtins/code.rs b/crates/vm/src/builtins/code.rs index b25c9d5c499..63c73fe4e5b 100644 --- a/crates/vm/src/builtins/code.rs +++ b/crates/vm/src/builtins/code.rs @@ -601,7 +601,7 @@ impl Representable for PyCode { fn repr_str(zelf: &Py, _vm: &VirtualMachine) -> PyResult { let code = &zelf.code; Ok(format!( - "", + "", code.obj_name, zelf.get_id(), zelf.source_path().as_str(), @@ -842,7 +842,8 @@ impl Constructor for PyCode { } else { None }, - max_stackdepth: args.stacksize, + // Room for one value is always reserved, even where nothing is pushed. + max_stackdepth: args.stacksize.max(1), obj_name: vm.ctx.intern_str(args.name.as_wtf8()), qualname: vm.ctx.intern_str(args.qualname.as_wtf8()), constants, @@ -1352,10 +1353,12 @@ impl PyCode { OptionalArg::Missing => self.code.qualname.to_owned(), }; + // Room for one value is always reserved, even where nothing is pushed. let max_stackdepth = match co_stacksize { OptionalArg::Present(stacksize) => stacksize, OptionalArg::Missing => self.code.max_stackdepth, - }; + } + .max(1); let instructions = match co_code { OptionalArg::Present(code_bytes) => { diff --git a/crates/vm/src/builtins/dict.rs b/crates/vm/src/builtins/dict.rs index d2b9dea31fa..014b8bba5ff 100644 --- a/crates/vm/src/builtins/dict.rs +++ b/crates/vm/src/builtins/dict.rs @@ -1,6 +1,6 @@ use super::{ IterStatus, PositionIterInternal, PyBaseExceptionRef, PyGenericAlias, PyMappingProxy, PySet, - PyStr, PyStrRef, PyTupleRef, PyType, PyTypeRef, set, set::PySetInner, + PyStr, PyStrRef, PyTupleRef, PyType, PyTypeRef, locked_step, set, set::PySetInner, }; use crate::common::lock::LazyLock; use crate::object::{Traverse, TraverseFn}; @@ -24,6 +24,7 @@ use crate::{ use alloc::fmt; use core::cell::Cell; use core::ptr::NonNull; +use rustpython_common::atomic::{Ordering, PyAtomic, Radium}; use rustpython_common::lock::PyMutex; use rustpython_common::wtf8::Wtf8Buf; @@ -240,7 +241,7 @@ impl PyDict { } })?; elem_iter - .into_iter::(vm)? + .into_iter::(vm) .collect::>>() })() .map_err(|exc| Self::add_update_sequence_note(exc, index, vm))?; @@ -257,7 +258,7 @@ impl PyDict { let iter = seq2.get_iter(vm)?; let dict = &self.entries; - for (index, element) in iter.iter_without_hint::(vm)?.enumerate() { + for (index, element) in iter.iter::(vm)?.enumerate() { let (key, value) = Self::update_sequence_pair(element?, index, vm)?; if !override_existing && dict.contains(vm, &*key)? { @@ -774,13 +775,38 @@ impl Py { } /// Take a python dictionary and convert it to attributes. - pub fn to_attributes(&self, vm: &VirtualMachine) -> PyAttributes { + /// + /// `PyAttributes` is keyed by interned strings, so a key that is not a + /// string has nowhere to go. Those keys are left out, and `on_non_string` + /// is called once, the first time one turns up, so the caller can decide + /// whether that deserves an error or a warning. + pub fn to_attributes( + &self, + vm: &VirtualMachine, + on_non_string: impl FnOnce(&VirtualMachine) -> PyResult<()>, + ) -> PyResult { let mut attrs = PyAttributes::default(); + let mut on_non_string = Some(on_non_string); for (key, value) in self { - let key: PyRefExact = key.downcast_exact(vm).expect("dict has non-string keys"); - attrs.insert(vm.ctx.intern_str(key), value); + let key = match key.downcast_exact::(vm) { + Ok(key) => vm.ctx.intern_str(key), + // `PyStr`, not the exact type: a `str` subclass names an + // attribute just as well, the same way it does as a keyword + // argument. Interning drops the subclass, which nothing but + // the key object itself can observe. + Err(key) => match key.downcast_ref::() { + Some(key) => vm.ctx.intern_str(key.as_wtf8()), + None => { + if let Some(on_non_string) = on_non_string.take() { + on_non_string(vm)?; + } + continue; + } + }, + }; + attrs.insert(key, value); } - attrs + Ok(attrs) } pub fn get_item_opt( @@ -1164,6 +1190,11 @@ macro_rules! dict_view { #[derive(Debug)] pub(crate) struct $iter_name { pub(crate) size: dict_inner::DictSize, + /// Whether the dict was found to have changed, which + /// `dictiter_iternextkey()` records by writing a size no dict can + /// have. Sticky: what it makes the iterator answer, it answers + /// from then on. + changed: PyAtomic, pub(crate) internal: PyMutex>, } @@ -1179,13 +1210,26 @@ macro_rules! dict_view { fn new(dict: PyDictRef) -> Self { $iter_name { size: dict.size(), + changed: Radium::new(false), internal: PyMutex::new(PositionIterInternal::new(dict, 0)), } } #[pymethod] fn __length_hint__(&self) -> usize { - self.internal.lock().length_hint(|_| self.size.entries_size) + // `dictiter_len()` answers for a dict it can no longer walk + // with nothing, comparing the size it captured against the + // dict's own every time it is asked. + if self.changed.load(Ordering::Relaxed) { + return 0; + } + self.internal.lock().length_hint(|dict| { + if dict.size() == self.size { + self.size.entries_size + } else { + 0 + } + }) } #[pymethod] @@ -1214,32 +1258,33 @@ macro_rules! dict_view { impl IterNext for $iter_name { fn next(zelf: &Py, vm: &VirtualMachine) -> PyResult { - let mut internal = zelf.internal.lock(); - let next = if let IterStatus::Active(dict) = &internal.status { - match dict.entries.next_entry_checked( - internal.position, - &zelf.size, - $project_fn, - ) { + locked_step(&zelf.internal, |internal| { + let IterStatus::Active(dict) = &internal.status else { + return (Ok(PyIterReturn::StopIteration(None)), None); + }; + let mutated = + || vm.new_runtime_error("dictionary changed size during iteration"); + if zelf.changed.load(Ordering::Relaxed) { + // The dict is not looked at again once it has been + // found to change: an iterator that has raised keeps + // raising. + return (Err(mutated()), None); + } + let entry = + dict.entries + .next_entry_checked(internal.position, &zelf.size, $project_fn); + match entry { Err(dict_inner::DictChanged) => { - internal.status = IterStatus::Exhausted; - return Err( - vm.new_runtime_error("dictionary changed size during iteration") - ); + zelf.changed.store(true, Ordering::Relaxed); + (Err(mutated()), None) } Ok(Some((position, item))) => { internal.position = position; - PyIterReturn::Return(($result_fn)(vm, item)) - } - Ok(None) => { - internal.status = IterStatus::Exhausted; - PyIterReturn::StopIteration(None) + (Ok(PyIterReturn::Return(($result_fn)(vm, item))), None) } + Ok(None) => (Ok(PyIterReturn::StopIteration(None)), internal.exhaust()), } - } else { - PyIterReturn::StopIteration(None) - }; - Ok(next) + }) } } @@ -1247,6 +1292,8 @@ macro_rules! dict_view { #[derive(Debug)] pub(crate) struct $reverse_iter_name { pub(crate) size: dict_inner::DictSize, + /// As in `$iter_name`. + changed: PyAtomic, internal: PyMutex>, } @@ -1264,6 +1311,7 @@ macro_rules! dict_view { let position = size.entries_size.saturating_sub(1); $reverse_iter_name { size, + changed: Radium::new(false), internal: PyMutex::new(PositionIterInternal::new(dict, position)), } } @@ -1294,9 +1342,17 @@ macro_rules! dict_view { #[pymethod] fn __length_hint__(&self) -> usize { - self.internal - .lock() - .rev_length_hint(|_| self.size.entries_size) + // As in `$iter_name`. + if self.changed.load(Ordering::Relaxed) { + return 0; + } + let internal = self.internal.lock(); + match &internal.status { + IterStatus::Active(dict) if dict.size() == self.size => { + internal.rev_length_hint(|_| self.size.entries_size) + } + _ => 0, + } } } @@ -1304,36 +1360,38 @@ macro_rules! dict_view { impl IterNext for $reverse_iter_name { fn next(zelf: &Py, vm: &VirtualMachine) -> PyResult { - let mut internal = zelf.internal.lock(); - let next = if let IterStatus::Active(dict) = &internal.status { - match dict.entries.prev_entry_checked( - internal.position, - &zelf.size, - $project_fn, - ) { + locked_step(&zelf.internal, |internal| { + let IterStatus::Active(dict) = &internal.status else { + return (Ok(PyIterReturn::StopIteration(None)), None); + }; + let mutated = + || vm.new_runtime_error("dictionary changed size during iteration"); + if zelf.changed.load(Ordering::Relaxed) { + // The dict is not looked at again once it has been + // found to change: an iterator that has raised keeps + // raising. + return (Err(mutated()), None); + } + let entry = + dict.entries + .prev_entry_checked(internal.position, &zelf.size, $project_fn); + match entry { Err(dict_inner::DictChanged) => { - internal.status = IterStatus::Exhausted; - return Err( - vm.new_runtime_error("dictionary changed size during iteration") - ); + zelf.changed.store(true, Ordering::Relaxed); + (Err(mutated()), None) } Ok(Some((found_index, item))) => { - if found_index == 0 { - internal.status = IterStatus::Exhausted; + let released = if found_index == 0 { + internal.exhaust() } else { internal.position = found_index - 1; - } - PyIterReturn::Return(($result_fn)(vm, item)) - } - Ok(None) => { - internal.status = IterStatus::Exhausted; - PyIterReturn::StopIteration(None) + None + }; + (Ok(PyIterReturn::Return(($result_fn)(vm, item))), released) } + Ok(None) => (Ok(PyIterReturn::StopIteration(None)), internal.exhaust()), } - } else { - PyIterReturn::StopIteration(None) - }; - Ok(next) + }) } } }; diff --git a/crates/vm/src/builtins/enumerate.rs b/crates/vm/src/builtins/enumerate.rs index 95e144dad21..dac19dd89cc 100644 --- a/crates/vm/src/builtins/enumerate.rs +++ b/crates/vm/src/builtins/enumerate.rs @@ -1,6 +1,6 @@ use super::{ IterStatus, PositionIterInternal, PyGenericAlias, PyIntRef, PyTupleRef, PyType, PyTypeRef, - iter::builtins_reversed, + iter::builtins_reversed, locked_rev_next, }; use crate::common::lock::{PyMutex, PyRwLock}; use crate::{ @@ -142,9 +142,9 @@ impl PyReverseSequenceIterator { impl SelfIter for PyReverseSequenceIterator {} impl IterNext for PyReverseSequenceIterator { fn next(zelf: &Py, vm: &VirtualMachine) -> PyResult { - zelf.internal - .lock() - .rev_next(|obj, pos| PyIterReturn::from_getitem_result(obj.get_item(&pos, vm), vm)) + locked_rev_next(&zelf.internal, |obj, pos| { + PyIterReturn::from_getitem_result(obj.get_item(&pos, vm), vm) + }) } } diff --git a/crates/vm/src/builtins/function.rs b/crates/vm/src/builtins/function.rs index a5342d1df3a..94c231b0b83 100644 --- a/crates/vm/src/builtins/function.rs +++ b/crates/vm/src/builtins/function.rs @@ -1578,7 +1578,11 @@ impl PyCell { } pub(crate) fn set(&self, x: Option) { - *self.contents.lock() = x; + // What was here is released after the lock, the way `Py_XSETREF` stores + // before it decrefs. Releasing it under the lock would let a `__del__` + // that reads this cell wait on a lock this call still holds. + let replaced = core::mem::replace(&mut *self.contents.lock(), x); + drop(replaced); } #[pygetset] diff --git a/crates/vm/src/builtins/int.rs b/crates/vm/src/builtins/int.rs index bb7b5128073..3a4c18a3cdd 100644 --- a/crates/vm/src/builtins/int.rs +++ b/crates/vm/src/builtins/int.rs @@ -593,7 +593,7 @@ impl PyInt { Sign::Minus if !signed => { return Err(vm.new_overflow_error("can't convert negative int to unsigned")); } - Sign::NoSign => return Ok(vec![0u8; byte_len].into()), + Sign::NoSign => return Ok(vm.new_zeroed_bytes(byte_len)?.into()), _ => {} } @@ -609,10 +609,10 @@ impl PyInt { return Err(vm.new_overflow_error("int too big to convert")); } - let mut append_bytes = match value.sign() { - Sign::Minus => vec![255u8; byte_len - origin_len], - _ => vec![0u8; byte_len - origin_len], - }; + let mut append_bytes = vm.new_zeroed_bytes(byte_len - origin_len)?; + if value.sign() == Sign::Minus { + append_bytes.fill(255); + } let bytes = match args.byteorder { ArgByteOrder::Big => { diff --git a/crates/vm/src/builtins/iter.rs b/crates/vm/src/builtins/iter.rs index 4e29df583a8..2d231e9e6a8 100644 --- a/crates/vm/src/builtins/iter.rs +++ b/crates/vm/src/builtins/iter.rs @@ -91,41 +91,67 @@ impl PositionIterInternal { } } - fn _next(&mut self, f: F, op: OP) -> PyResult + /// `op` answers whether the step it took left this exhausted. + fn _next(&mut self, f: F, op: OP) -> (PyResult, Option) where F: FnOnce(&T, usize) -> PyResult, - OP: FnOnce(&mut Self), + OP: FnOnce(&mut Self) -> bool, { - if let IterStatus::Active(obj) = &self.status { - let ret = f(obj, self.position); - if let Ok(PyIterReturn::Return(_)) = ret { - op(self); - } else { - self.status = IterStatus::Exhausted; - } - ret - } else { - Ok(PyIterReturn::StopIteration(None)) + let IterStatus::Active(obj) = &self.status else { + return (Ok(PyIterReturn::StopIteration(None)), None); + }; + let ret = f(obj, self.position); + let done = match &ret { + Ok(PyIterReturn::Return(_)) => op(self), + Ok(PyIterReturn::StopIteration(_)) => true, + // An error belongs to the element, not to the walk, so the next + // call reaches for the same one again. `iter_iternext()` lets go of + // its sequence for `IndexError` and `StopIteration` alone, and + // `PyIterReturn::from_getitem_result` has already turned the first + // of those into the second. + Err(_) => false, + }; + let released = if done { self.exhaust() } else { None }; + (ret, released) + } + + /// Mark this exhausted and hand back what it was holding, for the caller to + /// release once it has dropped the lock guarding this. Releasing it under + /// that lock would let a `__del__` that iterates again deadlock. + #[must_use] + pub fn exhaust(&mut self) -> Option { + match core::mem::replace(&mut self.status, IterStatus::Exhausted) { + IterStatus::Active(obj) => Some(obj), + IterStatus::Exhausted => None, } } - pub fn next(&mut self, f: F) -> PyResult + /// Advance, along with what this was holding if the step exhausted it. See + /// [`Self::exhaust`] for why the caller is handed it rather than the drop + /// happening here; [`locked_next`] does the release for the common case. + #[must_use = "what this hands back is released after the lock, not here"] + pub fn next(&mut self, f: F) -> (PyResult, Option) where F: FnOnce(&T, usize) -> PyResult, { - self._next(f, |zelf| zelf.position += 1) + self._next(f, |zelf| { + zelf.position += 1; + false + }) } - pub fn rev_next(&mut self, f: F) -> PyResult + /// [`Self::next`] walking backwards, exhausted once it steps off the front. + #[must_use = "what this hands back is released after the lock, not here"] + pub fn rev_next(&mut self, f: F) -> (PyResult, Option) where F: FnOnce(&T, usize) -> PyResult, { self._next(f, |zelf| { if zelf.position == 0 { - zelf.status = IterStatus::Exhausted; - } else { - zelf.position -= 1; + return true; } + zelf.position -= 1; + false }) } @@ -153,6 +179,43 @@ impl PositionIterInternal { } } +/// Take `step` under the lock `internal` holds, releasing whatever the step +/// hands back only after that lock is gone. `setiter_iternext()` puts its +/// `Py_DECREF(so)` past `Py_END_CRITICAL_SECTION()` for the same reason: a +/// `__del__` that iterates again would otherwise wait on a lock still held here. +pub(crate) fn locked_step( + internal: &PyMutex>, + step: impl FnOnce(&mut PositionIterInternal) -> (PyResult, Option), +) -> PyResult { + let mut guard = internal.lock(); + let (ret, released) = step(&mut guard); + drop(guard); + drop(released); + ret +} + +/// [`PositionIterInternal::next`] with the release [`locked_step`] describes. +pub fn locked_next( + internal: &PyMutex>, + f: F, +) -> PyResult +where + F: FnOnce(&T, usize) -> PyResult, +{ + locked_step(internal, |internal| internal.next(f)) +} + +/// [`locked_next`] walking backwards. +pub fn locked_rev_next( + internal: &PyMutex>, + f: F, +) -> PyResult +where + F: FnOnce(&T, usize) -> PyResult, +{ + locked_step(internal, |internal| internal.rev_next(f)) +} + pub fn builtins_iter(vm: &VirtualMachine) -> PyObjectRef { vm.builtins.get_attr("iter", vm).unwrap() } @@ -227,7 +290,7 @@ impl PySequenceIterator { impl SelfIter for PySequenceIterator {} impl IterNext for PySequenceIterator { fn next(zelf: &Py, vm: &VirtualMachine) -> PyResult { - zelf.internal.lock().next(|obj, pos| { + locked_next(&zelf.internal, |obj, pos| { let seq = obj.sequence_unchecked(); PyIterReturn::from_getitem_result(seq.get_item(pos as isize, vm), vm) }) diff --git a/crates/vm/src/builtins/list.rs b/crates/vm/src/builtins/list.rs index fe674a45821..3ba537a81e0 100644 --- a/crates/vm/src/builtins/list.rs +++ b/crates/vm/src/builtins/list.rs @@ -1,6 +1,7 @@ use super::{ PositionIterInternal, PyGenericAlias, PyTupleRef, PyType, PyTypeRef, iter::{builtins_iter, builtins_reversed}, + locked_next, locked_rev_next, }; use crate::atomic_func; use crate::common::lock::{ @@ -187,7 +188,11 @@ impl PyList { #[pymethod] pub(crate) fn extend(&self, x: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { - let mut new_elements = x.try_to_value(vm)?; + // What is already here decides whether the iterable's length hint is + // believable, so it goes along with the request for the elements. It is + // counted where `list_extend()` reads `Py_SIZE(self)`, after the + // iterable has answered, because answering runs code that can change it. + let mut new_elements = vm.extract_elements_sized(&x, &|| self.borrow_vec().len(), Ok)?; self.borrow_vec_mut().append(&mut new_elements); Ok(()) } @@ -221,8 +226,7 @@ impl PyList { other: &PyObject, vm: &VirtualMachine, ) -> PyResult { - let mut seq = extract_cloned(other, Ok, vm)?; - zelf.borrow_vec_mut().append(&mut seq); + zelf.extend(other.to_owned(), vm)?; Ok(zelf.to_owned().into()) } @@ -231,8 +235,7 @@ impl PyList { other: PyObjectRef, vm: &VirtualMachine, ) -> PyResult> { - let mut seq = extract_cloned(&other, Ok, vm)?; - zelf.borrow_vec_mut().append(&mut seq); + zelf.extend(other, vm)?; Ok(zelf) } @@ -481,7 +484,7 @@ impl Initializer for PyList { fn init(zelf: PyRef, iterable: Self::Args, vm: &VirtualMachine) -> PyResult<()> { let mut elements = if let OptionalArg::Present(iterable) = iterable { - iterable.try_to_value(vm)? + vm.extract_elements_sized(&iterable, &|| 0, Ok)? } else { vec![] }; @@ -909,24 +912,22 @@ impl PyListIterator { impl PyListIterator { /// Fast path for FOR_ITER specialization. pub(crate) fn fast_next(&self) -> Option { - self.internal - .lock() - .next(|list, pos| { - let vec = list.borrow_vec(); - Ok(PyIterReturn::from_result(vec.get(pos).cloned().ok_or(None))) - }) - .ok() - .and_then(|r| match r { - PyIterReturn::Return(v) => Some(v), - PyIterReturn::StopIteration(_) => None, - }) + locked_next(&self.internal, |list, pos| { + let vec = list.borrow_vec(); + Ok(PyIterReturn::from_result(vec.get(pos).cloned().ok_or(None))) + }) + .ok() + .and_then(|r| match r { + PyIterReturn::Return(v) => Some(v), + PyIterReturn::StopIteration(_) => None, + }) } } impl SelfIter for PyListIterator {} impl IterNext for PyListIterator { fn next(zelf: &Py, _vm: &VirtualMachine) -> PyResult { - zelf.internal.lock().next(|list, pos| { + locked_next(&zelf.internal, |list, pos| { let vec = list.borrow_vec(); Ok(PyIterReturn::from_result(vec.get(pos).cloned().ok_or(None))) }) @@ -975,7 +976,7 @@ impl PyListReverseIterator { impl SelfIter for PyListReverseIterator {} impl IterNext for PyListReverseIterator { fn next(zelf: &Py, _vm: &VirtualMachine) -> PyResult { - zelf.internal.lock().rev_next(|list, pos| { + locked_rev_next(&zelf.internal, |list, pos| { let vec = list.borrow_vec(); Ok(PyIterReturn::from_result(vec.get(pos).cloned().ok_or(None))) }) diff --git a/crates/vm/src/builtins/map.rs b/crates/vm/src/builtins/map.rs index cb8db23e640..2606b61933a 100644 --- a/crates/vm/src/builtins/map.rs +++ b/crates/vm/src/builtins/map.rs @@ -54,15 +54,6 @@ impl Constructor for PyMap { #[pyclass(with(IterNext, Iterable, Constructor), flags(BASETYPE))] impl PyMap { - #[pymethod] - fn __length_hint__(&self, vm: &VirtualMachine) -> PyResult { - self.iterators.iter().try_fold(0, |prev, cur| { - let cur = cur.as_ref().to_owned().length_hint(0, vm)?; - let max = core::cmp::max(prev, cur); - Ok(max) - }) - } - #[pymethod] fn __reduce__(zelf: PyRef, vm: &VirtualMachine) -> PyTupleRef { let cls = zelf.class().to_owned(); diff --git a/crates/vm/src/builtins/memory.rs b/crates/vm/src/builtins/memory.rs index 0b04de133e7..86396825b0c 100644 --- a/crates/vm/src/builtins/memory.rs +++ b/crates/vm/src/builtins/memory.rs @@ -1,12 +1,13 @@ use super::{ PositionIterInternal, PyBytes, PyBytesRef, PyGenericAlias, PyInt, PyListRef, PySlice, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType, PyTypeRef, PyUtf8StrRef, iter::builtins_iter, + locked_next, }; use crate::common::lock::LazyLock; use crate::{ AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromBorrowedObject, TryFromObject, VirtualMachine, atomic_func, - buffer::FormatSpec, + buffer::{FormatSpec, PackErrorKind}, bytes_inner::{ByteInnerHexOptions, bytes_to_hex}, class::{PyClassImpl, StaticType}, common::{ @@ -329,11 +330,22 @@ impl PyMemoryView { // conversion runs `__index__` or `__float__`, which can read or write the // same buffer. // TODO: Optimize - let data = self.format_spec.pack(vec![value], vm).map_err(|_| { - vm.new_type_error(format!( - "memoryview: invalid type for format '{}'", + // A value of the wrong kind and a value the format has no room for are + // different errors here, though packing reports both the same way. + let data = self.format_spec.try_pack(vec![value], vm).map_err(|err| { + let what = match err.kind { + PackErrorKind::Type => "type", + PackErrorKind::Value => "value", + PackErrorKind::Raised => return err.exception, + }; + let msg = format!( + "memoryview: invalid {what} for format '{}'", self.desc.format - )) + ); + match err.kind { + PackErrorKind::Type => vm.new_type_error(msg), + _ => vm.new_value_error(msg), + } })?; // The conversion, and the index that produced `pos`, could have released // the view; `pos` addresses a buffer that is no longer there. @@ -842,6 +854,9 @@ impl PyMemoryView { } fn __delitem__(&self, _needle: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { + self.try_not_released(vm)?; + // What cannot be written cannot be deleted from either, and that is + // the first thing answered. if self.desc.readonly { return Err(vm.new_type_error("cannot modify read-only memory")); } @@ -1133,10 +1148,6 @@ impl Py { if self.desc.readonly { return Err(vm.new_type_error("cannot modify read-only memory")); } - if value.is(&vm.ctx.none) { - return Err(vm.new_type_error("cannot delete memory")); - } - if self.desc.ndim() == 0 { // TODO: merge branches when we got conditional if let if needle.is(&vm.ctx.ellipsis) { @@ -1291,7 +1302,7 @@ impl AsMapping for PyMemoryView { if let Some(value) = value { zelf.__setitem__(needle.to_owned(), value, vm) } else { - Err(vm.new_type_error("cannot delete memory".to_owned())) + zelf.__delitem__(needle.to_owned(), vm) } }), }; @@ -1681,7 +1692,7 @@ impl PyMemoryViewIterator { impl SelfIter for PyMemoryViewIterator {} impl IterNext for PyMemoryViewIterator { fn next(zelf: &Py, vm: &VirtualMachine) -> PyResult { - zelf.internal.lock().next(|mv, pos| { + locked_next(&zelf.internal, |mv, pos| { let len = mv.__len__(vm)?; Ok(if pos >= len { PyIterReturn::StopIteration(None) diff --git a/crates/vm/src/builtins/range.rs b/crates/vm/src/builtins/range.rs index 5962f90e521..a315cef9d10 100644 --- a/crates/vm/src/builtins/range.rs +++ b/crates/vm/src/builtins/range.rs @@ -39,7 +39,7 @@ fn iter_search( ) -> PyResult { let mut count = 0; let iter = obj.get_iter(vm)?; - for element in iter.iter_without_hint::(vm)? { + for element in iter.iter::(vm)? { if vm.bool_eq(item, &*element?)? { match flag { SearchType::Index => return Ok(count), @@ -720,13 +720,17 @@ fn range_iter_reduce( vm: &VirtualMachine, ) -> PyTupleRef { let iter = builtins_iter(vm); + // CPython pickles the remaining range with a None state. next() increments + // the index unconditionally, so clamp it to length before rebasing start. + let index = BigInt::from(index).min(length.clone()); let stop = start.clone() + length * step.clone(); + let start = start + index * step.clone(); let range = PyRange { start: PyInt::from(start).into_ref(&vm.ctx), stop: PyInt::from(stop).into_ref(&vm.ctx), step: PyInt::from(step).into_ref(&vm.ctx), }; - vm.new_tuple((iter, (range,), index)) + vm.new_tuple((iter, (range,), vm.ctx.none())) } // Silently clips state (i.e index) in range [0, usize::MAX]. diff --git a/crates/vm/src/builtins/set.rs b/crates/vm/src/builtins/set.rs index d737612b158..7e6f43bbb4c 100644 --- a/crates/vm/src/builtins/set.rs +++ b/crates/vm/src/builtins/set.rs @@ -3,7 +3,7 @@ */ use super::{ IterStatus, PositionIterInternal, PyDict, PyDictRef, PyGenericAlias, PyTupleRef, PyType, - PyTypeRef, builtins_iter, + PyTypeRef, builtins_iter, locked_step, }; use crate::{ AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, @@ -378,13 +378,6 @@ impl PySetInner { Ok(true) } - fn iter(&self) -> PySetIterator { - PySetIterator { - size: self.content.size(), - internal: PyMutex::new(PositionIterInternal::new(self.content.clone(), 0)), - } - } - fn repr(&self, class_name: Option<&str>, vm: &VirtualMachine) -> PyResult { let empty = format!("{}()", class_name.unwrap_or("set")); collection_repr(class_name, "{", "}", &empty, self.elements().iter(), vm) @@ -933,7 +926,10 @@ impl Comparable for PySet { impl Iterable for PySet { fn iter(zelf: PyRef, vm: &VirtualMachine) -> PyResult { - Ok(zelf.inner.iter().into_pyobject(vm)) + Ok(PySetIterator::new(AnySet { + object: zelf.into(), + }) + .into_pyobject(vm)) } } @@ -1351,7 +1347,10 @@ impl Comparable for PyFrozenSet { impl Iterable for PyFrozenSet { fn iter(zelf: PyRef, vm: &VirtualMachine) -> PyResult { - Ok(zelf.inner.iter().into_pyobject(vm)) + Ok(PySetIterator::new(AnySet { + object: zelf.into(), + }) + .into_pyobject(vm)) } } @@ -1487,7 +1486,11 @@ impl TryFromObject for AnySet { #[pyclass(module = false, name = "set_iterator")] pub(crate) struct PySetIterator { size: DictSize, - internal: PyMutex>>, + /// Whether the set was found to have changed, which `setiter_iternext()` + /// records by writing a size no set can have. Sticky: what it makes the + /// iterator answer, it answers from then on. + changed: PyAtomic, + internal: PyMutex>, } impl fmt::Debug for PySetIterator { @@ -1504,11 +1507,33 @@ impl PyPayload for PySetIterator { } } +impl PySetIterator { + fn new(set: AnySet) -> Self { + Self { + size: set.as_inner().content.size(), + changed: Radium::new(false), + internal: PyMutex::new(PositionIterInternal::new(set, 0)), + } + } +} + #[pyclass(flags(DISALLOW_INSTANTIATION), with(IterNext, Iterable))] impl PySetIterator { #[pymethod] fn __length_hint__(&self) -> usize { - self.internal.lock().length_hint(|_| self.size.entries_size) + // `setiter_len()` answers for a set it can no longer walk with nothing, + // comparing the size it captured against the set's own every time it is + // asked. + if self.changed.load(Ordering::Relaxed) { + return 0; + } + self.internal.lock().length_hint(|set| { + if set.as_inner().content.size() == self.size { + self.size.entries_size + } else { + 0 + } + }) } #[pymethod] @@ -1519,9 +1544,13 @@ impl PySetIterator { (vm.ctx .new_list(match &internal.status { IterStatus::Exhausted => vec![], - IterStatus::Active(dict) => { - dict.keys().into_iter().skip(internal.position).collect() - } + IterStatus::Active(set) => set + .as_inner() + .content + .keys() + .into_iter() + .skip(internal.position) + .collect(), }) .into(),), ) @@ -1531,26 +1560,33 @@ impl PySetIterator { impl SelfIter for PySetIterator {} impl IterNext for PySetIterator { fn next(zelf: &crate::Py, vm: &VirtualMachine) -> PyResult { - let mut internal = zelf.internal.lock(); - let next = if let IterStatus::Active(dict) = &internal.status { - match dict.next_entry_checked(internal.position, &zelf.size, |key, ()| key.clone()) { + locked_step(&zelf.internal, |internal| { + let IterStatus::Active(set) = &internal.status else { + return (Ok(PyIterReturn::StopIteration(None)), None); + }; + let mutated = || vm.new_runtime_error("Set changed size during iteration"); + if zelf.changed.load(Ordering::Relaxed) { + // The set is not looked at again once it has been found to + // change: an iterator that has raised keeps raising. + return (Err(mutated()), None); + } + let entry = set.as_inner().content.next_entry_checked( + internal.position, + &zelf.size, + |key, ()| key.clone(), + ); + match entry { Err(crate::dict_inner::DictChanged) => { - internal.status = IterStatus::Exhausted; - return Err(vm.new_runtime_error("set changed size during iteration")); + zelf.changed.store(true, Ordering::Relaxed); + (Err(mutated()), None) } Ok(Some((position, key))) => { internal.position = position; - PyIterReturn::Return(key) - } - Ok(None) => { - internal.status = IterStatus::Exhausted; - PyIterReturn::StopIteration(None) + (Ok(PyIterReturn::Return(key)), None) } + Ok(None) => (Ok(PyIterReturn::StopIteration(None)), internal.exhaust()), } - } else { - PyIterReturn::StopIteration(None) - }; - Ok(next) + }) } } diff --git a/crates/vm/src/builtins/slice.rs b/crates/vm/src/builtins/slice.rs index 026b976b65e..4eb6c0f9b0e 100644 --- a/crates/vm/src/builtins/slice.rs +++ b/crates/vm/src/builtins/slice.rs @@ -373,7 +373,7 @@ impl Representable for PySlice { } } -#[pyclass(module = false, name = "EllipsisType")] +#[pyclass(module = false, name = "ellipsis")] #[derive(Debug)] pub struct PyEllipsis; diff --git a/crates/vm/src/builtins/str.rs b/crates/vm/src/builtins/str.rs index 6e774f7e652..dc5a1daf4b9 100644 --- a/crates/vm/src/builtins/str.rs +++ b/crates/vm/src/builtins/str.rs @@ -1,10 +1,7 @@ use super::{ PositionIterInternal, PyBytesRef, PyDict, PyTupleRef, PyType, PyTypeRef, int::{PyInt, PyIntRef}, - iter::{ - IterStatus::{self, Exhausted}, - builtins_iter, - }, + iter::{IterStatus, builtins_iter}, }; use crate::{ AsObject, Context, Py, PyExact, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult, @@ -379,7 +376,11 @@ impl IterNext for PyStrIterator { internal.1 += ch.len_wtf8(); return Ok(PyIterReturn::Return(ch.to_pyobject(vm))); } - internal.0.status = Exhausted; + let released = internal.0.exhaust(); + // The string is released after the lock. A `__del__` that iterates + // again would otherwise reach for a lock this call still holds. + drop(internal); + drop(released); } Ok(PyIterReturn::StopIteration(None)) } @@ -1173,7 +1174,9 @@ impl PyStr { iterable: ArgIterable, vm: &VirtualMachine, ) -> PyResult { - let iter = iterable.iter(vm)?; + // `PyUnicode_Join()` reaches its elements through `PySequence_Fast()`, + // which fills a list from the iterator and so asks it how long it is. + let iter = iterable.iter_sized(vm)?; let joined = match iter.exactly_one() { Ok(first) => { let first = first?; diff --git a/crates/vm/src/builtins/tuple.rs b/crates/vm/src/builtins/tuple.rs index d510e35326f..3bd53094e8c 100644 --- a/crates/vm/src/builtins/tuple.rs +++ b/crates/vm/src/builtins/tuple.rs @@ -1,5 +1,6 @@ use super::{ PositionIterInternal, PyGenericAlias, PyStrRef, PyType, PyTypeRef, iter::builtins_iter, + locked_next, }; use crate::common::lock::LazyLock; use crate::common::{hash, hash::PyHash, lock::PyMutex, wtf8::wtf8_concat}; @@ -701,25 +702,23 @@ impl PyTupleIterator { impl PyTupleIterator { /// Fast path for FOR_ITER specialization. pub(crate) fn fast_next(&self) -> Option { - self.internal - .lock() - .next(|tuple, pos| { - Ok(PyIterReturn::from_result( - tuple.get(pos).cloned().ok_or(None), - )) - }) - .ok() - .and_then(|r| match r { - PyIterReturn::Return(v) => Some(v), - PyIterReturn::StopIteration(_) => None, - }) + locked_next(&self.internal, |tuple, pos| { + Ok(PyIterReturn::from_result( + tuple.get(pos).cloned().ok_or(None), + )) + }) + .ok() + .and_then(|r| match r { + PyIterReturn::Return(v) => Some(v), + PyIterReturn::StopIteration(_) => None, + }) } } impl SelfIter for PyTupleIterator {} impl IterNext for PyTupleIterator { fn next(zelf: &Py, _vm: &VirtualMachine) -> PyResult { - zelf.internal.lock().next(|tuple, pos| { + locked_next(&zelf.internal, |tuple, pos| { Ok(PyIterReturn::from_result( tuple.get(pos).cloned().ok_or(None), )) diff --git a/crates/vm/src/builtins/type.rs b/crates/vm/src/builtins/type.rs index 46e2e4ebfc6..20ccf64dc1b 100644 --- a/crates/vm/src/builtins/type.rs +++ b/crates/vm/src/builtins/type.rs @@ -2179,7 +2179,14 @@ impl Constructor for PyType { name.clone().into_wtf8() }); - let mut attributes = dict.to_attributes(vm); + let mut attributes = dict.to_attributes(vm, |vm| { + crate::stdlib::_warnings::warn( + vm.ctx.exceptions.runtime_warning, + format!("non-string key in the __dict__ of class {name}"), + 1, + vm, + ) + })?; attributes.shift_remove(identifier!(vm, __qualname__)); // Check __doc__ for surrogates - raises UnicodeEncodeError during type creation diff --git a/crates/vm/src/byte.rs b/crates/vm/src/byte.rs index 0e90f296ac9..b22fb54fa08 100644 --- a/crates/vm/src/byte.rs +++ b/crates/vm/src/byte.rs @@ -3,21 +3,64 @@ use num_traits::ToPrimitive; use crate::{ - AsObject, PyObject, PyResult, VirtualMachine, + AsObject, PyObject, PyObjectRef, PyResult, VirtualMachine, protocol::{BufferFlags, PyBuffer}, }; // PyBytes_FromObject pub fn bytes_from_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult> { + collect_bytes(vm, obj, true, |name| { + format!("cannot convert '{name}' object to bytes") + }) +} + +/// [`bytes_from_object`] for the bytearray constructor and for assigning to a +/// slice of one, which run the iterator without asking the object they were +/// handed how long it is. +pub fn bytearray_from_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult> { + collect_bytes(vm, obj, false, |name| { + format!("cannot convert '{name}' object to bytearray") + }) +} + +/// [`bytes_from_object`] for `bytearray_extend()`, which names what it was +/// doing rather than what it was converting to. +pub fn bytearray_extend_from_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult> { + collect_bytes(vm, obj, true, |name| { + format!("can't extend bytearray with {name}") + }) +} + +/// `measured` is whether the object is asked how long it is; `unusable` names, +/// from the class name, what could not be done with one that is not iterable. +fn collect_bytes( + vm: &VirtualMachine, + obj: &PyObject, + measured: bool, + unusable: impl FnOnce(&str) -> String, +) -> PyResult> { if obj.check_buffer() { let buffer = PyBuffer::from_object(vm, obj, BufferFlags::FULL_RO)?; return Ok(buffer.contiguous_or_collect(|bytes| bytes.to_vec())); } - if !obj.fast_isinstance(vm.ctx.types.str_type) - && let Ok(elements) = vm.map_iterable_object(obj, |x| value_from_object(vm, &x)) - { - return elements; + if !obj.fast_isinstance(vm.ctx.types.str_type) { + // What `PyObject_GetIter()` cannot take is answered for by the caller, + // which knows what it was being asked to do, rather than by the + // iteration protocol saying the object is not iterable. + let cls = obj.class(); + if cls.slots.iter.load().is_none() && !cls.has_attr(identifier!(vm, __getitem__)) { + return Err(vm.new_type_error(unusable(&cls.name()))); + } + let value = |x: PyObjectRef| value_from_object(vm, &x); + let elements = if measured { + vm.map_iterable_object_sized(obj, value) + } else { + vm.map_iterable_object(obj, value) + }; + if let Ok(elements) = elements { + return elements; + } } Err(vm.new_type_error("can assign only bytes, buffers, or iterables of ints in range(0, 256)")) diff --git a/crates/vm/src/bytes_inner.rs b/crates/vm/src/bytes_inner.rs index e16c636a964..d87fee4c2a2 100644 --- a/crates/vm/src/bytes_inner.rs +++ b/crates/vm/src/bytes_inner.rs @@ -7,7 +7,6 @@ use crate::{ PyBaseExceptionRef, PyByteArray, PyBytes, PyBytesRef, PyInt, PyIntRef, PyStr, PyStrRef, pystr, pystr::PyUtf8StrRef, }, - byte::bytes_from_object, cformat::cformat_bytes, common::hash, common::wtf8::is_py_ascii_whitespace, @@ -17,6 +16,11 @@ use crate::{ sequence::{SequenceExt, SequenceMutExt}, types::PyComparisonOp, }; +/// How a source object that is neither a size nor a string is turned into +/// bytes: [`crate::byte::bytes_from_object`] or +/// [`crate::byte::bytearray_from_object`]. +pub(crate) type FromObject = fn(&VirtualMachine, &PyObject) -> PyResult>; + use bstr::ByteSlice; use itertools::Itertools; use malachite_bigint::BigInt; @@ -64,8 +68,12 @@ impl ByteInnerNewOptions { Ok(bytes.as_bytes().to_vec().into()) } - fn get_value_from_source(source: PyObjectRef, vm: &VirtualMachine) -> PyResult { - bytes_from_object(vm, &source).map(|x| x.into()) + fn get_value_from_source( + source: PyObjectRef, + from_object: FromObject, + vm: &VirtualMachine, + ) -> PyResult { + from_object(vm, &source).map(|x| x.into()) } fn get_value_from_size(size: PyIntRef, vm: &VirtualMachine) -> PyResult { @@ -81,19 +89,26 @@ impl ByteInnerNewOptions { Ok(vm.new_zeroed_bytes(size)?.into()) } - fn handle_object_fallback(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult { + fn handle_object_fallback( + obj: PyObjectRef, + from_object: FromObject, + vm: &VirtualMachine, + ) -> PyResult { match_class!(match obj { i @ PyInt => { Self::get_value_from_size(i, vm) } _s @ PyStr => Err(vm.new_type_error(STRING_WITHOUT_ENCODING.to_owned())), obj => { - Self::get_value_from_source(obj, vm) + Self::get_value_from_source(obj, from_object, vm) } }) } - pub fn get_bytearray_inner(self, vm: &VirtualMachine) -> PyResult { + /// `from_object` is how a source that is neither a size nor a string is + /// read: `bytes()` and `bytearray()` differ in whether they ask it how long + /// it is. + pub fn get_inner(self, from_object: FromObject, vm: &VirtualMachine) -> PyResult { match (self.source, self.encoding, self.errors) { (OptionalArg::Present(obj), OptionalArg::Missing, OptionalArg::Missing) => { // Try __index__ first to handle int-like objects that might raise custom exceptions @@ -105,7 +120,7 @@ impl ByteInnerNewOptions { // TypeError means the object doesn't support __index__, so fall back if e.fast_isinstance(vm.ctx.exceptions.type_error) { // Fall back to treating as buffer-like object - Self::handle_object_fallback(obj, vm) + Self::handle_object_fallback(obj, from_object, vm) } else { // Propagate other exceptions (e.g., ZeroDivisionError) Err(e) @@ -113,7 +128,7 @@ impl ByteInnerNewOptions { } } } else { - Self::handle_object_fallback(obj, vm) + Self::handle_object_fallback(obj, from_object, vm) } } (OptionalArg::Present(obj), OptionalArg::Present(encoding), errors) => { @@ -614,7 +629,8 @@ impl PyBytesInner { } pub fn join(&self, iterable: ArgIterable, vm: &VirtualMachine) -> PyResult> { - let iter = iterable.iter(vm)?; + // `PySequence_Fast()`, as in `PyUnicode_Join()`. + let iter = iterable.iter_sized(vm)?; self.elements.py_join(iter) } diff --git a/crates/vm/src/exception_group.rs b/crates/vm/src/exception_group.rs index 11c13912b76..333c268fbc5 100644 --- a/crates/vm/src/exception_group.rs +++ b/crates/vm/src/exception_group.rs @@ -95,8 +95,13 @@ pub(super) mod types { for exc in exceptions { if is_base_exception_group(&exc, vm) { - // Recursive call for nested groups - let subgroup_result = vm.call_method(&exc, "subgroup", (condition.clone(),))?; + // Recursive call for nested groups. It pushes no Python + // frame, so a deep enough group runs off the native stack + // unless this guard is here. + let subgroup_result = vm + .with_recursion("in exception group subgroup", || { + vm.call_method(&exc, "subgroup", (condition.clone(),)) + })?; if !vm.is_none(&subgroup_result) { matching.push(subgroup_result.clone()); } @@ -142,7 +147,11 @@ pub(super) mod types { for exc in exceptions { if is_base_exception_group(&exc, vm) { - let result = vm.call_method(&exc, "split", (condition.clone(),))?; + // Same as in subgroup: nothing else bounds this recursion + // against the native stack. + let result = vm.with_recursion("in exception group split", || { + vm.call_method(&exc, "split", (condition.clone(),)) + })?; let result_tuple: PyTupleRef = result.try_into_value(vm)?; let match_part = result_tuple .first() diff --git a/crates/vm/src/format.rs b/crates/vm/src/format.rs index 657601e1470..75f5c32f0c3 100644 --- a/crates/vm/src/format.rs +++ b/crates/vm/src/format.rs @@ -86,6 +86,10 @@ impl IntoPyException for FormatSpecError { Self::StringAlignmentFlag => { vm.new_value_error("'=' alignment not allowed in string format specifier") } + Self::StringSpecNotAllowed(s) => { + let msg = format!("{s} not allowed in string format specifier"); + vm.new_value_error(msg) + } Self::NotImplemented(c, s) => { let msg = format!("Format code '{c}' for object of type '{s}' not implemented yet"); vm.new_value_error(msg) @@ -143,14 +147,21 @@ fn format_internal( FormatString::from_str(format_spec).map_err(|e| e.to_pyexception(vm))?; let format_spec = format_internal(vm, &nested_format, field_func)?; - let argument = match conversion_spec.and_then(FormatConversion::from_char) { - Some(FormatConversion::Str) => argument.str(vm)?.into(), - Some(FormatConversion::Repr) => argument.repr(vm)?.into(), - Some(FormatConversion::Ascii) => builtins::ascii(argument, vm)?.into(), - Some(FormatConversion::Bytes) => { - vm.call_method(&argument, identifier!(vm, decode).as_str(), ())? - } + let argument = match conversion_spec { None => argument, + Some(c) => match FormatConversion::from_char(*c) { + Some(FormatConversion::Str) => argument.str(vm)?.into(), + Some(FormatConversion::Repr) => argument.repr(vm)?.into(), + Some(FormatConversion::Ascii) => builtins::ascii(argument, vm)?.into(), + Some(FormatConversion::Bytes) => { + vm.call_method(&argument, identifier!(vm, decode).as_str(), ())? + } + None => { + return Err( + vm.new_value_error(format!("Unknown conversion specifier {c}")) + ); + } + }, }; // FIXME: compiler can intern specs using parser tree. Then this call can be interned_str diff --git a/crates/vm/src/function/protocol.rs b/crates/vm/src/function/protocol.rs index d503fabaca8..5d5e4527f57 100644 --- a/crates/vm/src/function/protocol.rs +++ b/crates/vm/src/function/protocol.rs @@ -91,16 +91,30 @@ impl ArgIterable { &self.iterable } - /// Returns an iterator over this sequence of objects. + /// This object's iterator. /// /// This operation may fail if an exception is raised while invoking the /// `__iter__` method of the iterable object. - pub fn iter<'a>(&self, vm: &'a VirtualMachine) -> PyResult> { - let iter = PyIter::new(match self.iter_fn { + fn get_iter(&self, vm: &VirtualMachine) -> PyResult { + Ok(PyIter::new(match self.iter_fn { Some(f) => f(self.iterable.clone(), vm)?, None => PySequenceIterator::new(self.iterable.clone(), vm)?.into_pyobject(vm), - }); - iter.into_iter(vm) + })) + } + + /// Returns an iterator over this sequence of objects. See [`PyIter::iter`] + /// for why it does not ask how long the iterator is. + /// + /// This operation may fail if an exception is raised while invoking the + /// `__iter__` method of the iterable object. + pub fn iter<'a>(&self, vm: &'a VirtualMachine) -> PyResult> { + Ok(self.get_iter(vm)?.into_iter(vm)) + } + + /// [`Self::iter`] for a caller that fills a sized container from the + /// iterator, the way `PySequence_Fast()` does. + pub fn iter_sized<'a>(&self, vm: &'a VirtualMachine) -> PyResult> { + self.get_iter(vm)?.into_iter_sized(vm) } } diff --git a/crates/vm/src/gc_state.rs b/crates/vm/src/gc_state.rs index e5eb3758950..3a3440fb557 100644 --- a/crates/vm/src/gc_state.rs +++ b/crates/vm/src/gc_state.rs @@ -4,7 +4,7 @@ use crate::common::linked_list::LinkedList; use crate::common::lock::{PyMutex, PyRwLock}; -use crate::object::{GC_NO_OWNER, GC_PERMANENT, GC_UNTRACKED, GcLink, GcOwner}; +use crate::object::{GC_NO_OWNER, GC_PERMANENT, GC_REACHABLE, GC_UNTRACKED, GcLink, GcOwner}; use crate::{AsObject, PyObject, PyObjectRef}; use core::ptr::NonNull; use core::sync::atomic::{AtomicBool, AtomicU16, AtomicU32, AtomicUsize, Ordering}; @@ -160,11 +160,11 @@ struct GcPtr(NonNull); /// choosing keys that collide. Nothing chooses these keys: they are addresses /// this process handed out, and the tables live and die inside one collection. /// What a collection needs from them is speed -- it hashes every tracked -/// object and every edge between them -- so this runs the address through a -/// handful of multiplies and shifts instead. The shifts are what earns the -/// speed: a table picks its bucket from the low bits, and an address arrives -/// with its low bits zeroed by alignment, so entropy has to be carried -/// downward or every object lands in the same few buckets. +/// object -- so this runs the address through a handful of multiplies and +/// shifts instead. The shifts are what earns the speed: a table picks its +/// bucket from the low bits, and an address arrives with its low bits zeroed +/// by alignment, so entropy has to be carried downward or every object lands +/// in the same few buckets. #[derive(Default)] struct GcPtrHasher(u64); @@ -299,9 +299,9 @@ impl Drop for CollectStopTheWorld { pub struct GcState { /// Per-generation intrusive linked lists for object tracking. /// Objects start in gen0, survivors are promoted to gen1, then gen2. - generation_lists: [PyRwLock>; 3], + generation_lists: [PyRwLock>; 3], /// Frozen/permanent objects (excluded from normal GC) - permanent_list: PyRwLock>, + permanent_list: PyRwLock>, /// Number of tracked objects per generation, across all interpreters. /// /// Advisory: they drive the collection threshold and `gc.get_count()`, and @@ -322,7 +322,7 @@ pub struct GcState { } // SAFETY: All fields are either inherently Send/Sync (atomics, RwLock, Mutex) or protected by PyMutex. -// LinkedList is Send+Sync because GcLink's Target (PyObject) is Send+Sync. +// LinkedList is Send+Sync because GcLink's Target (PyObject) is Send+Sync. #[cfg(feature = "threading")] unsafe impl Send for GcState {} #[cfg(feature = "threading")] @@ -418,8 +418,7 @@ impl GcState { let (list_lock, count) = if obj_gen <= 2 { ( - &self.generation_lists[obj_gen as usize] - as &PyRwLock>, + &self.generation_lists[obj_gen as usize] as &PyRwLock>, &self.counts[obj_gen as usize], ) } else if obj_gen == GC_PERMANENT { @@ -459,7 +458,7 @@ impl GcState { /// If generation is Some(n), returns those in generation n only. pub fn get_objects(&self, generation: Option, owner: GcOwner) -> Vec { fn collect_from_list( - list: &LinkedList, + list: &LinkedList, owner: GcOwner, ) -> impl Iterator + '_ { list.iter() @@ -594,12 +593,12 @@ impl GcState { retired.sort_unstable(); retired }; - // The candidates and their reference counts go in one table, not a set - // beside a map: every edge in the heap is looked up here, and the two - // held the same keys, so a second table only bought a second hash of - // the same address. `candidate_ptrs` keeps them in a walkable order, - // since the counts are written while the candidates are read. - let mut gc_refs: GcMap = GcMap::default(); + // Each candidate carries its own count, with `GcBits::COLLECTING` + // saying the count is there. Every edge in the heap is answered from + // that bit and that field; a table keyed by address turned each of + // those answers into a hash of the address instead. `candidate_ptrs` + // keeps the candidates in a walkable order, and the bit is what keeps + // an object that appears in two generation lists out of it twice. let mut candidate_ptrs: Vec = Vec::new(); for gen_list in &gen_locks { for obj in gen_list.iter() { @@ -607,12 +606,9 @@ impl GcState { obj.set_gc_owner(GC_NO_OWNER); } let strong_count = obj.strong_count(); - let ptr = GcPtr(NonNull::from(obj)); - if strong_count > 0 - && is_owned_by(obj, owner) - && gc_refs.insert(ptr, strong_count).is_none() - { - candidate_ptrs.push(ptr); + if strong_count > 0 && is_owned_by(obj, owner) && !obj.is_gc_collecting() { + obj.start_gc_refs(strong_count); + candidate_ptrs.push(GcPtr(NonNull::from(obj))); } } } @@ -679,24 +675,23 @@ impl GcState { unsafe { obj.gc_extend_referent_ptrs(&mut referent_ptrs) }; let end = referent_ptrs.len(); for &child_ptr in &referent_ptrs[start..end] { - if let Some(refs) = gc_refs.get_mut(&GcPtr(child_ptr)) { - *refs = refs.saturating_sub(1); + // SAFETY: the referents came from `traverse`, which handed out + // live references to them, and the world is stopped. + let child = unsafe { child_ptr.as_ref() }; + if child.is_gc_collecting() { + child.subtract_gc_ref(); } } referent_ranges.insert(ptr, (start, end)); } // Step 4: Find reachable objects (gc_refs > 0) and traverse from them - let mut reachable: GcSet = GcSet::default(); let mut worklist: Vec = Vec::new(); - #[expect( - clippy::iter_over_hash_type, - reason = "Iteration order doesn't matter here" - )] - for (&ptr, &refs) in &gc_refs { - if refs > 0 { - reachable.insert(ptr); + for &ptr in &candidate_ptrs { + let obj = unsafe { ptr.0.as_ref() }; + if obj.gc_refs() > 0 { + obj.mark_gc_reachable(); worklist.push(ptr); } } @@ -717,20 +712,29 @@ impl GcState { } }; for &child_ptr in children { - let gc_ptr = GcPtr(child_ptr); - if gc_refs.contains_key(&gc_ptr) && reachable.insert(gc_ptr) { - worklist.push(gc_ptr); + // SAFETY: as in step 3, the referents are live. + let child = unsafe { child_ptr.as_ref() }; + if child.is_gc_collecting() && child.mark_gc_reachable() { + worklist.push(GcPtr(child_ptr)); } } } } - // Step 5: Find unreachable objects - let unreachable: Vec = candidate_ptrs - .iter() - .filter(|ptr| !reachable.contains(ptr)) - .copied() - .collect(); + // Step 5: Split the candidates on what step 4 concluded, and hand the + // headers back: nothing past here reads `gc_refs`, and a candidate that + // kept the bit would be passed over by every later collection. + let mut reachable: Vec = Vec::new(); + let mut unreachable: Vec = Vec::new(); + for &ptr in &candidate_ptrs { + let obj = unsafe { ptr.0.as_ref() }; + if obj.gc_refs() == GC_REACHABLE { + reachable.push(ptr); + } else { + unreachable.push(ptr); + } + obj.end_gc_refs(); + } // With the world stopped, every frame on any thread's call stack is a // live root that is externally referenced and must have been diff --git a/crates/vm/src/object/core.rs b/crates/vm/src/object/core.rs index bdacb7c5b83..02ffe2c7e5e 100644 --- a/crates/vm/src/object/core.rs +++ b/crates/vm/src/object/core.rs @@ -297,6 +297,9 @@ bitflags::bitflags! { const SHARED_INLINE = 1 << 5; /// Use deferred reference counting const DEFERRED = 1 << 6; + /// In the candidate set of the collection that is running, so its + /// `gc_refs` is meaningful. `_PyGC_PREV_MASK_COLLECTING`. + const COLLECTING = 1 << 7; } } @@ -316,6 +319,11 @@ pub(crate) type GcOwner = u16; /// current. Every interpreter collects these. pub(crate) const GC_NO_OWNER: GcOwner = 0; +/// `gc_refs` of an object a running collection has proved reachable. One past +/// the largest count [`PyObject::start_gc_refs`] stores, so no real count can +/// be taken for it. +pub(crate) const GC_REACHABLE: u32 = u32::MAX; + /// Link implementation for GC intrusive linked list tracking pub(crate) struct GcLink; @@ -405,6 +413,11 @@ pub(super) struct PyInner { /// `track_object`; read to scope a collection to one interpreter. /// Sits in what would otherwise be padding, so it costs no space. pub(super) gc_owner: PyAtomic, + /// The count a running collection is working with: the strong count with + /// the references held from inside the candidate set taken off, or + /// [`GC_REACHABLE`] once the object has been proved reachable. Only + /// meaningful while `gc_bits` has [`GcBits::COLLECTING`]. + pub(super) gc_refs: PyAtomic, /// Intrusive linked list pointers for GC generational tracking pub(super) gc_pointers: Pointers, @@ -415,9 +428,22 @@ pub(super) struct PyInner { pub(crate) const SIZEOF_PYOBJECT_HEAD: usize = core::mem::size_of::>(); // ref_count, vtable, gc_pointers (two) and typ are one word each; the gc bits, -// generation and owner share the word of padding their alignment forces. Adding -// to that group is free only while this holds. -const _: () = assert!(SIZEOF_PYOBJECT_HEAD == 6 * core::mem::size_of::()); +// generation, owner and refs take eight bytes between them. A 64-bit header had +// those eight as the padding its alignment forces, so they cost it nothing; a +// 32-bit header spends a word on them. Adding to that group is free only while +// this holds. +const _: () = assert!(SIZEOF_PYOBJECT_HEAD == 5 * core::mem::size_of::() + 8); + +// `PyInner::drop_fields` names `payload` and `typ`; it is only complete while +// every other field stays trivially destructible. +const _: () = assert!( + !core::mem::needs_drop::() + && !core::mem::needs_drop::<&'static PyObjVTable>() + && !core::mem::needs_drop::>() + && !core::mem::needs_drop::>() + && !core::mem::needs_drop::>() + && !core::mem::needs_drop::>() +); impl PyInner { /// Read type flags and member_count via raw pointers to avoid Stacked Borrows @@ -1109,6 +1135,20 @@ impl InstanceDict { } impl PyInner { + /// Run the destructors of the fields that have one, payload first. + /// + /// Declaration order would drop `typ` first, and `PyAtomicRef::drop` + /// leaves it null. A weakref payload is still linked into the list of the + /// object it points at until its own `Drop` unlinks it, and a thread + /// walking that list reads the class off every node it passes, so the + /// class has to outlive the payload. + unsafe fn drop_fields(ptr: *mut Self) { + unsafe { + core::ptr::drop_in_place(&raw mut (*ptr).payload); + core::ptr::drop_in_place(&raw mut (*ptr).typ); + } + } + /// Deallocate a PyInner, handling optional prefix(es). /// Layout: [ObjExt?][WeakRefList?][PyInner] /// @@ -1146,8 +1186,7 @@ impl PyInner { let alloc_ptr = (ptr as *mut u8).sub(inner_offset); - // Drop PyInner (payload, typ, etc.) - core::ptr::drop_in_place(ptr); + Self::drop_fields(ptr); // Drop ObjExt if present (dict, slots) if has_ext { @@ -1162,10 +1201,13 @@ impl PyInner { } } else if published { let layout = core::alloc::Layout::new::(); - core::ptr::drop_in_place(ptr); + Self::drop_fields(ptr); crate::object::qsbr::free_delayed(ptr as *mut u8, layout); } else { - drop(Box::from_raw(ptr)); + Self::drop_fields(ptr); + // The fields are gone; the box is only here to free the memory + // the matching `Box::new` in `new` allocated. + drop(Box::from_raw(ptr.cast::>())); } } } @@ -1248,6 +1290,7 @@ impl PyInner { gc_bits: Radium::new(0), gc_generation: Radium::new(GC_UNTRACKED), gc_owner: Radium::new(GC_NO_OWNER), + gc_refs: Radium::new(0), gc_pointers: Pointers::new(), typ: PyAtomicRef::from(typ), payload, @@ -1261,6 +1304,7 @@ impl PyInner { gc_bits: Radium::new(0), gc_generation: Radium::new(GC_UNTRACKED), gc_owner: Radium::new(GC_NO_OWNER), + gc_refs: Radium::new(0), gc_pointers: Pointers::new(), typ: PyAtomicRef::from(typ), payload, @@ -1803,6 +1847,67 @@ impl PyObject { self.0.gc_owner.store(owner, Ordering::Relaxed); } + /// Enter the running collection's candidate set, with `strong_count` as the + /// count to subtract internal references from. A count too large to hold is + /// taken as reachable outright, rather than clipped to a number the + /// subtraction could still walk down to zero. + #[inline] + pub(crate) fn start_gc_refs(&self, strong_count: usize) { + let refs = if strong_count >= GC_REACHABLE as usize { + GC_REACHABLE + } else { + strong_count as u32 + }; + self.0.gc_refs.store(refs, Ordering::Relaxed); + self.set_gc_bit(GcBits::COLLECTING); + } + + /// The count the running collection is working with. + #[inline] + pub(crate) fn gc_refs(&self) -> u32 { + self.0.gc_refs.load(Ordering::Relaxed) + } + + /// Whether this object is in the running collection's candidate set. + #[inline] + pub(crate) fn is_gc_collecting(&self) -> bool { + GcBits::from_bits_retain(self.0.gc_bits.load(Ordering::Relaxed)) + .contains(GcBits::COLLECTING) + } + + /// Take off one reference held from inside the candidate set. A count that + /// did not fit stands for more references than every subtraction together + /// could take off, so it stays where [`Self::start_gc_refs`] put it. + #[inline] + pub(crate) fn subtract_gc_ref(&self) { + let refs = self.0.gc_refs.load(Ordering::Relaxed); + if refs == GC_REACHABLE { + return; + } + self.0 + .gc_refs + .store(refs.saturating_sub(1), Ordering::Relaxed); + } + + /// Mark the object reachable, answering whether this call was the one that + /// did it. + #[inline] + pub(crate) fn mark_gc_reachable(&self) -> bool { + if self.0.gc_refs.load(Ordering::Relaxed) == GC_REACHABLE { + return false; + } + self.0.gc_refs.store(GC_REACHABLE, Ordering::Relaxed); + true + } + + /// Leave the candidate set, whatever the collection concluded. + #[inline] + pub(crate) fn end_gc_refs(&self) { + self.0 + .gc_bits + .fetch_and(!GcBits::COLLECTING.bits(), Ordering::Relaxed); + } + /// _PyObject_GC_TRACK #[inline] pub(crate) fn set_gc_tracked(&self) { @@ -2723,6 +2828,7 @@ pub(crate) fn init_type_hierarchy() -> (PyTypeRef, PyTypeRef, PyTypeRef) { gc_bits: Radium::new(0), gc_generation: Radium::new(GC_UNTRACKED), gc_owner: Radium::new(GC_NO_OWNER), + gc_refs: Radium::new(0), gc_pointers: Pointers::new(), payload: type_payload, }, @@ -2739,6 +2845,7 @@ pub(crate) fn init_type_hierarchy() -> (PyTypeRef, PyTypeRef, PyTypeRef) { gc_bits: Radium::new(0), gc_generation: Radium::new(GC_UNTRACKED), gc_owner: Radium::new(GC_NO_OWNER), + gc_refs: Radium::new(0), gc_pointers: Pointers::new(), payload: object_payload, }, @@ -2827,4 +2934,53 @@ mod tests { let obj = ctx.new_bytes(b"dfghjkl".to_vec()); drop(obj); } + + /// A weakref node stays linked into its target's list until its own + /// `Drop` unlinks it, and `WeakRefList::add` reads the class off every + /// node it walks looking for a proxy to reuse. A node that lost its class + /// while still linked made that walk dereference a null type pointer. + #[cfg(feature = "threading")] + #[test] + fn weakref_proxies_keep_their_class_while_linked() { + const THREADS: usize = 8; + const ROUNDS: usize = 20_000; + + crate::Interpreter::without_stdlib(Default::default()).enter(|vm| { + let target: PyObjectRef = vm + .ctx + .new_class( + None, + "WeakrefTarget", + vm.ctx.types.object_type.to_owned(), + Default::default(), + ) + .into(); + let workers = (0..THREADS) + .map(|_| { + let thread_vm = vm.new_thread(); + let target = target.clone(); + std::thread::spawn(move || { + thread_vm.run(|vm| { + let proxy_type = vm.ctx.types.weakproxy_type.to_owned(); + for _ in 0..ROUNDS { + let proxy = target + .downgrade_with_typ(None, proxy_type.clone(), vm) + .expect("a type object takes weakrefs"); + drop(proxy); + vm.check_signals().unwrap(); + } + }) + }) + }) + .collect::>(); + // Detach while joining: a thread that blocks attached never + // reaches a safepoint, so a collection started by a worker could + // not finish. + vm.allow_threads(|| { + for worker in workers { + worker.join().unwrap(); + } + }); + }); + } } diff --git a/crates/vm/src/object/mod.rs b/crates/vm/src/object/mod.rs index becfcabb1d4..b6c7590a86d 100644 --- a/crates/vm/src/object/mod.rs +++ b/crates/vm/src/object/mod.rs @@ -9,5 +9,5 @@ pub use self::core::*; pub use self::ext::*; pub use self::payload::*; pub(crate) use core::SIZEOF_PYOBJECT_HEAD; -pub(crate) use core::{GC_NO_OWNER, GC_PERMANENT, GC_UNTRACKED, GcLink, GcOwner}; +pub(crate) use core::{GC_NO_OWNER, GC_PERMANENT, GC_REACHABLE, GC_UNTRACKED, GcLink, GcOwner}; pub use traverse::{MaybeTraverse, Traverse, TraverseFn}; diff --git a/crates/vm/src/protocol/iter.rs b/crates/vm/src/protocol/iter.rs index 1aa0bcd5b13..3df72fd80eb 100644 --- a/crates/vm/src/protocol/iter.rs +++ b/crates/vm/src/protocol/iter.rs @@ -56,25 +56,31 @@ where iternext(self.0.borrow(), vm) } + /// Walks the iterator without asking it how long it is. Almost nothing + /// asks: a loop over an iterator takes no room up front, so what the + /// object would have answered -- slowly, or by raising -- never runs. pub fn iter<'a, 'b, U>( &'b self, vm: &'a VirtualMachine, - ) -> PyResult> { - let length_hint = vm.length_hint_opt(self.as_ref().to_owned())?; - Ok(PyIterIter::new(vm, self.0.borrow(), length_hint)) - } - - pub fn iter_without_hint<'a, 'b, U>( - &'b self, - vm: &'a VirtualMachine, ) -> PyResult> { Ok(PyIterIter::new(vm, self.0.borrow(), None)) } } impl PyIter { - /// Returns an iterator over this sequence of objects. - pub fn into_iter(self, vm: &VirtualMachine) -> PyResult> { + /// Returns an iterator over this sequence of objects. See [`Self::iter`] + /// for why it does not ask how long the iterator is. + pub fn into_iter(self, vm: &VirtualMachine) -> PyIterIter<'_, U, PyObjectRef> { + PyIterIter::new(vm, self.0, None) + } + + /// [`Self::into_iter`] for a caller that fills a sized container from the + /// iterator, the way `PySequence_Fast()` does. It asks how much room that + /// takes and answers with whatever asking raised. + pub fn into_iter_sized( + self, + vm: &VirtualMachine, + ) -> PyResult> { let length_hint = vm.length_hint_opt(self.as_object().to_owned())?; Ok(PyIterIter::new(vm, self.0, length_hint)) } diff --git a/crates/vm/src/signal.rs b/crates/vm/src/signal.rs index 16a097ea62b..d1ddd8c3cdd 100644 --- a/crates/vm/src/signal.rs +++ b/crates/vm/src/signal.rs @@ -88,17 +88,23 @@ fn trigger_signals(vm: &VirtualMachine) -> PyResult<()> { let signal_handlers = vm .signal_handlers .get() - .expect("should never fail since we check above") - .borrow(); + .expect("should never fail since we check above"); for (signum, trigger) in TRIGGERS.iter().enumerate().skip(1) { let triggered = trigger.swap(false, Ordering::Relaxed); + if !triggered { + continue; + } // SAFETY: TRIGGERS has the same length as the signal_handlers let signum = unsafe { SignalNum::new_unchecked(signum as i32) }; - if triggered - && let Some(handler) = &signal_handlers[signum] + // Read the handler out and drop the borrow before running it. A + // handler is free to call signal.signal(), which takes the same cell + // mutably, and a live read borrow turns that into a panic. + let handler = signal_handlers.borrow()[signum].clone(); + + if let Some(handler) = handler && let Some(callable) = handler.to_callable() { callable.invoke((signum.as_i32(), vm.ctx.none()), vm)?; diff --git a/crates/vm/src/stdlib/_ast.rs b/crates/vm/src/stdlib/_ast.rs index b36277f5456..887c3cc7d3a 100644 --- a/crates/vm/src/stdlib/_ast.rs +++ b/crates/vm/src/stdlib/_ast.rs @@ -388,17 +388,7 @@ fn text_range_to_source_range(source_file: &SourceFile, text_range: TextRange) - let start_row = index.line_index(text_range.start()); let end_row = index.line_index(text_range.end()); let start_col = text_range.start() - index.line_start(start_row, source); - let (end_row, end_col) = { - let end_col = text_range.end() - index.line_start(end_row, source); - if end_col == TextSize::new(0) && end_row > start_row { - let prev_line_end = text_range.end() - TextSize::new(1); - let row = index.line_index(prev_line_end); - let col = prev_line_end - index.line_start(row, source) + TextSize::new(1); - (row, col) - } else { - (end_row, end_col) - } - }; + let end_col = text_range.end() - index.line_start(end_row, source); PySourceRange { start: PySourceLocation { @@ -1035,7 +1025,7 @@ fn type_comment_parse_error( raw_location: range, location: source_range.start.to_source_location(), end_location: source_range.end.to_source_location(), - source_path: "".to_string(), + source_path: source_file.name().to_owned(), is_unclosed_bracket: false, } .into() @@ -1046,9 +1036,9 @@ fn future_feature_compile_error( source_file: &SourceFile, error: codegen::preprocess::FutureFeatureError, ) -> CompileError { - let location = source_file - .to_source_code() - .source_location(error.range.start(), PositionEncoding::Utf8); + let source_code = source_file.to_source_code(); + let location = source_code.source_location(error.range.start(), PositionEncoding::Utf8); + let end_location = source_code.source_location(error.range.end(), PositionEncoding::Utf8); let error = match error.kind { codegen::preprocess::FutureFeatureErrorKind::InvalidFeature(feature) => { codegen::error::CodegenErrorType::InvalidFutureFeature(feature) @@ -1059,6 +1049,7 @@ fn future_feature_compile_error( }; codegen::error::CodegenError { location: Some(location), + end_location: Some(end_location), error, source_path: source_file.name().to_owned(), } @@ -1763,7 +1754,7 @@ fn ipython_escape_command_syntax_error( raw_location: range, location: source_range.start.to_source_location(), end_location: source_range.end.to_source_location(), - source_path: "".to_owned(), + source_path: source_file.name().to_owned(), is_unclosed_bracket: false, } .into(), @@ -1797,23 +1788,29 @@ fn empty_arguments_object(vm: &VirtualMachine) -> PyObjectRef { pub(crate) fn parse( vm: &VirtualMachine, source: &str, + filename: &str, mode: parser::Mode, optimize: u8, target_version: Option, type_comments: bool, optimized_ast: bool, interactive: bool, - explicit_future_annotations: bool, + explicit_future_features: crate::bytecode::CodeFlags, dont_imply_dedent: bool, ) -> Result { - let source_file = SourceFileBuilder::new("".to_owned(), source.to_owned()).finish(); + let source_file = SourceFileBuilder::new(filename.to_owned(), source.to_owned()).finish(); let mut options = parser::ParseOptions::from(mode); let target_version = target_version.unwrap_or(ast::PythonVersion::PY314); if let Some(error) = feature_version_syntax_error(source, &source_file, target_version) { return Err(error); } options = options.with_target_version(target_version); - let parsed = parser::parse_unchecked(source, options); + let barry_source = rustpython_compiler::prepare_barry_as_flufl_source( + source, + options.clone(), + explicit_future_features.contains(crate::bytecode::CodeFlags::FUTURE_BARRY_AS_BDFL), + ); + let parsed = parser::parse_unchecked(barry_source.source(), options); let type_comment_source = type_comments.then(|| TypeCommentSource::new(source, parsed.tokens())); if let Some(lines) = &type_comment_source @@ -1823,17 +1820,23 @@ pub(crate) fn parse( } if let Err(errors) = parsed.as_result() { let parse_error = errors[0].clone(); + if let Some(error) = barry_source.diagnostic(Some(&parse_error), &source_file) { + return Err(error); + } let range = text_range_to_source_range(&source_file, parse_error.location); return Err(ParseError { error: parse_error.error, raw_location: parse_error.location, location: range.start.to_source_location(), end_location: range.end.to_source_location(), - source_path: "".to_string(), + source_path: source_file.name().to_owned(), is_unclosed_bracket: false, } .into()); } + if let Some(error) = barry_source.diagnostic(None, &source_file) { + return Err(error); + } if dont_imply_dedent && interactive && let Some(error) = rustpython_compiler::dont_imply_dedent_source_error(&source_file) @@ -1855,7 +1858,7 @@ pub(crate) fn parse( raw_location: error.range(), location: range.start.to_source_location(), end_location: range.end.to_source_location(), - source_path: "".to_string(), + source_path: source_file.name().to_owned(), is_unclosed_bracket: false, } .into()); @@ -1869,7 +1872,13 @@ pub(crate) fn parse( return Err(error); } + if let Some(error) = rustpython_compiler::leading_byte_order_mark_error(&source_file) { + return Err(error); + } let mut top = parsed.into_syntax(); + if let Some(error) = rustpython_compiler::unsupported_grammar_error(&top, &source_file) { + return Err(error); + } if let Some(error) = ipython_escape_command_syntax_error(&top, &source_file) { return Err(error); } @@ -1880,7 +1889,8 @@ pub(crate) fn parse( { let future_features = codegen::preprocess::checked_future_features(&top) .map_err(|err| future_feature_compile_error(&source_file, err))?; - let future_annotations = explicit_future_annotations + let future_annotations = explicit_future_features + .contains(crate::bytecode::CodeFlags::FUTURE_ANNOTATIONS) || future_features.contains(crate::bytecode::CodeFlags::FUTURE_ANNOTATIONS); if interactive && let ast::Mod::Module(module) = &mut top { codegen::preprocess::preprocess_statements( @@ -1945,6 +1955,7 @@ pub(crate) fn wrap_interactive(vm: &VirtualMachine, module_obj: PyObjectRef) -> pub(crate) fn parse_func_type( vm: &VirtualMachine, source: &str, + filename: &str, optimize: u8, target_version: Option, ) -> Result { @@ -1956,7 +1967,7 @@ pub(crate) fn parse_func_type( raw_location: TextRange::default(), location: SourceLocation::default(), end_location: SourceLocation::default(), - source_path: "".to_owned(), + source_path: filename.to_owned(), is_unclosed_bracket: false, } .into() @@ -1984,7 +1995,7 @@ pub(crate) fn parse_func_type( raw_location: TextRange::default(), location: SourceLocation::default(), end_location: SourceLocation::default(), - source_path: "".to_owned(), + source_path: filename.to_owned(), is_unclosed_bracket: false, } .into()); @@ -1994,7 +2005,7 @@ pub(crate) fn parse_func_type( let right = source[split_at + 2..].trim(); let parse_expr = |expr_src: &str| -> Result { - let source_file = SourceFileBuilder::new("".to_owned(), expr_src.to_owned()).finish(); + let source_file = SourceFileBuilder::new(filename.to_owned(), expr_src.to_owned()).finish(); let options = parser::ParseOptions::from(parser::Mode::Expression) .with_target_version(target_version.unwrap_or(ast::PythonVersion::PY314)); let parsed = parser::parse(expr_src, options).map_err(|parse_error| { @@ -2004,7 +2015,7 @@ pub(crate) fn parse_func_type( raw_location: parse_error.location, location: range.start.to_source_location(), end_location: range.end.to_source_location(), - source_path: "".to_string(), + source_path: source_file.name().to_owned(), is_unclosed_bracket: false, } })?; @@ -2025,7 +2036,7 @@ pub(crate) fn parse_func_type( return Err(invalid_func_type()); } let call_source = format!("__rustpython_func_type__({inner})"); - let source_file = SourceFileBuilder::new("".to_owned(), call_source.clone()).finish(); + let source_file = SourceFileBuilder::new(filename.to_owned(), call_source.clone()).finish(); let options = parser::ParseOptions::from(parser::Mode::Expression) .with_target_version(target_version.unwrap_or(ast::PythonVersion::PY314)); let parsed = parser::parse(&call_source, options).map_err(|parse_error| { @@ -2035,7 +2046,7 @@ pub(crate) fn parse_func_type( raw_location: parse_error.location, location: range.start.to_source_location(), end_location: range.end.to_source_location(), - source_path: "".to_string(), + source_path: source_file.name().to_owned(), is_unclosed_bracket: false, } })?; @@ -2477,6 +2488,7 @@ pub(crate) fn compile( ); let marker = codegen::error::CodegenError { location: Some(location), + end_location: None, error: codegen::error::CodegenErrorType::SyntaxError(message), source_path: source_path.clone(), }; diff --git a/crates/vm/src/stdlib/_ast/constant.rs b/crates/vm/src/stdlib/_ast/constant.rs index 6debbf5c0d1..189c1538d00 100644 --- a/crates/vm/src/stdlib/_ast/constant.rs +++ b/crates/vm/src/stdlib/_ast/constant.rs @@ -2,6 +2,7 @@ use super::*; use crate::builtins::{PyComplex, PyFrozenSet, PyTuple}; use ast::str_prefix::StringLiteralPrefix; use rustpython_codegen::compile::ruff_int_to_bigint; +use rustpython_common::wtf8::Wtf8Buf; use rustpython_compiler_core::{SourceFile, bytecode::ConstantData}; #[derive(Debug)] @@ -14,7 +15,7 @@ pub(super) struct Constant { impl Constant { pub(super) fn new_str( - value: impl Into>, + value: impl Into, prefix: StringLiteralPrefix, range: TextRange, ) -> Self { @@ -112,7 +113,7 @@ pub(crate) enum ConstantLiteral { None, Bool(bool), Str { - value: Box, + value: Wtf8Buf, prefix: StringLiteralPrefix, }, Bytes(Box<[u8]>), @@ -199,7 +200,7 @@ fn constant_literal_to_constant_data(value: &ConstantLiteral) -> ConstantData { ConstantLiteral::None => ConstantData::None, ConstantLiteral::Bool(value) => ConstantData::Boolean { value: *value }, ConstantLiteral::Str { value, .. } => ConstantData::Str { - value: value.as_ref().into(), + value: value.clone(), }, ConstantLiteral::Bytes(value) => ConstantData::Bytes { value: value.to_vec(), @@ -548,7 +549,11 @@ impl Node for ConstantLiteral { }) } else if cls.is(vm.ctx.types.str_type) { Self::Str { - value: value_object.try_to_value::(vm)?.into(), + value: value_object + .downcast_ref::() + .expect("AST value field was checked to be a str") + .as_wtf8() + .to_owned(), prefix: StringLiteralPrefix::Empty, } } else if cls.is(vm.ctx.types.bytes_type) { @@ -650,7 +655,8 @@ pub(super) fn string_literal_to_object( .iter() .next() .map_or(StringLiteralPrefix::Empty, |part| part.flags.prefix()); - let c = Constant::new_str(value.to_str(), prefix, range); + let value = rustpython_codegen::string_literal_value(source_file, &value); + let c = Constant::new_str(value, prefix, range); c.ast_to_object(vm, source_file) } diff --git a/crates/vm/src/stdlib/_ast/expression.rs b/crates/vm/src/stdlib/_ast/expression.rs index 10bdf526684..97a3519ea2e 100644 --- a/crates/vm/src/stdlib/_ast/expression.rs +++ b/crates/vm/src/stdlib/_ast/expression.rs @@ -918,18 +918,8 @@ impl Node for ast::ExprGenerator { elt, generators, range, - parenthesized, + parenthesized: _, } = self; - let range = if parenthesized { - range - } else { - TextRange::new( - range - .start() - .saturating_sub(ruff_text_size::TextSize::from(1)), - range.end() + ruff_text_size::TextSize::from(1), - ) - }; let node = NodeAst .into_ref_with_type(vm, pyast::NodeExprGeneratorExp::static_type().to_owned()) .unwrap(); diff --git a/crates/vm/src/stdlib/_ast/string.rs b/crates/vm/src/stdlib/_ast/string.rs index 7a3bb8799b9..2e44ce48fdc 100644 --- a/crates/vm/src/stdlib/_ast/string.rs +++ b/crates/vm/src/stdlib/_ast/string.rs @@ -2,6 +2,7 @@ use super::constant::{Constant, ConstantLiteral}; use super::*; use crate::warn; use ast::str_prefix::StringLiteralPrefix; +use rustpython_common::wtf8::Wtf8Buf; fn ruff_fstring_element_into_iter( mut fstring_element: ast::InterpolatedStringElements, @@ -18,48 +19,77 @@ fn ruff_fstring_element_into_iter( .into_iter() } -fn ruff_fstring_element_to_joined_str_part( +fn push_ruff_fstring_element( vm: &VirtualMachine, + source_file: &SourceFile, + flags: ast::AnyStringFlags, element: ast::InterpolatedStringElement, -) -> JoinedStrPart { + output: &mut Vec, +) { match element { - ast::InterpolatedStringElement::Literal(ast::InterpolatedStringLiteralElement { - range, - value, - node_index: _, - }) => JoinedStrPart::Constant(Constant::new_str( - value, - ast::str_prefix::StringLiteralPrefix::Empty, - range, - )), + ast::InterpolatedStringElement::Literal(literal) => { + output.push(JoinedStrPart::Constant(Constant::new_str( + rustpython_codegen::interpolated_string_literal_value(source_file, &literal, flags), + ast::str_prefix::StringLiteralPrefix::Empty, + literal.range, + ))); + } ast::InterpolatedStringElement::Interpolation(ast::InterpolatedElement { range, expression, - debug_text: _, // TODO: What is this? - conversion, + debug_text, + mut conversion, format_spec, node_index: _, runtime_str: _, runtime_interpolation_format_spec: _, runtime_formatted_value_format_spec, }) => { + if let Some(debug_text) = &debug_text { + output.push(JoinedStrPart::Constant(interpolation_debug_constant( + source_file, + debug_text, + expression.range(), + ))); + conversion = debug_conversion(conversion, format_spec.is_some()); + } let runtime_format_spec = runtime_formatted_value_format_spec.or_else(|| { - ruff_format_spec_to_joined_str(vm, format_spec) + ruff_format_spec_to_joined_str(vm, source_file, flags, format_spec) .map(|joined_str| Box::new(joined_str.into_expr(false))) }); - JoinedStrPart::FormattedValue(FormattedValue { + output.push(JoinedStrPart::FormattedValue(FormattedValue { value: expression, conversion, format_spec: runtime_format_spec, range, - }) + })); } } } +/// The literal an `{expr=}` interpolation puts in front of its value. +fn interpolation_debug_constant( + source_file: &SourceFile, + debug_text: &ast::DebugText, + expression_range: TextRange, +) -> Constant { + let (text, range) = + rustpython_codegen::interpolation_debug_text(source_file, debug_text, expression_range); + Constant::new_str(text, ast::str_prefix::StringLiteralPrefix::Empty, range) +} + +/// A `{expr=}` interpolation takes `repr` unless it was told otherwise. +fn debug_conversion(conversion: ast::ConversionFlag, has_format_spec: bool) -> ast::ConversionFlag { + if matches!(conversion, ast::ConversionFlag::None) && !has_format_spec { + ast::ConversionFlag::Repr + } else { + conversion + } +} + fn push_joined_str_literal( output: &mut Vec, - pending: &mut Option<(String, StringLiteralPrefix, TextRange)>, + pending: &mut Option<(Wtf8Buf, StringLiteralPrefix, TextRange)>, ) { if let Some((value, prefix, range)) = pending.take() && !value.is_empty() @@ -72,7 +102,7 @@ fn push_joined_str_literal( fn normalize_joined_str_parts(values: Vec) -> Vec { let mut output = Vec::with_capacity(values.len()); - let mut pending: Option<(String, StringLiteralPrefix, TextRange)> = None; + let mut pending: Option<(Wtf8Buf, StringLiteralPrefix, TextRange)> = None; for part in values { match part { @@ -82,9 +112,10 @@ fn normalize_joined_str_parts(values: Vec) -> Vec output.push(JoinedStrPart::Constant(constant)); continue; }; - let value: String = value.into(); - if let Some((pending_value, _, _)) = pending.as_mut() { - pending_value.push_str(&value); + if let Some((pending_value, _, pending_range)) = pending.as_mut() { + pending_value.push_wtf8(&value); + // Folded literals span from the first of them to the last. + *pending_range = TextRange::new(pending_range.start(), constant.range.end()); } else { pending = Some((value, prefix, constant.range)); } @@ -102,7 +133,7 @@ fn normalize_joined_str_parts(values: Vec) -> Vec fn push_template_str_literal( output: &mut Vec, - pending: &mut Option<(String, StringLiteralPrefix, TextRange)>, + pending: &mut Option<(Wtf8Buf, StringLiteralPrefix, TextRange)>, ) { if let Some((value, prefix, range)) = pending.take() && !value.is_empty() @@ -115,7 +146,7 @@ fn push_template_str_literal( fn normalize_template_str_parts(values: Vec) -> Vec { let mut output = Vec::with_capacity(values.len()); - let mut pending: Option<(String, StringLiteralPrefix, TextRange)> = None; + let mut pending: Option<(Wtf8Buf, StringLiteralPrefix, TextRange)> = None; for part in values { match part { @@ -125,9 +156,10 @@ fn normalize_template_str_parts(values: Vec) -> Vec>, ) -> Option> { match format_spec { @@ -256,7 +290,15 @@ fn ruff_format_spec_to_joined_str( elements, node_index: _, } = *format_spec; - let range = if range.start() > ruff_text_size::TextSize::from(0) { + // The `:` that opens a format spec belongs to its range, and the + // parser leaves it out of the outermost one. + let opened_by_colon = source_file + .source_text() + .as_bytes() + .get(..range.start().to_usize()) + .and_then(<[u8]>::last) + == Some(&b':'); + let range = if opened_by_colon { TextRange::new( range.start() - ruff_text_size::TextSize::from(1), range.end(), @@ -264,9 +306,10 @@ fn ruff_format_spec_to_joined_str( } else { range }; - let values: Vec<_> = ruff_fstring_element_into_iter(elements) - .map(|element| ruff_fstring_element_to_joined_str_part(vm, element)) - .collect(); + let mut values = Vec::new(); + for element in ruff_fstring_element_into_iter(elements) { + push_ruff_fstring_element(vm, source_file, flags, element, &mut values); + } let values = normalize_joined_str_parts(values).into_boxed_slice(); Some(Box::new(JoinedStr { range, @@ -480,7 +523,7 @@ fn joined_str_part_to_ruff_fstring_element( ast::InterpolatedStringLiteralElement { node_index: Default::default(), range, - value, + value: value.to_string_lossy().into(), }, )) } @@ -685,26 +728,21 @@ pub(super) fn fstring_to_object( for i in 0..value.as_slice().len() { let part = core::mem::replace(value.iter_mut().nth(i).unwrap(), default_part.clone()); match part { - ast::FStringPart::Literal(ast::StringLiteral { - range, - value, - flags, - node_index: _, - }) => { + ast::FStringPart::Literal(literal) => { values.push(JoinedStrPart::Constant(Constant::new_str( - value, - flags.prefix(), - range, + rustpython_codegen::string_literal_part_value(source_file, &literal), + literal.flags.prefix(), + literal.range, ))); } ast::FStringPart::FString(ast::FString { range: _, elements, - flags: _, + flags, node_index: _, }) => { for element in ruff_fstring_element_into_iter(elements) { - values.push(ruff_fstring_element_to_joined_str_part(vm, element)); + push_ruff_fstring_element(vm, source_file, flags.into(), element, &mut values); } } } @@ -727,26 +765,26 @@ pub(super) fn fstring_to_object( // ===== TString (Template String) Support ===== -fn ruff_tstring_element_to_template_str_part( +fn push_ruff_tstring_element( vm: &VirtualMachine, source_file: &SourceFile, + flags: ast::AnyStringFlags, element: ast::InterpolatedStringElement, -) -> TemplateStrPart { + output: &mut Vec, +) { match element { - ast::InterpolatedStringElement::Literal(ast::InterpolatedStringLiteralElement { - range, - value, - node_index: _, - }) => TemplateStrPart::Constant(Constant::new_str( - value, - ast::str_prefix::StringLiteralPrefix::Empty, - range, - )), + ast::InterpolatedStringElement::Literal(literal) => { + output.push(TemplateStrPart::Constant(Constant::new_str( + rustpython_codegen::interpolated_string_literal_value(source_file, &literal, flags), + ast::str_prefix::StringLiteralPrefix::Empty, + literal.range, + ))); + } ast::InterpolatedStringElement::Interpolation(ast::InterpolatedElement { range, expression, debug_text, - conversion, + mut conversion, format_spec, node_index: _, runtime_str, @@ -756,7 +794,13 @@ fn ruff_tstring_element_to_template_str_part( let expr_range = extend_expr_range_with_wrapping_parens(source_file, range, expression.range()) .unwrap_or_else(|| expression.range()); - let expr_str = if let Some(debug_text) = debug_text { + let expr_str = if let Some(debug_text) = &debug_text { + output.push(TemplateStrPart::Constant(interpolation_debug_constant( + source_file, + debug_text, + expression.range(), + ))); + conversion = debug_conversion(conversion, format_spec.is_some()); let expr_source = source_file.slice(expr_range); let mut expr_with_debug = String::with_capacity( debug_text.leading.len() + expr_source.len() + debug_text.trailing.len(), @@ -773,7 +817,7 @@ fn ruff_tstring_element_to_template_str_part( runtime_str, runtime_interpolation_format_spec, ); - TemplateStrPart::Interpolation(TStringInterpolation { + output.push(TemplateStrPart::Interpolation(TStringInterpolation { value: expression, str: runtime_interpolation .as_ref() @@ -782,11 +826,11 @@ fn ruff_tstring_element_to_template_str_part( format_spec: runtime_interpolation .and_then(|(_, format_spec)| format_spec) .or_else(|| { - ruff_format_spec_to_joined_str(vm, format_spec) + ruff_format_spec_to_joined_str(vm, source_file, flags, format_spec) .map(|joined_str| Box::new(joined_str.into_expr(false))) }), range, - }) + })); } } } @@ -957,7 +1001,7 @@ fn template_part_to_element( ast::InterpolatedStringLiteralElement { range: constant.range, node_index: Default::default(), - value, + value: value.to_string_lossy().into(), }, )) } @@ -1200,12 +1244,9 @@ pub(super) fn tstring_to_object( let mut values = Vec::new(); for i in 0..value.as_slice().len() { let tstring = core::mem::replace(value.iter_mut().nth(i).unwrap(), default_tstring.clone()); + let flags = tstring.flags.into(); for element in ruff_fstring_element_into_iter(tstring.elements) { - values.push(ruff_tstring_element_to_template_str_part( - vm, - source_file, - element, - )); + push_ruff_tstring_element(vm, source_file, flags, element, &mut values); } } let values = normalize_template_str_parts(values); @@ -1239,8 +1280,13 @@ fn standalone_tstring_interpolation_to_object( str, conversion: interp.conversion, format_spec: format_spec.or_else(|| { - ruff_format_spec_to_joined_str(vm, interp.format_spec.clone()) - .map(|joined_str| Box::new(joined_str.into_expr(false))) + ruff_format_spec_to_joined_str( + vm, + source_file, + ast::TStringFlags::empty().into(), + interp.format_spec.clone(), + ) + .map(|joined_str| Box::new(joined_str.into_expr(false))) }), range: interp.range, }; diff --git a/crates/vm/src/stdlib/_ast/validate.rs b/crates/vm/src/stdlib/_ast/validate.rs index e936c9d3fb7..b4dd4a76d10 100644 --- a/crates/vm/src/stdlib/_ast/validate.rs +++ b/crates/vm/src/stdlib/_ast/validate.rs @@ -19,6 +19,7 @@ fn invalid_syntax_error(vm: &VirtualMachine) -> crate::builtins::PyBaseException vm.new_syntax_error( &CompileError::Codegen(CodegenError { location: None, + end_location: None, error: CodegenErrorType::SyntaxError("invalid syntax".to_owned()), source_path: "".to_owned(), }), diff --git a/crates/vm/src/stdlib/_collections.rs b/crates/vm/src/stdlib/_collections.rs index b48c0e670ac..3783d6fff9b 100644 --- a/crates/vm/src/stdlib/_collections.rs +++ b/crates/vm/src/stdlib/_collections.rs @@ -8,6 +8,7 @@ mod _collections { builtins::{ IterStatus::{Active, Exhausted}, PositionIterInternal, PyDict, PyGenericAlias, PyInt, PyStr, PyType, PyTypeRef, + locked_step, }, common::lock::{PyMutex, PyRwLock, PyRwLockReadGuard, PyRwLockWriteGuard}, convert::ToPyObject, @@ -76,6 +77,10 @@ mod _collections { fn borrow_deque_mut(&self) -> PyRwLockWriteGuard<'_, VecDeque> { self.deque.write() } + + fn is_over_maxlen(&self, deque: &VecDeque) -> bool { + self.maxlen.is_some_and(|maxlen| deque.len() > maxlen) + } } #[pyclass( @@ -95,20 +100,22 @@ mod _collections { fn append(&self, obj: PyObjectRef) { self.state.fetch_add(1); let mut deque = self.borrow_deque_mut(); - if self.maxlen == Some(deque.len()) { + deque.push_back(obj); + // Trim after pushing, so that a `maxlen` of zero drops what just + // arrived instead of popping from an empty deque and keeping it. + if self.is_over_maxlen(&deque) { deque.pop_front(); } - deque.push_back(obj); } #[pymethod] fn appendleft(&self, obj: PyObjectRef) { self.state.fetch_add(1); let mut deque = self.borrow_deque_mut(); - if self.maxlen == Some(deque.len()) { + deque.push_front(obj); + if self.is_over_maxlen(&deque) { deque.pop_back(); } - deque.push_front(obj); } #[pymethod] @@ -277,6 +284,7 @@ mod _collections { fn __reversed__(zelf: PyRef) -> PyReverseDequeIterator { PyReverseDequeIterator { state: zelf.state.load(), + counter: AtomicCell::new(zelf.__len__()), internal: PyMutex::new(PositionIterInternal::new(zelf, 0)), } } @@ -632,6 +640,11 @@ mod _collections { #[derive(Debug, PyPayload)] struct PyDequeIterator { state: usize, + /// How many elements are left to walk, `dequeiterobject.counter`. Kept + /// beside the deque rather than read back from it, because a mutated + /// deque is walked no further and what is left of it then reads as + /// nothing. + counter: AtomicCell, internal: PyMutex>, } @@ -656,6 +669,8 @@ mod _collections { if let OptionalArg::Present(index) = index { let index = max(index, 0) as usize; iter.internal.lock().position = index; + iter.counter + .store(iter.counter.load().saturating_sub(index)); } Ok(iter) } @@ -666,13 +681,14 @@ mod _collections { pub(crate) fn new(deque: PyDequeRef) -> Self { Self { state: deque.state.load(), + counter: AtomicCell::new(deque.__len__()), internal: PyMutex::new(PositionIterInternal::new(deque, 0)), } } #[pymethod] fn __length_hint__(&self) -> usize { - self.internal.lock().length_hint(|obj| obj.__len__()) + self.counter.load() } #[pymethod] @@ -693,16 +709,62 @@ mod _collections { } impl SelfIter for PyDequeIterator {} + + /// Whether the deque moved under an iterator that captured `state`. What is + /// left to walk is emptied before the error goes out, the way + /// `deque_iternext()` zeroes its counter before it raises. + fn deque_moved( + internal: &PositionIterInternal, + state: usize, + counter: &AtomicCell, + ) -> bool { + let Active(deque) = &internal.status else { + return false; + }; + if state == deque.state.load() { + return false; + } + counter.store(0); + true + } + + /// Hand back the element at the position the iterator keeps, `at` reaching + /// for it. Both deque iterators end here; they differ in whether they look + /// at the deque or at the count first. + fn deque_take( + internal: &mut PositionIterInternal, + counter: &AtomicCell, + at: impl FnOnce(&VecDeque, usize) -> Option, + ) -> (PyResult, Option) { + let item = match &internal.status { + Active(deque) if counter.load() != 0 => at(&deque.borrow_deque(), internal.position), + _ => None, + }; + let Some(item) = item else { + counter.store(0); + return (Ok(PyIterReturn::StopIteration(None)), internal.exhaust()); + }; + internal.position += 1; + counter.store(counter.load() - 1); + (Ok(PyIterReturn::Return(item)), None) + } + + fn deque_mutated(vm: &VirtualMachine) -> PyResult { + Err(vm.new_runtime_error("deque mutated during iteration")) + } + impl IterNext for PyDequeIterator { fn next(zelf: &Py, vm: &VirtualMachine) -> PyResult { - zelf.internal.lock().next(|deque, pos| { - if zelf.state != deque.state.load() { - return Err(vm.new_runtime_error("Deque mutated during iteration")); + locked_step(&zelf.internal, |internal| { + // The deque before the count, as in `deque_iternext()`, so an + // iterator still holding a deque that moved raises again on + // every call rather than running out after the first. + if deque_moved(internal, zelf.state, &zelf.counter) { + return (deque_mutated(vm), None); } - let deque = deque.borrow_deque(); - Ok(PyIterReturn::from_result( - deque.get(pos).cloned().ok_or(None), - )) + deque_take(internal, &zelf.counter, |deque, pos| { + deque.get(pos).cloned() + }) }) } } @@ -712,6 +774,8 @@ mod _collections { #[derive(Debug, PyPayload)] struct PyReverseDequeIterator { state: usize, + /// As in [`PyDequeIterator`]. + counter: AtomicCell, // position is counting from the tail internal: PyMutex>, } @@ -728,6 +792,8 @@ mod _collections { if let OptionalArg::Present(index) = index { let index = max(index, 0) as usize; iter.internal.lock().position = index; + iter.counter + .store(iter.counter.load().saturating_sub(index)); } Ok(iter) } @@ -737,7 +803,7 @@ mod _collections { impl PyReverseDequeIterator { #[pymethod] fn __length_hint__(&self) -> usize { - self.internal.lock().length_hint(|obj| obj.__len__()) + self.counter.load() } #[pymethod] @@ -761,17 +827,19 @@ mod _collections { impl IterNext for PyReverseDequeIterator { fn next(zelf: &Py, vm: &VirtualMachine) -> PyResult { - zelf.internal.lock().next(|deque, pos| { - if deque.state.load() != zelf.state { - return Err(vm.new_runtime_error("Deque mutated during iteration")); + locked_step(&zelf.internal, |internal| { + // The count before the deque, as in `dequereviter_next()`, so + // an iterator that has raised once runs out instead. + if zelf.counter.load() != 0 && deque_moved(internal, zelf.state, &zelf.counter) { + return (deque_mutated(vm), None); } - let deque = deque.borrow_deque(); - let r = deque - .len() - .checked_sub(pos + 1) - .and_then(|pos| deque.get(pos)) - .cloned(); - Ok(PyIterReturn::from_result(r.ok_or(None))) + deque_take(internal, &zelf.counter, |deque, pos| { + deque + .len() + .checked_sub(pos + 1) + .and_then(|pos| deque.get(pos)) + .cloned() + }) }) } } diff --git a/crates/vm/src/stdlib/_ctypes/array.rs b/crates/vm/src/stdlib/_ctypes/array.rs index d4674f33b07..965f7257e60 100644 --- a/crates/vm/src/stdlib/_ctypes/array.rs +++ b/crates/vm/src/stdlib/_ctypes/array.rs @@ -429,7 +429,7 @@ impl Constructor for PyCArray { } // Create array with zero-initialized buffer - let buffer = vec![0u8; total_size]; + let buffer = vm.new_zeroed_bytes(total_size)?; let instance = Self(PyCData::from_bytes_with_length(buffer, None, length)) .into_ref_with_type(vm, cls)?; diff --git a/crates/vm/src/stdlib/_functools.rs b/crates/vm/src/stdlib/_functools.rs index 944a2e8abdb..2c16632dc95 100644 --- a/crates/vm/src/stdlib/_functools.rs +++ b/crates/vm/src/stdlib/_functools.rs @@ -32,7 +32,7 @@ mod _functools { iterator, initial, } = args; - let mut iter = iterator.iter_without_hint(vm)?; + let mut iter = iterator.iter(vm)?; // OptionalOption distinguishes between: // - Missing: no argument provided → use first element from iterator // - Present(None): explicitly passed None → use None as initial value diff --git a/crates/vm/src/stdlib/_io.rs b/crates/vm/src/stdlib/_io.rs index 5479c47abc4..08dd0e0ef80 100644 --- a/crates/vm/src/stdlib/_io.rs +++ b/crates/vm/src/stdlib/_io.rs @@ -113,10 +113,6 @@ impl std::os::fd::AsRawFd for Fildes { } #[pymodule] -#[expect( - clippy::std_instead_of_core, - reason = "false positive: core::io items (Cursor, etc.) are unstable (core_io)" -)] mod _io { use super::*; use crate::{ @@ -647,8 +643,7 @@ mod _io { #[pymethod] fn read(instance: PyObjectRef, size: OptionalSize, vm: &VirtualMachine) -> PyResult { if let Some(size) = size.to_usize() { - // FIXME: unnecessary zero-init - let b = PyByteArray::from(vec![0; size]).into_ref(&vm.ctx); + let b = PyByteArray::from(vm.new_zeroed_bytes(size)?).into_ref(&vm.ctx); let n = >::try_from_object( vm, vm.call_method(&instance, "readinto", (b.clone(),))?, diff --git a/crates/vm/src/stdlib/_operator.rs b/crates/vm/src/stdlib/_operator.rs index 5e72ef03eb4..aac528c52aa 100644 --- a/crates/vm/src/stdlib/_operator.rs +++ b/crates/vm/src/stdlib/_operator.rs @@ -178,7 +178,7 @@ mod _operator { #[pyfunction(name = "countOf")] fn count_of(a: PyIter, b: PyObjectRef, vm: &VirtualMachine) -> PyResult { let mut count: usize = 0; - for element in a.iter_without_hint::(vm)? { + for element in a.iter::(vm)? { let element = element?; if element.is(&b) || vm.bool_eq(&b, &element)? { count += 1; @@ -199,7 +199,7 @@ mod _operator { #[pyfunction(name = "indexOf")] fn index_of(a: PyIter, b: PyObjectRef, vm: &VirtualMachine) -> PyResult { - for (index, element) in a.iter_without_hint::(vm)?.enumerate() { + for (index, element) in a.iter::(vm)?.enumerate() { let element = element?; if element.is(&b) || vm.bool_eq(&b, &element)? { return Ok(index); diff --git a/crates/vm/src/stdlib/_signal.rs b/crates/vm/src/stdlib/_signal.rs index 5abfd327553..5f5010812cb 100644 --- a/crates/vm/src/stdlib/_signal.rs +++ b/crates/vm/src/stdlib/_signal.rs @@ -337,10 +337,6 @@ pub(crate) mod _signal { } #[cfg(windows)] - #[expect( - clippy::std_instead_of_core, - reason = "false positive: core::io::ErrorKind is unstable (core_io)" - )] let is_socket = if fd != INVALID_WAKEUP { host_signal::wakeup_fd_is_socket(fd).map_err(|err| { if err.kind() == std::io::ErrorKind::InvalidInput { diff --git a/crates/vm/src/stdlib/_sre.rs b/crates/vm/src/stdlib/_sre.rs index a9f98ca7015..4575901d3e8 100644 --- a/crates/vm/src/stdlib/_sre.rs +++ b/crates/vm/src/stdlib/_sre.rs @@ -452,15 +452,25 @@ mod _sre { let mut match_list: Vec = Vec::new(); let mut iter = SearchIter { req, state }; + // What a group that took no part in the match is reported as. + // `findall` hands back the matched text rather than a match + // object, so the stand-in has to be an empty value of the type + // the pattern works on. `Match.groups` still reports `None` and + // is not affected by this. + let empty: PyObjectRef = if zelf.isbytes { + vm.ctx.new_bytes(vec![]).into() + } else { + vm.ctx.new_str(ascii!("")).into() + }; + while iter.next().is_some() { let m = Match::new(&mut iter.state, zelf.clone(), string_args.string.clone()); let item = if zelf.groups == 0 || zelf.groups == 1 { m.get_slice(zelf.groups, s, vm) - .unwrap_or_else(|| vm.ctx.none()) + .unwrap_or_else(|| empty.clone()) } else { - m.groups(OptionalArg::Present(vm.ctx.new_str(ascii!("")).into()), vm)? - .into() + m.groups(OptionalArg::Present(empty.clone()), vm)?.into() }; match_list.push(item); diff --git a/crates/vm/src/stdlib/_symtable.rs b/crates/vm/src/stdlib/_symtable.rs index eb0ecaa87d7..f772da62146 100644 --- a/crates/vm/src/stdlib/_symtable.rs +++ b/crates/vm/src/stdlib/_symtable.rs @@ -3,9 +3,10 @@ pub(crate) use _symtable::module_def; #[pymodule] mod _symtable { use crate::{ - Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, - builtins::{PyDictRef, PyUtf8StrRef}, + AsObject, Py, PyPayload, PyRef, PyResult, VirtualMachine, + builtins::{PyBaseExceptionRef, PyDictRef, PyListRef, PyStrRef, PyUtf8StrRef}, compiler, + function::{ArgStrOrBytesLike, FsPath}, types::Representable, }; use alloc::fmt; @@ -97,8 +98,8 @@ mod _symtable { #[pyfunction] fn symtable( - source: PyUtf8StrRef, - filename: PyUtf8StrRef, + source: ArgStrOrBytesLike, + filename: FsPath, mode: PyUtf8StrRef, vm: &VirtualMachine, ) -> PyResult> { @@ -107,15 +108,97 @@ mod _symtable { .parse::() .map_err(|err| vm.new_value_error(err.to_string()))?; - let symtable = compiler::compile_symtable(source.as_str(), mode, filename.as_str()) - .map_err(|err| vm.new_syntax_error(&err, Some(source.as_str())))?; + let filename_obj = match &filename { + FsPath::Str(filename) => filename.clone(), + FsPath::Bytes(filename) => { + let filename = FsPath::bytes_as_os_str(filename.as_bytes(), vm)?.to_owned(); + vm.fsdecode(filename) + } + }; + let filename = filename_obj.to_string_lossy(); + let source = match &source { + ArgStrOrBytesLike::Str(source) => source.try_as_utf8(vm)?.as_str().to_owned(), + ArgStrOrBytesLike::Buf(source) => vm + .decode_source_bytes(&source.borrow_buf(), &filename, false) + .map_err(|err| set_syntax_error_filename(err, &filename_obj, vm))?, + }; + if source.as_bytes().contains(&0) { + return Err(vm.new_exception_msg( + vm.ctx.exceptions.syntax_error.to_owned(), + "source code string cannot contain null bytes".into(), + )); + } + let symtable = compiler::compile_symtable(&source, mode, &filename).map_err(|err| { + let err = vm.new_syntax_error(&err, Some(&source)); + set_syntax_error_filename(err, &filename_obj, vm) + })?; + + Ok(to_py_symbol_table(symtable, vm)) + } + + fn set_syntax_error_filename( + err: PyBaseExceptionRef, + filename: &PyStrRef, + vm: &VirtualMachine, + ) -> PyBaseExceptionRef { + if err.fast_isinstance(vm.ctx.exceptions.syntax_error) { + err.as_object() + .set_attr("filename", filename.clone(), vm) + .unwrap(); + } + err + } - let py_symbol_table = to_py_symbol_table(symtable); - Ok(py_symbol_table.into_ref(&vm.ctx)) + fn append_visible_child(table: SymbolTable, children: &mut Vec) { + if table.comp_inlined { + for child in table.sub_tables { + append_visible_child(child, children); + } + } else { + children.push(table); + } } - const fn to_py_symbol_table(symtable: SymbolTable) -> PySymbolTable { - PySymbolTable { symtable } + fn to_py_symbol_table(mut symtable: SymbolTable, vm: &VirtualMachine) -> PyRef { + let mut child_tables = Vec::new(); + for table in core::mem::take(&mut symtable.sub_tables) { + append_visible_child(table, &mut child_tables); + } + if !symtable.future_annotations + && let Some(annotation_block) = symtable.annotation_block.take() + { + child_tables.push(*annotation_block); + } + child_tables.sort_by_key(|table| table.block_index); + + let children = vm.ctx.new_list( + child_tables + .into_iter() + .map(|table| to_py_symbol_table(table, vm).into()) + .collect(), + ); + let symbols = vm.ctx.new_dict(); + for (name, symbol) in &symtable.symbols { + let packed_flags = + i32::from(symbol.flags.bits()) | (symbol.scope.as_i32() << SCOPE_OFFSET); + symbols + .set_item(name.as_str(), vm.new_pyobj(packed_flags), vm) + .unwrap(); + } + let varnames = vm.ctx.new_list( + symtable + .varnames + .iter() + .map(|name| vm.ctx.new_str(name.as_str()).into()) + .collect(), + ); + PySymbolTable { + symtable, + children, + symbols, + varnames, + } + .into_ref(&vm.ctx) } #[pyattr] @@ -123,6 +206,9 @@ mod _symtable { #[derive(PyPayload)] struct PySymbolTable { symtable: SymbolTable, + children: PyListRef, + symbols: PyDictRef, + varnames: PyListRef, } impl fmt::Debug for PySymbolTable { @@ -135,7 +221,7 @@ mod _symtable { impl PySymbolTable { #[pygetset] fn name(&self) -> String { - self.symtable.name.clone() + self.symtable.name.to_string() } #[pygetset(name = "type")] @@ -160,20 +246,8 @@ mod _symtable { } #[pygetset] - fn children(&self, vm: &VirtualMachine) -> Vec { - self.symtable - .sub_tables - .iter() - .flat_map(|t| { - if t.comp_inlined { - // Flatten: replace inlined comprehension tables with their children - t.sub_tables.iter().collect::>() - } else { - vec![t] - } - }) - .map(|t| to_py_symbol_table(t.clone()).into_pyobject(vm)) - .collect() + fn children(&self) -> PyListRef { + self.children.clone() } #[pygetset] @@ -182,14 +256,13 @@ mod _symtable { } #[pygetset] - fn symbols(&self, vm: &VirtualMachine) -> PyDictRef { - let dict = vm.ctx.new_dict(); - for (name, symbol) in &self.symtable.symbols { - let packed_flags = - i32::from(symbol.flags.bits()) | (symbol.scope.as_i32() << SCOPE_OFFSET); - dict.set_item(name, vm.new_pyobj(packed_flags), vm).unwrap(); - } - dict + fn symbols(&self) -> PyDictRef { + self.symbols.clone() + } + + #[pygetset] + fn varnames(&self) -> PyListRef { + self.varnames.clone() } #[pygetset] diff --git a/crates/vm/src/stdlib/_thread.rs b/crates/vm/src/stdlib/_thread.rs index 79dce3d21ce..45b92ff97e7 100644 --- a/crates/vm/src/stdlib/_thread.rs +++ b/crates/vm/src/stdlib/_thread.rs @@ -547,7 +547,12 @@ pub(crate) mod _thread { let args = FuncArgs::new( args.to_vec(), kwargs - .map_or_else(Default::default, |k| k.to_attributes(vm)) + .map_or_else( + || Ok(Default::default()), + |k| { + k.to_attributes(vm, |vm| Err(vm.new_type_error("keywords must be strings"))) + }, + )? .into_iter() .map(|(k, v)| (k.as_str().to_owned(), v)) .collect::(), @@ -616,25 +621,32 @@ pub(crate) mod _thread { const DEFAULT_THREAD_STACK_SIZE: usize = 8 * 1024 * 1024; /// Configure a `thread::Builder` with the stack size to use for a new - /// Python thread. Uses the value set via `threading.stack_size(N)` when - /// the user has provided one (non-zero). Otherwise, debug builds fall - /// back to [`DEFAULT_THREAD_STACK_SIZE`] and release builds leave the - /// builder unmodified (Rust's std default applies). + /// Python thread. Release builds use the value set via + /// `threading.stack_size(N)` when the user has provided one (non-zero) and + /// otherwise leave the builder unmodified (Rust's std default applies). + /// + /// Debug builds take [`DEFAULT_THREAD_STACK_SIZE`] as a floor rather than + /// only as a default: an unoptimized `ExecutingFrame::run` reserves around + /// eighty kilobytes of stack where an optimized one reserves under a + /// thousand, so a size that holds a Python call chain in release holds + /// three of its frames here — starting a thread at all needs six. The + /// value `threading.stack_size()` reports is untouched. fn apply_thread_stack_size( thread_builder: thread::Builder, vm: &VirtualMachine, ) -> thread::Builder { let configured = vm.state.stacksize.load(); - if configured != 0 { - return thread_builder.stack_size(configured); - } #[cfg(debug_assertions)] { - thread_builder.stack_size(DEFAULT_THREAD_STACK_SIZE) + thread_builder.stack_size(configured.max(DEFAULT_THREAD_STACK_SIZE)) } #[cfg(not(debug_assertions))] { - thread_builder + if configured == 0 { + thread_builder + } else { + thread_builder.stack_size(configured) + } } } @@ -2029,6 +2041,31 @@ pub(crate) mod _thread { }); } + /// A size small enough for CPython's frames is not small enough for an + /// unoptimized build's: `test_threading` asks for 256 KiB, which holds + /// three of them where starting a thread needs six. The size the + /// request set is still what `threading.stack_size()` answers with. + #[test] + #[cfg(all(debug_assertions, any(target_os = "linux", target_os = "macos")))] + fn explicit_python_thread_stack_size_is_a_floor_debug() { + const REQUESTED: usize = 256 * 1024; + + Interpreter::without_stdlib(Default::default()).enter(|vm| { + vm.state.stacksize.store(REQUESTED); + let builder = apply_thread_stack_size(thread::Builder::new(), vm); + let stack_size = builder + .spawn(current_thread_stack_size) + .expect("failed to spawn thread") + .join() + .expect("thread panicked"); + assert!( + stack_size >= DEFAULT_THREAD_STACK_SIZE, + "Python thread stack size is {stack_size} bytes, expected at least {DEFAULT_THREAD_STACK_SIZE}" + ); + assert_eq!(vm.state.stacksize.load(), REQUESTED); + }); + } + #[cfg(all(debug_assertions, target_os = "linux"))] fn current_thread_stack_size() -> usize { use libc::{ diff --git a/crates/vm/src/stdlib/builtins.rs b/crates/vm/src/stdlib/builtins.rs index 34be8c6178d..75d84abfb70 100644 --- a/crates/vm/src/stdlib/builtins.rs +++ b/crates/vm/src/stdlib/builtins.rs @@ -32,7 +32,7 @@ mod builtins { types::PyComparisonOp, vm::compile_mode::{ CompilerFlags, PY_EVAL_INPUT, PY_FILE_INPUT, PY_FUNC_TYPE_INPUT, PY_SINGLE_INPUT, - compile_future_feature_mask, compile_future_features_from_flags, + compile_future_features_from_flags, }, }; use itertools::Itertools; @@ -130,9 +130,7 @@ mod builtins { ) -> bytecode::CodeFlags { let mut future_features = compile_future_features_from_flags(flags); if !dont_inherit && let Some(code) = crate::frame::current_code() { - future_features |= bytecode::CodeFlags::from_bits_truncate( - code.flags.bits() & compile_future_feature_mask().bits(), - ); + future_features |= code.flags & bytecode::CodeFlags::FUTURE_MASK; } future_features } @@ -653,9 +651,7 @@ mod builtins { let source = string.as_str(); let mut opts = vm.compile_opts(); if let Some(code) = crate::frame::current_code() { - opts.future_features = bytecode::CodeFlags::from_bits_truncate( - code.flags.bits() & compile_future_feature_mask().bits(), - ); + opts.future_features = code.flags & bytecode::CodeFlags::FUTURE_MASK; } vm.compile_with_opts(source, mode, "", opts) .map_err(|err| err.into_pyexception(vm, Some(source)))? @@ -1175,7 +1171,9 @@ mod builtins { #[pyfunction] fn sorted(iterable: PyObjectRef, opts: SortOptions, vm: &VirtualMachine) -> PyResult { - let items: Vec<_> = iterable.try_to_value(vm)?; + // `PySequence_List()`, so the room comes from what the iterable reports + // rather than from its iterator. + let items = vm.extract_elements_sized(&iterable, &|| 0, Ok)?; let lst = PyList::from(items); lst.sort(opts, vm)?; Ok(lst) diff --git a/crates/vm/src/stdlib/itertools.rs b/crates/vm/src/stdlib/itertools.rs index 6eb268d94c1..5f85f1b7238 100644 --- a/crates/vm/src/stdlib/itertools.rs +++ b/crates/vm/src/stdlib/itertools.rs @@ -1123,7 +1123,7 @@ mod decl { #[derive(FromArgs)] struct ProductArgs { #[pyarg(named, optional)] - repeat: OptionalArg, + repeat: OptionalArg, } impl Constructor for PyItertoolsProduct { @@ -1135,19 +1135,47 @@ mod decl { vm: &VirtualMachine, ) -> PyResult { let repeat = args.repeat.unwrap_or(1); - let mut pools = Vec::new(); + if repeat < 0 { + return Err(vm.new_value_error("repeat argument cannot be negative")); + } + let repeat = repeat as usize; + + // The count is settled before the arguments are read, the way + // `product_new()` settles it before it calls `PySequence_Tuple()` + // on any of them, so a repeat too large to serve does not run their + // code first. + let npools = iterables + .iter() + .len() + .checked_mul(repeat) + .filter(|n| *n <= isize::MAX as usize / size_of::()) + .ok_or_else(|| vm.new_overflow_error("repeat argument too large"))?; + + let mut single: Vec> = Vec::new(); for arg in iterables.iter() { - pools.push(arg.try_to_value(vm)?); + single.push(arg.try_to_value(vm)?); } - let pools = core::iter::repeat_n(pools, repeat) - .flatten() - .collect::>>(); + + let mut pools: Vec> = Vec::new(); + pools + .try_reserve_exact(npools) + .map_err(|_| vm.new_memory_error(""))?; + // Filled by index, the way `product_new()` fills a tuple of + // `npools`. Repeating the arguments `repeat` times instead walks + // that many steps even when there are no arguments to repeat, so + // `product(repeat=2**62)` would spin rather than answer `[()]`. + pools.extend((0..npools).map(|i| single[i % single.len()].clone())); + + let mut idxs = Vec::new(); + idxs.try_reserve_exact(npools) + .map_err(|_| vm.new_memory_error(""))?; + idxs.resize(npools, 0); let l = pools.len(); Ok(Self { pools, - idxs: PyRwLock::new(vec![0; l]), + idxs: PyRwLock::new(idxs), cur: AtomicCell::new(l.wrapping_sub(1)), stop: AtomicCell::new(false), }) diff --git a/crates/vm/src/stdlib/os.rs b/crates/vm/src/stdlib/os.rs index 668545a3cec..3e5e2393ee3 100644 --- a/crates/vm/src/stdlib/os.rs +++ b/crates/vm/src/stdlib/os.rs @@ -328,7 +328,7 @@ pub(super) mod _os { #[pyfunction] fn read(fd: crt_fd::Borrowed<'_>, n: usize, vm: &VirtualMachine) -> PyResult { - let mut buffer = vec![0u8; n]; + let mut buffer = vm.new_zeroed_bytes(n)?; loop { match vm.allow_threads(|| crt_fd::read(fd, &mut buffer)) { Ok(n) => { @@ -2135,7 +2135,7 @@ pub(crate) fn envobj_to_dict( } let keys = vm.call_method(obj, "keys", ())?; let dict = vm.ctx.new_dict(); - for key in keys.get_iter(vm)?.into_iter::(vm)? { + for key in keys.get_iter(vm)?.into_iter::(vm) { let key = key?; let val = obj.get_item(&*key, vm)?; dict.set_item(&*key, val, vm)?; diff --git a/crates/vm/src/stdlib/winsound.rs b/crates/vm/src/stdlib/winsound.rs index 75f576adf81..fbefa236c6a 100644 --- a/crates/vm/src/stdlib/winsound.rs +++ b/crates/vm/src/stdlib/winsound.rs @@ -6,9 +6,7 @@ pub(crate) use winsound::module_def; #[pymodule] mod winsound { use crate::builtins::{PyBaseExceptionRef, PyBytes, PyStr}; - use crate::convert::{IntoPyException, ToPyException, TryFromBorrowedObject}; - use crate::exceptions; - use crate::host_env::windows::ToWideString; + use crate::convert::{IntoPyException, ToPyException}; use crate::protocol::{BufferFlags, PyBuffer}; use crate::{AsObject, PyObjectRef, PyResult, VirtualMachine}; use rustpython_host_env::winsound::{PlaySoundError, PlaySoundSource, play_sound}; diff --git a/crates/vm/src/vm/compile.rs b/crates/vm/src/vm/compile.rs index 2beaf24f07c..1cc46adf4cc 100644 --- a/crates/vm/src/vm/compile.rs +++ b/crates/vm/src/vm/compile.rs @@ -191,7 +191,10 @@ impl VirtualMachine { filename: &str, ignore_cookie: bool, ) -> PyResult { - let has_bom = source.starts_with(b"\xef\xbb\xbf"); + // `ignore_cookie` marks source that was handed over as text. A byte + // order mark belongs to the byte encoding, so text keeps whatever it + // was written with and the parser rejects a stray U+FEFF. + let has_bom = !ignore_cookie && source.starts_with(b"\xef\xbb\xbf"); let encoding = if ignore_cookie { None } else { @@ -278,8 +281,6 @@ impl VirtualMachine { let is_ast_only = cf.contains(CompilerFlags::ONLY_AST); let optimized_ast = cf.contains(CompilerFlags::OPTIMIZED_AST); let future_features = compile_future_features_from_flags(flags); - let explicit_future_annotations = - future_features.contains(crate::bytecode::CodeFlags::FUTURE_ANNOTATIONS); let target_version = if is_ast_only { Some(ruff_python_ast::PythonVersion { major: 3, @@ -291,7 +292,7 @@ impl VirtualMachine { if is_ast_only { if start == PY_FUNC_TYPE_INPUT { - return _ast::parse_func_type(self, source, optimize, target_version) + return _ast::parse_func_type(self, source, filename, optimize, target_version) .map_err(|e| (e, Some(source), allow_incomplete).to_pyexception(self)); } let (parser_mode, interactive) = match start { @@ -307,13 +308,14 @@ impl VirtualMachine { let parsed = _ast::parse( self, source, + filename, parser_mode, optimize, target_version, type_comments, optimized_ast, interactive, - explicit_future_annotations, + future_features, dont_imply_dedent, ) .map_err(|e| (e, Some(source), allow_incomplete).to_pyexception(self))?; @@ -336,13 +338,14 @@ impl VirtualMachine { _ast::parse( self, source, + filename, parser_mode, optimize, None, type_comments, false, start == PY_SINGLE_INPUT, - explicit_future_annotations, + future_features, dont_imply_dedent, ) .map_err(|e| (e, Some(source), allow_incomplete).to_pyexception(self))?; @@ -409,6 +412,7 @@ impl VirtualMachine { // Recovered below via `escalated`, so this is never surfaced. compiler::codegen::error::CodegenError { location: Some(location), + end_location: None, error: compiler::codegen::error::CodegenErrorType::SyntaxError( String::new(), ), @@ -1116,6 +1120,58 @@ mod escape_warnings { }) } + #[test] + fn ast_only_compile_honors_barry_as_flufl() { + Interpreter::without_stdlib(Default::default()).enter(|vm| { + let flags = CompilerFlags::ONLY_AST.bits(); + vm.compile_string_object_with_flags( + b"from __future__ import barry_as_FLUFL\n2 <> 3\n", + "", + PY_FILE_INPUT, + flags, + -1, + -1, + ) + .expect("PyCF_ONLY_AST should accept <> in Barry mode"); + + let err = vm + .compile_string_object_with_flags( + b"from __future__ import barry_as_FLUFL\n2 != 3\n", + "", + PY_FILE_INPUT, + flags, + -1, + -1, + ) + .expect_err("PyCF_ONLY_AST should reject != in Barry mode"); + assert!( + err.as_object() + .str(vm) + .unwrap() + .as_wtf8() + .to_string() + .contains("with Barry as BDFL") + ); + }); + } + + #[test] + fn type_comment_preparse_honors_inherited_barry_as_flufl() { + Interpreter::without_stdlib(Default::default()).enter(|vm| { + let flags = CompilerFlags::TYPE_COMMENTS.bits() + | crate::bytecode::CodeFlags::FUTURE_BARRY_AS_BDFL.bits() as i32; + vm.compile_string_object_with_flags( + b"2 <> 3\n", + "", + PY_FILE_INPUT, + flags, + -1, + -1, + ) + .expect("type-comment preparse should accept <> in inherited Barry mode"); + }); + } + #[test] fn codegen_caller_warning_precedes_later_return_error() { let message = compile_error_message("(1)()\nreturn\n"); diff --git a/crates/vm/src/vm/compile_mode.rs b/crates/vm/src/vm/compile_mode.rs index 9885ba2e1f7..6da531bbc1f 100644 --- a/crates/vm/src/vm/compile_mode.rs +++ b/crates/vm/src/vm/compile_mode.rs @@ -67,17 +67,6 @@ pub(crate) const PY_CF_ALLOW_TOP_LEVEL_AWAIT: i32 = CompilerFlags::ALLOW_TOP_LEV pub(crate) const PY_CF_ALLOW_INCOMPLETE_INPUT: i32 = CompilerFlags::ALLOW_INCOMPLETE_INPUT.bits(); pub(crate) const PY_CF_OPTIMIZED_AST: i32 = CompilerFlags::OPTIMIZED_AST.bits(); -pub(crate) fn compile_future_feature_mask() -> bytecode::CodeFlags { - // RustPython accepts barry_as_FLUFL but leaves its parser mode disabled. - bytecode::CodeFlags::FUTURE_DIVISION - | bytecode::CodeFlags::FUTURE_ABSOLUTE_IMPORT - | bytecode::CodeFlags::FUTURE_WITH_STATEMENT - | bytecode::CodeFlags::FUTURE_PRINT_FUNCTION - | bytecode::CodeFlags::FUTURE_UNICODE_LITERALS - | bytecode::CodeFlags::FUTURE_GENERATOR_STOP - | bytecode::CodeFlags::FUTURE_ANNOTATIONS -} - pub(crate) fn compile_future_features_from_flags(flags: i32) -> bytecode::CodeFlags { - bytecode::CodeFlags::from_bits_truncate(flags as u32 & compile_future_feature_mask().bits()) + bytecode::CodeFlags::from_bits_truncate(flags as u32 & bytecode::CodeFlags::FUTURE_MASK.bits()) } diff --git a/crates/vm/src/vm/interpreter.rs b/crates/vm/src/vm/interpreter.rs index c538eb32ec8..6d4e1f75a22 100644 --- a/crates/vm/src/vm/interpreter.rs +++ b/crates/vm/src/vm/interpreter.rs @@ -1095,11 +1095,22 @@ mod tests { ); let (lock, ready) = &*state; - let mut state = lock.lock().unwrap(); - state.entered += 1; - ready.notify_all(); - while !state.release { - state = ready.wait(state).unwrap(); + { + let mut state = lock.lock().unwrap(); + state.entered += 1; + ready.notify_all(); + } + // Wait attached, but keep passing safepoints: a thread + // that blocks outright while attached never suspends, + // so a concurrent stop-the-world could not finish and + // the other worker could never attach. + loop { + vm.check_signals().unwrap(); + let state = lock.lock().unwrap(); + if state.release { + break; + } + let _ = ready.wait_timeout(state, Duration::from_millis(1)).unwrap(); } }); }) @@ -1165,6 +1176,11 @@ mod tests { let result = vm._add(&a, &b).unwrap(); assert_eq!(*int::get_value(&result), 42_i32.to_bigint().unwrap()); operations += 1; + // The protocol calls above never reach a safepoint on + // their own; a bytecode loop would. Without this, a + // concurrent stop-the-world could not finish while this + // thread stays attached. + vm.check_signals().unwrap(); std::thread::yield_now(); } (sub_finished_worker.load(Ordering::Acquire), operations) diff --git a/crates/vm/src/vm/mod.rs b/crates/vm/src/vm/mod.rs index 54d3e813eec..28e59a2f477 100644 --- a/crates/vm/src/vm/mod.rs +++ b/crates/vm/src/vm/mod.rs @@ -23,8 +23,8 @@ mod vm_ops; use crate::{ AsObject, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, builtins::{ - self, PyBaseExceptionRef, PyDict, PyDictRef, PyInt, PyList, PyModule, PyStr, PyStrInterned, - PyStrRef, PyTypeRef, PyUtf8Str, PyUtf8StrInterned, PyWeak, + self, PyBaseExceptionRef, PyBaseObject, PyDict, PyDictRef, PyInt, PyList, PyModule, PyStr, + PyStrInterned, PyStrRef, PyTypeRef, PyUtf8Str, PyUtf8StrInterned, PyWeak, code::PyCode, dict::{PyDictItems, PyDictKeys, PyDictValues}, pystr::AsPyStr, @@ -42,6 +42,7 @@ use crate::{ scope::Scope, signal::{self, SignalHandlers}, stdlib, + types::{GetattroFunc, fn_addr}, warn::WarningsState, }; use alloc::{borrow::Cow, collections::BTreeMap}; @@ -879,6 +880,19 @@ struct SuspendedFrame { is_entry: bool, } +/// Whether a sequence being built asks the iterable it was handed how much room +/// to take. `list_extend()` asks and reserves; `PySequence_Tuple()` and the +/// rest ask nothing at all. +#[derive(Clone, Copy)] +enum LengthHint<'a> { + /// Grows as the loop goes, the way `tuple()`, `set()`, `min()` and + /// `deque()` do, so an object slow to answer is never asked. + Unasked, + /// Reserves what the iterable answers, unless it leaves no room for the + /// count this returns. + Iterable(&'a dyn Fn() -> usize), +} + impl VirtualMachine { fn init_callable_cache(&mut self) -> PyResult<()> { self.callable_cache.len = Some(self.builtins.get_attr("len", self)?); @@ -2161,13 +2175,12 @@ impl VirtualMachine { ) -> PyResult { self.check_recursive_call("")?; - // Check the native C stack periodically. The sampling interval - // (every 8th call) balances overhead against the risk of missing - // an overflow between checks, especially when light and heavy - // frames alternate (each recursion step uses different native - // stack amounts). - let depth = self.recursion_depth.get(); - if depth & 7 == 0 && self.check_c_stack_overflow() { + // Every entry, not every eighth. The margin only has to cover what a + // single frame takes if the check runs each time; sampling asks it to + // cover eight, and a recursion whose steps re-enter through native + // code -- an `__add__` chain, a sort key that sorts -- takes more than + // the margin in that many. + if self.check_c_stack_overflow() { return Err(self.new_recursion_error(String::new())); } @@ -2261,11 +2274,7 @@ impl VirtualMachine { ) -> PyResult { self.check_recursive_call("")?; - let depth = self.recursion_depth.get(); - if depth & 7 == 0 && self.check_c_stack_overflow() { - return Err(self.new_recursion_error(String::new())); - } - + // The C stack is checked by `enter_iframe_unchecked` below. self.enter_iframe_unchecked(iframe) } @@ -2278,8 +2287,7 @@ impl VirtualMachine { &self, iframe: &mut crate::frame::InterpreterFrame, ) -> PyResult { - let depth = self.recursion_depth.get(); - if depth & 7 == 0 && self.check_c_stack_overflow() { + if self.check_c_stack_overflow() { return Err(self.new_recursion_error(String::new())); } @@ -2635,6 +2643,49 @@ impl VirtualMachine { where F: Fn(PyObjectRef) -> PyResult, { + self.extract_elements_inner(value, LengthHint::Unasked, func) + } + + /// [`Self::extract_elements_with`] for a caller that asks the iterable + /// itself how much room to take, the way `list_extend()` does. `held` + /// answers how many elements the caller already has, and is read after the + /// iterable has been asked, since asking runs its code. + pub fn extract_elements_sized( + &self, + value: &PyObject, + held: &dyn Fn() -> usize, + func: F, + ) -> PyResult> + where + F: Fn(PyObjectRef) -> PyResult, + { + self.extract_elements_inner(value, LengthHint::Iterable(held), func) + } + + fn extract_elements_inner( + &self, + value: &PyObject, + hint: LengthHint<'_>, + func: F, + ) -> PyResult> + where + F: Fn(PyObjectRef) -> PyResult, + { + // A count known up front is taken in one go. Collecting into a + // `Result` instead would drop it: the adapter that carries the error + // may stop early, so it reports no lower bound and the vector grows a + // step at a time. + fn map_known_len( + items: impl ExactSizeIterator, + func: impl Fn(T) -> PyResult, + ) -> PyResult> { + let mut results = Vec::with_capacity(items.len()); + for item in items { + results.push(func(item)?); + } + Ok(results) + } + // Type-specific fast paths corresponding to _list_extend() in CPython // Objects/listobject.c. Each branch takes an atomic snapshot to avoid // race conditions from concurrent mutation (no GIL). @@ -2644,9 +2695,11 @@ impl VirtualMachine { } else if cls.is(self.ctx.types.list_type) { // The list is re-read on every step, the way map_iterable_object() // does it: func() runs Python, which can mutate or even clear the - // same list, and a borrow held across that call deadlocks it. + // same list, and a borrow held across that call deadlocks it. Its + // length at the start is only how much room to take, not how far + // the loop runs. let list = value.downcast_ref::().unwrap(); - let mut results = Vec::new(); + let mut results = Vec::with_capacity(list.borrow_vec().len()); let mut i = 0; loop { let elem = { @@ -2663,34 +2716,58 @@ impl VirtualMachine { return Ok(results); } else if cls.is(self.ctx.types.dict_type) { let keys = value.downcast_ref::().unwrap().keys_vec(); - return keys.into_iter().map(func).collect(); + return map_known_len(keys.into_iter(), func); } else if cls.is(self.ctx.types.dict_keys_type) { let keys = value.downcast_ref::().unwrap().dict.keys_vec(); - return keys.into_iter().map(func).collect(); + return map_known_len(keys.into_iter(), func); } else if cls.is(self.ctx.types.dict_values_type) { let values = value .downcast_ref::() .unwrap() .dict .values_vec(); - return values.into_iter().map(func).collect(); + return map_known_len(values.into_iter(), func); } else if cls.is(self.ctx.types.dict_items_type) { let items = value .downcast_ref::() .unwrap() .dict .items_vec(); - return items - .into_iter() - .map(|(k, v)| func(self.ctx.new_tuple(vec![k, v]).into())) - .collect(); + return map_known_len(items.into_iter(), |(k, v)| { + func(self.ctx.new_tuple(vec![k, v]).into()) + }); } else { - return self.map_py_iter(value, func); + return self.map_py_iter(value, hint, func); }; - slice.iter().map(|obj| func(obj.clone())).collect() + map_known_len(slice.iter(), |obj| func(obj.clone())) } - pub fn map_iterable_object(&self, obj: &PyObject, mut f: F) -> PyResult>> + /// [`Self::map_iterable_object`] for a caller that asks the object it was + /// handed how long it is. + pub fn map_iterable_object_sized( + &self, + obj: &PyObject, + f: F, + ) -> PyResult>> + where + F: FnMut(PyObjectRef) -> PyResult, + { + self.map_iterable_object_inner(obj, LengthHint::Iterable(&|| 0), f) + } + + pub fn map_iterable_object(&self, obj: &PyObject, f: F) -> PyResult>> + where + F: FnMut(PyObjectRef) -> PyResult, + { + self.map_iterable_object_inner(obj, LengthHint::Unasked, f) + } + + fn map_iterable_object_inner( + &self, + obj: &PyObject, + hint: LengthHint<'_>, + mut f: F, + ) -> PyResult>> where F: FnMut(PyObjectRef) -> PyResult, { @@ -2719,33 +2796,55 @@ impl VirtualMachine { ref t @ PyTuple => Ok(t.iter().cloned().map(f).collect()), // TODO: put internal iterable type obj => { - Ok(self.map_py_iter(obj, f)) + Ok(self.map_py_iter(obj, hint, f)) } }) } - fn map_py_iter(&self, value: &PyObject, mut f: F) -> PyResult> + fn map_py_iter( + &self, + value: &PyObject, + hint: LengthHint<'_>, + mut f: F, + ) -> PyResult> where F: FnMut(PyObjectRef) -> PyResult, { let iter = value.to_owned().get_iter(self)?; - let cap = match self.length_hint_opt(value.to_owned()) { - Err(e) if e.class().is(self.ctx.exceptions.runtime_error) => return Err(e), - Ok(Some(value)) => Some(value), - // Use a power of 2 as a default capacity. - _ => None, - }; - // TODO: fix extend to do this check (?), see test_extend in Lib/test/list_tests.py, - // https://github.com/python/cpython/blob/v3.9.0/Objects/listobject.c#L922-L928 - if let Some(cap) = cap - && cap >= isize::MAX as usize - { - return Ok(Vec::new()); - } - let mut results = PyIterIter::new(self, iter.as_ref(), cap) - .map(|element| f(element?)) - .collect::>>()?; + // Take the room the iterable asks for up front, for the callers that + // do. Collecting into a `Result` drops the iterator's lower bound -- + // the adapter may stop early -- so without this the vector grows a step + // at a time and an iterable claiming more elements than can be held is + // found out by running out of memory rather than by saying so. An error + // the ask answers with is the iterable's own and belongs to the caller + // that made it; `length_hint_opt` already answers `None` for the + // iterable that declines to guess. + // + // Nobody else asks, so what an object would have answered -- slowly, or + // by raising -- costs the rest nothing. + // + // A hint that does not leave room for what is already held is one the + // iterable cannot be telling the truth about, so it is passed over + // rather than refused: if it was honest the loop runs out of memory on + // its own, and if it lied there was nothing wrong to report. What is + // held is counted now rather than before, since asking for the hint + // runs code that can add to it or take from it. + let mut results: Vec = Vec::new(); + let mut cap = None; + if let LengthHint::Iterable(held) = hint { + cap = self.length_hint_opt(value.to_owned())?; + if let Some(cap) = cap + && held() <= (isize::MAX as usize) - cap + { + results + .try_reserve_exact(cap) + .map_err(|_| self.new_memory_error(""))?; + } + } + for element in PyIterIter::new(self, iter.as_ref(), cap) { + results.push(f(element?)?); + } results.shrink_to_fit(); Ok(results) } @@ -2756,8 +2855,14 @@ impl VirtualMachine { attr_name: impl AsPyStr<'a>, ) -> PyResult> { let attr_name = attr_name.as_pystr(&self.ctx); - match obj.get_attr_inner(attr_name, self) { - Ok(attr) => Ok(Some(attr)), + let getattro = obj.class().slots.getattro.load().unwrap(); + let result = if fn_addr(getattro) == fn_addr(PyBaseObject::getattro as GetattroFunc) { + obj.generic_getattr_opt(attr_name, None, self) + } else { + obj.get_attr_inner(attr_name, self).map(Some) + }; + match result { + Ok(attr) => Ok(attr), Err(e) if e.fast_isinstance(self.ctx.exceptions.attribute_error) => Ok(None), Err(e) => Err(e), } diff --git a/crates/vm/src/vm/thread.rs b/crates/vm/src/vm/thread.rs index 3f83d88fe70..4ba0d7ffada 100644 --- a/crates/vm/src/vm/thread.rs +++ b/crates/vm/src/vm/thread.rs @@ -53,7 +53,8 @@ pub struct ThreadSlot { pub top_iframe: AtomicUsize, /// Raw frame pointers, valid while the owning thread's call stack is active. /// Readers must hold the Mutex and convert to FrameObjectRef inside the lock. - /// Used on non-unix threading builds, which have no stop-the-world. + /// Stands in for `top_frame` where that field is not built, so a reader + /// that finds no `top_iframe` still has the frames to answer from. #[cfg(not(unix))] pub frames: parking_lot::Mutex>, pub exception: crate::PyAtomicRef>, diff --git a/crates/vm/src/vm/vm_new.rs b/crates/vm/src/vm/vm_new.rs index 82f382ca6d7..0783f91b199 100644 --- a/crates/vm/src/vm/vm_new.rs +++ b/crates/vm/src/vm/vm_new.rs @@ -99,7 +99,7 @@ impl SyntaxErrorInfo { format!("invalid syntax: {}", self.msg.replace('`', "'")) } - ParseErrorType::UnexpectedExpressionToken => format!("invalid syntax: {}", self.msg), + ParseErrorType::UnexpectedExpressionToken => "invalid syntax".into(), ParseErrorType::ExpectedToken { expected, found } => { Self::handle_expected_token(*expected, *found).into() @@ -166,6 +166,10 @@ impl SyntaxErrorInfo { "arguments cannot follow var-keyword argument".into() } + ParseErrorType::InvalidAnnotatedAssignmentTarget => { + "illegal target for annotation".into() + } + ParseErrorType::Lexical(LexicalErrorType::UnrecognizedToken { .. }) | ParseErrorType::SimpleStatementsOnSameLine | ParseErrorType::SimpleAndCompoundStatementOnSameLine @@ -175,18 +179,35 @@ impl SyntaxErrorInfo { "invalid syntax".into() } + // What the parser says when it cannot continue the list it is + // recovering; each of these situations is a plain "invalid syntax". ParseErrorType::OtherError(s) - if s.eq_ignore_ascii_case( - "Expected a type parameter or the end of the type parameter list", + if matches!( + s.as_str(), + "Expected a statement" + | "Expected an `elif` or `else` clause, or the end of the `if` statement." + | "Expected an `except` or `finally` clause or the end of the `try` statement." + | "The keyword is not allowed as a variable declaration name" + | "Expected an assignment target" + | "Expected a type parameter or the end of the type parameter list" + | "Expected an import name or a ')'" + | "Expected an import name" + | "Expected an expression or the end of the slice list" + | "Expected an expression or a ']'" + | "Expected an expression or a '}'" + | "Expected an expression or a ')'" + | "Expected an expression" + | "Expected a pattern or the end of the sequence pattern" + | "Expected a mapping pattern or the end of the mapping pattern" + | "Expected a pattern or a ')'" + | "Expected a delete target" + | "Expected a parameter or the end of the parameter list" + | "Expected an expression or the end of the with item list" ) => { "invalid syntax".into() } - ParseErrorType::OtherError(s) if s.eq_ignore_ascii_case("Expected a statement") => { - "invalid syntax".into() - } - ParseErrorType::OtherError(s) if s.eq_ignore_ascii_case( "bytes literal cannot be mixed with non-bytes literals", @@ -837,6 +858,18 @@ impl VirtualMachine { || msg.starts_with("except expressions without parentheses are") || msg.starts_with("Pattern matching is"); let line_end_binary_operator_error = msg.starts_with("The '@' operator is"); + let unclosed_bracket_error = cfg_select! { + feature = "parser" => { + matches!( + error, + crate::compiler::CompileError::Parse(rustpython_compiler::ParseError { + is_unclosed_bracket: true, + .. + }) + ) + } + _ => false, + }; let syntax_error = self.new_exception_msg(syntax_error_type, msg.into()); @@ -860,6 +893,10 @@ impl VirtualMachine { .is_some_and(|ch| ch.is_ascii_whitespace())); let (end_lineno, end_offset) = if no_end_offset { (end_lineno, -1) + } else if unclosed_bracket_error { + // The bracket that was never closed is marked where it opened, + // and the span stops there. + (end_lineno, 0) } else if line_end_binary_operator_error && end_offset == offset_raw { (end_lineno, (end_offset + 1) as isize) } else if narrow_caret { diff --git a/crates/wasm/src/vm_class.rs b/crates/wasm/src/vm_class.rs index 80f3ece1358..6780d4d1bc6 100644 --- a/crates/wasm/src/vm_class.rs +++ b/crates/wasm/src/vm_class.rs @@ -10,6 +10,7 @@ use ruff_text_size::Ranged; use rustpython_vm::{ Interpreter, PyObjectRef, PyRef, PyResult, Settings, VirtualMachine, builtins::PyWeak, + bytecode::CodeFlags, compiler::{self, Mode}, function::ArgMapping, scope::Scope, @@ -24,6 +25,7 @@ pub(crate) struct StoredVirtualMachine { /// you can put a Rc in here, keep it as a Weak, and it'll be held only for /// as long as the StoredVM is alive held_objects: RefCell>, + future_features: RefCell, } fn compile_err_to_js(vm: &VirtualMachine, err: VmCompileError) -> JsValue { @@ -33,8 +35,17 @@ fn compile_err_to_js(vm: &VirtualMachine, err: VmCompileError) -> JsValue { } } -fn statement_chunks(source: &str) -> Option> { - let module = compiler::parser::parse_module(source).ok()?.into_syntax(); +fn statement_chunks(source: &str, future_features: CodeFlags) -> Option> { + let parser_options = compiler::parser::ParseOptions::from(compiler::parser::Mode::Module); + let prepared = compiler::prepare_barry_as_flufl_source( + source, + parser_options.clone(), + future_features.contains(CodeFlags::FUTURE_BARRY_AS_BDFL), + ); + let module = compiler::parser::parse(prepared.source(), parser_options) + .ok()? + .into_syntax() + .expect_module(); module .body .iter() @@ -99,6 +110,7 @@ impl StoredVirtualMachine { interp, scope, held_objects: RefCell::new(Vec::new()), + future_features: RefCell::new(CodeFlags::empty()), } } } @@ -394,11 +406,24 @@ impl WASMVirtualMachine { source: &str, source_path: Option, ) -> Result { - self.with_vm(|vm, StoredVirtualMachine { scope, .. }| { + self.with_vm(|vm, stored| { + let scope = &stored.scope; let source_path = source_path.unwrap_or_else(|| "".to_owned()); - let Some(chunks) = statement_chunks(source) else { - let code = vm.compile(source, Mode::Single, source_path.as_str()); - let code = code.map_err(|err| compile_err_to_js(vm, err))?; + let compile = |source: &str, mode: Mode| -> Result<_, JsValue> { + let future_features = *stored.future_features.borrow(); + let opts = compiler::CompileOpts { + future_features, + ..vm.compile_opts() + }; + let code = vm + .compile_with_opts(source, mode, source_path.as_str(), opts) + .map_err(|err| compile_err_to_js(vm, err))?; + *stored.future_features.borrow_mut() |= code.code.flags & CodeFlags::FUTURE_MASK; + Ok(code) + }; + let future_features = *stored.future_features.borrow(); + let Some(chunks) = statement_chunks(source, future_features) else { + let code = compile(source, Mode::Single)?; let result = vm.run_code_obj(code, scope.clone()); return convert::pyresult_to_js_result(vm, result); }; @@ -413,8 +438,7 @@ impl WASMVirtualMachine { .map_err(|_| TypeError::new("lost sys.displayhook"))?; let mut result = vm.ctx.none(); for chunk in chunks { - let code = vm.compile(chunk, Mode::BlockExpr, source_path.as_str()); - let code = code.map_err(|err| compile_err_to_js(vm, err))?; + let code = compile(chunk, Mode::BlockExpr)?; result = vm.run_code_obj(code, scope.clone()).into_js(vm)?; displayhook.call((result.clone(),), vm).into_js(vm)?; } diff --git a/crates/wtf8/src/lib.rs b/crates/wtf8/src/lib.rs index 2167b6b04c6..7625e6f189a 100644 --- a/crates/wtf8/src/lib.rs +++ b/crates/wtf8/src/lib.rs @@ -1175,14 +1175,47 @@ impl Wtf8 { } pub fn replace(&self, from: &Wtf8, to: &Wtf8) -> Wtf8Buf { + if from.is_empty() { + return self.insert_at_boundaries(to, usize::MAX); + } let w = self.bytes.replace(from, to); unsafe { Wtf8Buf::from_bytes_unchecked(w) } } pub fn replacen(&self, from: &Wtf8, to: &Wtf8, n: usize) -> Wtf8Buf { + if from.is_empty() { + return self.insert_at_boundaries(to, n); + } let w = self.bytes.replacen(from, to, n); unsafe { Wtf8Buf::from_bytes_unchecked(w) } } + + /// Inserts `to` before every code point and once after the last one, + /// stopping after `limit` insertions. + /// + /// This is what an empty needle asks for. It cannot go through the byte + /// search the other cases use: that one matches an empty needle at every + /// *byte*, so it splits a multi-byte code point down the middle and leaves + /// bytes that are no longer WTF-8 at all. A needle that is not empty is + /// safe there, because a WTF-8 sequence never starts inside another one. + fn insert_at_boundaries(&self, to: &Wtf8, limit: usize) -> Wtf8Buf { + let mut result = Wtf8Buf::with_capacity(self.len()); + let mut inserted = 0; + + for code_point in self.code_points() { + if inserted < limit { + result.push_wtf8(to); + inserted += 1; + } + result.push(code_point); + } + + if inserted < limit { + result.push_wtf8(to); + } + + result + } } impl AsRef for str { @@ -1619,3 +1652,59 @@ impl From for Box { mod concat; pub use concat::Wtf8Concat; + +#[cfg(test)] +mod tests { + use super::{String, Wtf8, Wtf8Buf}; + + fn w(s: &str) -> &Wtf8 { + Wtf8::new(s) + } + + fn buf(s: &str) -> Wtf8Buf { + Wtf8Buf::from_string(String::from(s)) + } + + #[test] + fn replace_empty_needle_splits_on_code_points() { + assert_eq!(w("abc").replace(w(""), w("-")), buf("-a-b-c-")); + assert_eq!(w("ábç").replace(w(""), w("#")), buf("#á#b#ç#")); + assert_eq!(w("😀").replace(w(""), w("-")), buf("-😀-")); + assert_eq!(w("").replace(w(""), w("-")), buf("-")); + assert_eq!(w("abc").replace(w(""), w("")), buf("abc")); + } + + #[test] + fn replacen_empty_needle_counts_insertions() { + assert_eq!(w("abc").replacen(w(""), w("-"), 0), buf("abc")); + assert_eq!(w("abc").replacen(w(""), w("-"), 1), buf("-abc")); + assert_eq!(w("abc").replacen(w(""), w("-"), 3), buf("-a-b-c")); + assert_eq!(w("abc").replacen(w(""), w("-"), 4), buf("-a-b-c-")); + assert_eq!(w("abc").replacen(w(""), w("-"), 99), buf("-a-b-c-")); + assert_eq!(w("ábç").replacen(w(""), w("#"), 2), buf("#á#bç")); + } + + #[test] + fn replace_result_stays_valid_wtf8() { + // The byte search behind the non-empty cases matches an empty needle at + // every byte, which used to leave a replacement inside a multi-byte code + // point. What came out was not WTF-8, and every later read of it was + // reading something else. + for subject in ["abc", "á", "ábç", "😀", "a😀b", ""] { + for insert in ["-", "", "ç", "😀"] { + let replaced = Wtf8::new(subject).replace(w(""), w(insert)); + assert!( + Wtf8::from_bytes(replaced.as_bytes()).is_some(), + "{subject:?} with {insert:?} produced bytes that are not WTF-8" + ); + } + } + } + + #[test] + fn replace_non_empty_needle_is_unchanged() { + assert_eq!(w("ábç").replace(w("b"), w("#")), buf("á#ç")); + assert_eq!(w("ábç").replace(w("á"), w("#")), buf("#bç")); + assert_eq!(w("aaa").replacen(w("a"), w("b"), 2), buf("bba")); + } +} diff --git a/extra_tests/snippets/builtin_bytes.py b/extra_tests/snippets/builtin_bytes.py index 3cbed79c069..0c45fc3571e 100644 --- a/extra_tests/snippets/builtin_bytes.py +++ b/extra_tests/snippets/builtin_bytes.py @@ -766,3 +766,50 @@ def test_huge_size(): test_huge_size() + + +# bytes() asks the object it was handed how long it is, so what answering +# raises is the answer; the bytearray constructor asks nothing. +class BadLen: + def __iter__(self): + return iter([1, 2, 3]) + + def __len__(self): + raise RuntimeError("hello") + + +with assert_raises(RuntimeError): + bytes(BadLen()) +with assert_raises(RuntimeError): + int.from_bytes(BadLen(), "big") +assert bytearray(BadLen()) == bytearray(b"\x01\x02\x03") +with assert_raises(RuntimeError): + bytearray(b"ab").extend(BadLen()) +holder = bytearray(b"xyz") +holder[:] = BadLen() +assert holder == bytearray(b"\x01\x02\x03") + + +# What could not be turned into bytes is answered for by whatever was asked, +# rather than by the iteration protocol. +def cannot(fn, message): + try: + fn() + except TypeError as e: + assert str(e) == message, e + else: + raise AssertionError(f"expected TypeError: {message}") + + +cannot(lambda: bytes(object()), "cannot convert 'object' object to bytes") +cannot(lambda: bytes(1.5), "cannot convert 'float' object to bytes") +cannot(lambda: bytearray(object()), "cannot convert 'object' object to bytearray") +cannot( + lambda: bytearray(b"ab").__setitem__(slice(0, 2), object()), + "cannot convert 'object' object to bytearray", +) +cannot(lambda: bytearray().extend(object()), "can't extend bytearray with object") +cannot( + lambda: bytearray(b"ab").__setitem__(slice(0, 2), "ab"), + "can assign only bytes, buffers, or iterables of ints in range(0, 256)", +) diff --git a/extra_tests/snippets/builtin_compile.py b/extra_tests/snippets/builtin_compile.py index 73247e50df1..ff11bbda2d8 100644 --- a/extra_tests/snippets/builtin_compile.py +++ b/extra_tests/snippets/builtin_compile.py @@ -1,7 +1,6 @@ import __future__ import ast -import sys from testutils import assert_raises @@ -66,8 +65,7 @@ def _check_flags_error(flags): barry_flag = __future__.barry_as_FLUFL.compiler_flag barry_code = compile("x = 1", "", "exec", flags=barry_flag) compile("from __future__ import barry_as_FLUFL\nx = 1\n", "", "exec") -if sys.implementation.name == "rustpython": - assert not (barry_code.co_flags & barry_flag) +assert barry_code.co_flags & barry_flag n = ast.parse('x = "# type: int"\n', type_comments=True) assert n.body[0].type_comment is None diff --git a/extra_tests/snippets/builtin_format.py b/extra_tests/snippets/builtin_format.py index c2e2a897470..6b7403da133 100644 --- a/extra_tests/snippets/builtin_format.py +++ b/extra_tests/snippets/builtin_format.py @@ -32,6 +32,40 @@ def test_zero_padding(): else: raise AssertionError("expected ValueError for '=8s' string format specifier") +# regression: a sign, a space or an alternate form used to be accepted and dropped. +for spec, flag in [ + ("+", "Sign"), + ("-", "Sign"), + ("+5", "Sign"), + (" ", "Space"), + (" 5", "Space"), + ("#", "Alternate form (#)"), + ("#5", "Alternate form (#)"), + ("+.2", "Sign"), +]: + try: + format("result", spec) + except ValueError as error: + expected = f"{flag} not allowed in string format specifier" + if str(error) != expected: + raise AssertionError( + f"{spec!r}: unexpected error message: {error}" + ) from error + else: + raise AssertionError( + f"expected ValueError for {spec!r} string format specifier" + ) + +# regression: unknown conversion specifiers used to be silently ignored instead of raising. +# The ValueError case itself is covered by test_str, but here we're testing the error message. +try: + "{0!x}".format(3) +except ValueError as error: + if str(error) != "Unknown conversion specifier x": + raise AssertionError(f"unexpected error message: {error}") from error +else: + raise AssertionError("expected ValueError for unknown conversion specifier '!x'") + assert "{:,}".format(100) == "100" assert "{:,}".format(1024) == "1,024" assert "{:_}".format(65536) == "65_536" @@ -259,3 +293,37 @@ def test_zero_padding(): assert "{:.3g}".format(1234.5) == "1.23e+03" assert f"{float('nan'):.10f}" == "nan" assert f"{float('inf'):.10f}" == "inf" + +# bool has no __format__ of its own, so the int rules apply. Only the bare +# spec spells the value out. +assert format(True, "") == "True" +assert format(False, "") == "False" +assert f"{True}" == "True" +assert f"{True:}" == "True" + +assert format(True, "5") == " 1" +assert format(True, "<5") == "1 " +assert format(False, ">5") == " 0" +assert format(True, "^5") == " 1 " +assert format(True, "=5") == " 1" +assert format(True, "05") == "00001" +assert format(False, "05") == "00000" +assert format(True, "+") == "+1" +assert format(False, " ") == " 0" +assert format(True, ",") == "1" +assert format(True, "<") == "1" +assert "{:>6}|{:^6}".format(True, False) == " 1| 0 " + +# The presentation types were already right, and stay right. +assert format(True, "d") == "1" +assert format(True, "#b") == "0b1" +assert format(False, "x") == "0" +assert format(True, "c") == "\x01" +assert format(True, "e") == "1.000000e+00" +assert format(True, "%") == "100.000000%" + +# Precision belongs to no integer spec, bool included. +assert_raises(ValueError, format, True, ".2") +assert_raises(ValueError, format, True, "5.2") +assert_raises(ValueError, format, True, "z") +assert_raises(ValueError, format, True, "s") diff --git a/extra_tests/snippets/builtin_int.py b/extra_tests/snippets/builtin_int.py index 2828b5ad26d..c111d253254 100644 --- a/extra_tests/snippets/builtin_int.py +++ b/extra_tests/snippets/builtin_int.py @@ -401,3 +401,9 @@ class SubInt(int): assert str(huge) finally: sys.set_int_max_str_digits(_orig_limit) + +# to_bytes is handed the length to allocate, so one that cannot be satisfied +# must raise. Zero and non-zero take different paths to the same buffer. +for value in (0, 1, -1): + with assert_raises(MemoryError): + value.to_bytes(2**60, "big", signed=True) diff --git a/extra_tests/snippets/builtin_iter.py b/extra_tests/snippets/builtin_iter.py index 02d469a47ee..09fb94eeea2 100644 --- a/extra_tests/snippets/builtin_iter.py +++ b/extra_tests/snippets/builtin_iter.py @@ -69,3 +69,147 @@ def __len__(self): assert seq_it.__length_hint__() == 3 next(seq_it) assert seq_it.__length_hint__() == 2 + + +# Walking an iterator takes no room up front, so nothing on the way asks it how +# long it is. Only join does, reaching its elements through PySequence_Fast(), +# which fills a list from the iterator. +import array +import collections +import io +import math + + +class LoudIterator: + def __init__(self, seq): + self.i = iter(seq) + + def __iter__(self): + return self + + def __next__(self): + return next(self.i) + + def __length_hint__(self): + raise NotImplementedError("iterator hint") + + +def handing(seq=(1, 2, 3)): + class Handing: + def __iter__(self): + return LoudIterator(seq) + + return Handing() + + +assert set(handing()) == {1, 2, 3} +assert frozenset(handing()) == frozenset({1, 2, 3}) +assert {1}.difference(handing()) == set() +assert {1}.intersection(handing()) == {1} +assert {1}.symmetric_difference(handing()) == {2, 3} +assert {1}.issubset(handing()) +assert not {9}.issuperset(handing()) +assert dict.fromkeys(handing()) == {1: None, 2: None, 3: None} +assert array.array("b", handing()) == array.array("b", [1, 2, 3]) +assert all(handing()) and any(handing()) +assert sum(handing()) == 6 +assert math.fsum(handing()) == 6.0 +assert math.prod(handing()) == 6 +assert collections.deque(handing()) == collections.deque([1, 2, 3]) +assert tuple(handing()) == (1, 2, 3) +assert list(handing()) == [1, 2, 3] +assert min(handing()) == 1 +assert bytes(handing()) == b"\x01\x02\x03" +assert bytearray(handing()) == bytearray(b"\x01\x02\x03") +io.StringIO().writelines(handing(("a", "b"))) + +# join asks, and answers with what asking raised. +for empty in ("", b""): + try: + empty.join(handing((empty.__class__(),))) + except NotImplementedError: + pass + else: + raise AssertionError(f"{empty.__class__.__name__}.join did not ask") + + +# An error from an element is the element's, not the end of the walk, so the +# next step reaches for the same one again. +class Balky: + def __getitem__(self, i): + if i == 1: + raise ValueError("boom") + if i > 2: + raise IndexError + return i + + +it = iter(Balky()) +assert next(it) == 0 +for _ in range(2): + try: + next(it) + except ValueError as e: + assert str(e) == "boom", e + else: + raise AssertionError("the element's error did not reach the caller") + + +# A collection that moved under its iterator raises every time it is asked +# again, rather than reading as spent after the first. What is left to walk +# reads as nothing from the moment the collection no longer matches. +from collections import deque +from operator import length_hint + + +def moved(make, mutate, restore, moved_hint, again): + it = make() + next(it) + assert length_hint(it) == 9, length_hint(it) + mutate() + assert length_hint(it) == moved_hint, length_hint(it) + try: + next(it) + except RuntimeError: + pass + else: + raise AssertionError("a collection that moved was walked further") + assert length_hint(it) == 0, length_hint(it) + restore() + try: + next(it) + except RuntimeError: + got = RuntimeError + except StopIteration: + got = StopIteration + else: + raise AssertionError("a collection that moved was walked further") + assert got is again, got + assert length_hint(it) == 0, length_hint(it) + + +# A deque iterator carries its own count, so what the deque does to its own +# length before the iterator is asked again is not what the count answers. +d = deque(range(10)) +moved(lambda: iter(d), d.pop, lambda: d.append(99), 9, RuntimeError) +d2 = deque(range(10)) +# `dequereviter_next()` looks at the count before the deque, so once the count +# is spent the deque is never looked at again. +moved(lambda: reversed(d2), d2.pop, lambda: d2.append(99), 9, StopIteration) + +# A dict or set iterator answers from the size it captured, which the +# collection stops matching the moment it changes. +s = set(range(10)) +moved(lambda: iter(s), lambda: s.add(99), lambda: s.discard(99), 0, RuntimeError) +dd = {i: i for i in range(10)} +moved( + lambda: iter(dd), lambda: dd.update({99: 99}), lambda: dd.pop(99), 0, RuntimeError +) +dv = {i: i for i in range(10)} +moved( + lambda: reversed(dv.items()), + lambda: dv.update({99: 99}), + lambda: dv.pop(99), + 0, + RuntimeError, +) diff --git a/extra_tests/snippets/builtin_list.py b/extra_tests/snippets/builtin_list.py index 44492092bad..d2fb75b3576 100644 --- a/extra_tests/snippets/builtin_list.py +++ b/extra_tests/snippets/builtin_list.py @@ -930,3 +930,124 @@ def __eq__(self, other): # that product must raise instead of wrapping into a short allocation. with assert_raises(MemoryError): [1] * sys.maxsize + + +# A list takes the length an iterable reports before reading it, so one that +# reports more than can be held says so instead of filling memory. +class Reports: + def __init__(self, hint): + self.hint = hint + + def __iter__(self): + return iter([1, 2, 3]) + + def __length_hint__(self): + return self.hint + + +with assert_raises(MemoryError): + list(Reports(sys.maxsize)) +with assert_raises(MemoryError): + [].extend(Reports(sys.maxsize)) +with assert_raises(MemoryError): + empty = [] + empty += Reports(sys.maxsize) + +# A report that leaves no room for what the list already holds cannot be true, +# so it is passed over rather than refused. +held = [1, 2, 3, 4] +held.extend(Reports(sys.maxsize)) +assert held == [1, 2, 3, 4, 1, 2, 3] + + +# Reporting runs the iterable's own code, so what the list holds is counted +# after the report rather than before it. +grew = [] + + +class Grows: + def __iter__(self): + return iter([7]) + + def __length_hint__(self): + grew.extend([0] * 100) + return sys.maxsize - 50 + + +grew.extend(Grows()) +assert len(grew) == 101 and grew[-1] == 7, grew[-3:] + +shrunk = [1] * 100 + + +class Shrinks: + def __iter__(self): + return iter([]) + + def __length_hint__(self): + shrunk.clear() + return sys.maxsize + + +with assert_raises(MemoryError): + shrunk.extend(Shrinks()) + + +# Only the callers that take the room ask at all, which is why an iterable whose +# __len__ raises reaches tuple() but not list(). +class Lazy: + def __len__(self): + raise NotImplementedError + + def __iter__(self): + return iter([1, 2, 3]) + + +assert tuple(Lazy()) == (1, 2, 3) +assert (lambda *a: a)(*Lazy()) == (1, 2, 3) +assert min(Lazy()) == 1 +with assert_raises(NotImplementedError): + list(Lazy()) +with assert_raises(NotImplementedError): + sorted(Lazy()) +with assert_raises(NotImplementedError): + [].extend(Lazy()) +with assert_raises(NotImplementedError): + [*Lazy()] + + +# Nothing asks the iterator, so what it would have answered never runs. +class LoudIterator: + def __init__(self): + self.i = iter([1, 2, 3]) + + def __iter__(self): + return self + + def __next__(self): + return next(self.i) + + def __length_hint__(self): + raise NotImplementedError + + +class HandsOutLoud: + def __iter__(self): + return LoudIterator() + + +assert tuple(HandsOutLoud()) == (1, 2, 3) +assert (lambda *a: a)(*HandsOutLoud()) == (1, 2, 3) +assert min(HandsOutLoud()) == 1 +assert max(HandsOutLoud()) == 3 +assert list(HandsOutLoud()) == [1, 2, 3] +assert sorted(HandsOutLoud()) == [1, 2, 3] +assert bytearray(HandsOutLoud()) == bytearray(b"\x01\x02\x03") +held = [0] +held.extend(HandsOutLoud()) +assert held == [0, 1, 2, 3] + + +# A report the list can act on is acted on. +assert list(Reports(3)) == [1, 2, 3] +assert list(Reports(0)) == [1, 2, 3] diff --git a/extra_tests/snippets/builtin_map.py b/extra_tests/snippets/builtin_map.py index 559d108e38b..042a4947ff3 100644 --- a/extra_tests/snippets/builtin_map.py +++ b/extra_tests/snippets/builtin_map.py @@ -32,3 +32,16 @@ def mapping(x): assert list(map(mapping, [1, 2, 0, 4, 5])) == [1, 2] + + +# map does not report a length hint, so a chain of them is not walked to +# answer for one. +import operator + +assert not hasattr(map(lambda x: x, [1, 2, 3]), "__length_hint__") +assert operator.length_hint(map(lambda x: x, [1, 2, 3])) == 0 + +it = iter([1, 2, 3]) +for _ in range(10000): + it = map(lambda x: x, it) +assert operator.length_hint(it) == 0 diff --git a/extra_tests/snippets/builtin_memoryview.py b/extra_tests/snippets/builtin_memoryview.py index 979f584a2b1..ef28ffc3d79 100644 --- a/extra_tests/snippets/builtin_memoryview.py +++ b/extra_tests/snippets/builtin_memoryview.py @@ -850,3 +850,114 @@ def test_cast_bounds_the_dimensions(): test_cast_bounds_the_dimensions() + + +def test_setitem_error_kinds(): + import array + + # A value the format has no room for and a value of the wrong kind are + # different errors, the way they are for any other conversion. + for fmt, over, under in ( + ("B", 300, -1), + ("b", 128, -129), + ("i", 2**31, -(2**31) - 1), + ): + view = memoryview(array.array(fmt, [0, 0])) + for value in (over, under): + try: + view[0] = value + except ValueError as e: + assert str(e) == f"memoryview: invalid value for format '{fmt}'", e + else: + raise AssertionError(f"expected ValueError for {fmt!r} {value}") + for value in ("x", 1.5, None, [1]): + try: + view[0] = value + except TypeError as e: + assert str(e) == f"memoryview: invalid type for format '{fmt}'", e + else: + raise AssertionError(f"expected TypeError for {fmt!r} {value!r}") + + # A bytes item is a value error when it is the wrong length. + chars = memoryview(bytearray(b"ab")).cast("c") + for value in (b"", b"xy"): + try: + chars[0] = value + except ValueError as e: + assert str(e) == "memoryview: invalid value for format 'c'", e + else: + raise AssertionError(f"expected ValueError for {value!r}") + + +def test_setitem_propagates_index_errors(): + # An error raised by the value's own code is the answer, not a report that + # the value was the wrong kind. + class Boom: + def __index__(self): + raise ZeroDivisionError("boom") + + class NotAnInt: + def __index__(self): + return "not an int" + + view = memoryview(bytearray(b"ab")) + try: + view[0] = Boom() + except ZeroDivisionError as e: + assert str(e) == "boom", e + else: + raise AssertionError("expected ZeroDivisionError") + + try: + view[0] = NotAnInt() + except TypeError as e: + assert str(e) == "memoryview: invalid type for format 'B'", e + else: + raise AssertionError("expected TypeError") + + +def test_delete_answers_readonly_first(): + # Nothing can be deleted from a memoryview, but what cannot be written + # says so first. + try: + del memoryview(b"ab")[0] + except TypeError as e: + assert str(e) == "cannot modify read-only memory", e + else: + raise AssertionError("expected TypeError") + + view = memoryview(bytearray(b"abcd")) + for needle in (0, slice(0, 2)): + try: + del view[needle] + except TypeError as e: + assert str(e) == "cannot delete memory", e + else: + raise AssertionError(f"expected TypeError for {needle!r}") + + +test_setitem_error_kinds() +test_setitem_propagates_index_errors() +test_delete_answers_readonly_first() + + +def test_bool_format_keeps_its_own_error(): + # Deciding truth is the value's own code, and what it raises is the answer. + class Raises: + def __init__(self, exc): + self.exc = exc + + def __bool__(self): + raise self.exc + + view = memoryview(bytearray(b"\x00")).cast("?") + for exc in (ZeroDivisionError("boom"), ValueError("nope"), TypeError("nah")): + try: + view[0] = Raises(exc) + except type(exc) as e: + assert str(e) == str(exc), e + else: + raise AssertionError(f"expected {type(exc).__name__}") + + +test_bool_format_keeps_its_own_error() diff --git a/extra_tests/snippets/builtin_optional_attr.py b/extra_tests/snippets/builtin_optional_attr.py new file mode 100644 index 00000000000..3e501b3cd9a --- /dev/null +++ b/extra_tests/snippets/builtin_optional_attr.py @@ -0,0 +1,126 @@ +def assert_raises(exc_type, func, *args): + try: + func(*args) + except exc_type: + return + except BaseException as exc: + raise AssertionError( + f"expected {exc_type.__name__}, got {type(exc).__name__}" + ) from exc + raise AssertionError(f"expected {exc_type.__name__}") + + +class Plain: + class_attr = "class" + + +plain = Plain() +plain.instance_attr = "instance" +sentinel = object() + +assert hasattr(plain, "class_attr") +assert hasattr(plain, "instance_attr") +assert not hasattr(plain, "missing") +assert getattr(plain, "class_attr", sentinel) == "class" +assert getattr(plain, "instance_attr", sentinel) == "instance" +assert getattr(plain, "missing", sentinel) is sentinel +assert_raises(AttributeError, getattr, plain, "missing") +assert_raises(TypeError, hasattr, plain, 1) +assert_raises(TypeError, getattr, plain, 1, sentinel) + + +getattribute_calls = [] + + +class CustomGetattribute: + def __getattribute__(self, name): + getattribute_calls.append(name) + if name == "missing": + raise AttributeError("custom miss") + if name == "bad": + raise ValueError("custom error") + return f"value:{name}" + + +custom_getattribute = CustomGetattribute() +assert not hasattr(custom_getattribute, "missing") +assert getattr(custom_getattribute, "missing", sentinel) is sentinel +assert getattribute_calls == ["missing", "missing"] +assert getattr(custom_getattribute, "present", sentinel) == "value:present" +assert_raises(ValueError, hasattr, custom_getattribute, "bad") + + +getattr_calls = [] + + +class CustomGetattr: + def __getattr__(self, name): + getattr_calls.append(name) + if name == "present": + return "fallback value" + if name == "bad": + raise SystemExit("custom error") + raise AttributeError(name) + + +custom_getattr = CustomGetattr() +assert getattr(custom_getattr, "present", sentinel) == "fallback value" +assert not hasattr(custom_getattr, "missing") +assert getattr_calls == ["present", "missing"] +assert_raises(SystemExit, hasattr, custom_getattr, "bad") + + +class AttributeErrorSubclass(AttributeError): + pass + + +class AttributeErrorDescriptor: + def __get__(self, obj, owner): + raise AttributeError("descriptor miss") + + +class AttributeErrorSubclassDescriptor: + def __get__(self, obj, owner): + raise AttributeErrorSubclass("descriptor miss") + + +class ValueErrorDescriptor: + def __get__(self, obj, owner): + raise ValueError("descriptor error") + + +class DescriptorContainer: + attribute_error = AttributeErrorDescriptor() + attribute_error_subclass = AttributeErrorSubclassDescriptor() + value_error = ValueErrorDescriptor() + + +descriptor_container = DescriptorContainer() +assert not hasattr(descriptor_container, "attribute_error") +assert getattr(descriptor_container, "attribute_error", sentinel) is sentinel +assert not hasattr(descriptor_container, "attribute_error_subclass") +assert getattr(descriptor_container, "attribute_error_subclass", sentinel) is sentinel +assert_raises(ValueError, hasattr, descriptor_container, "value_error") + + +class Dynamic: + pass + + +dynamic = Dynamic() +assert not hasattr(dynamic, "missing") +dynamic_calls = [] + + +def dynamic_getattribute(self, name): + dynamic_calls.append(name) + if name == "missing": + raise AttributeError(name) + return object.__getattribute__(self, name) + + +Dynamic.__getattribute__ = dynamic_getattribute +assert not hasattr(dynamic, "missing") +del Dynamic.__getattribute__ +assert not hasattr(dynamic, "missing") +assert dynamic_calls == ["missing"] diff --git a/extra_tests/snippets/builtin_range.py b/extra_tests/snippets/builtin_range.py index 6bfb99f453d..4f91d4dce83 100644 --- a/extra_tests/snippets/builtin_range.py +++ b/extra_tests/snippets/builtin_range.py @@ -118,6 +118,17 @@ assert range(10, 1, -2).__reduce__()[0] == range assert range(10, 1, -2).__reduce__()[1] == (10, 1, -2) +# range iterator __reduce__ (state is None, range rebased to current position) +it = iter(range(10)) +next(it) +next(it) +next(it) +assert it.__reduce__()[0] is iter +assert it.__reduce__()[1] == (range(3, 10),) +assert it.__reduce__()[2] is None +assert iter(range(3)).__reduce__()[1:] == ((range(0, 3),), None) +assert reversed(range(3)).__reduce__()[1:] == ((range(2, -1, -1),), None) + # range retains the original int refs i = 2**64 assert range(i).stop is i diff --git a/extra_tests/snippets/builtin_str.py b/extra_tests/snippets/builtin_str.py index 684bd66a1ff..ccd2a03527c 100644 --- a/extra_tests/snippets/builtin_str.py +++ b/extra_tests/snippets/builtin_str.py @@ -915,3 +915,67 @@ def test_huge_width(): test_huge_width() + + +def test_replace_empty_pattern(): + # An empty pattern matches at every code point boundary, and only there. + # Matching it byte by byte instead put the replacement inside a multi-byte + # character, so what came back was no longer the text that went in. + assert "abc".replace("", "-") == "-a-b-c-" + assert "ábç".replace("", "#") == "#á#b#ç#" + assert "😀".replace("", "-") == "-😀-" + assert "".replace("", "-") == "-" + assert "abc".replace("", "") == "abc" + + # The count is a number of insertions, and the one after the last + # character only happens if the count reaches that far. + assert "abc".replace("", "-", 0) == "abc" + assert "abc".replace("", "-", 1) == "-abc" + assert "abc".replace("", "-", 3) == "-a-b-c" + assert "abc".replace("", "-", 4) == "-a-b-c-" + assert "abc".replace("", "-", 99) == "-a-b-c-" + assert "ábç".replace("", "#", 2) == "#á#bç" + + # The result has to stay readable as text afterwards. + spread = "á".replace("", "-") + assert len(spread) == 3 + assert list(spread) == ["-", "á", "-"] + assert spread[1] == "á" + assert spread.upper() == "-Á-" + assert spread.encode("utf-8") == b"-\xc3\xa1-" + + # A pattern that is not empty was already fine and stays that way. + assert "ábç".replace("b", "#") == "á#ç" + assert "ábç".replace("á", "#") == "#bç" + assert "aaa".replace("a", "b", 2) == "bba" + + +test_replace_empty_pattern() + + +def test_expandtabs_zero_tabsize(): + # With no width to advance to, the tabs come out and nothing else moves. + # A tab that followed a character used to ask for a run of usize::MAX + # spaces and take the interpreter down with it. + for tabsize in (0, -1, -8): + assert "a\tb".expandtabs(tabsize) == "ab" + assert "ab\tcd\tef".expandtabs(tabsize) == "abcdef" + assert "a\nb\tc".expandtabs(tabsize) == "a\nbc" + assert "a\r\nb\tc".expandtabs(tabsize) == "a\r\nbc" + assert "á\tb".expandtabs(tabsize) == "áb" + assert "😀\tb".expandtabs(tabsize) == "😀b" + assert "\ta".expandtabs(tabsize) == "a" + assert "\t".expandtabs(tabsize) == "" + assert "".expandtabs(tabsize) == "" + assert "no tabs".expandtabs(tabsize) == "no tabs" + assert b"a\tb".expandtabs(tabsize) == b"ab" + assert bytearray(b"a\tb").expandtabs(tabsize) == bytearray(b"ab") + + # A tab size that is actually there keeps working. + assert "a\tb".expandtabs(8) == "a b" + assert "a\tb".expandtabs(1) == "a b" + assert "abcd\te".expandtabs(4) == "abcd e" + assert "a\nb\tc".expandtabs(4) == "a\nb c" + + +test_expandtabs_zero_tabsize() diff --git a/extra_tests/snippets/builtin_str_encode.py b/extra_tests/snippets/builtin_str_encode.py index fc72e6ad4d1..7e7cff57765 100644 --- a/extra_tests/snippets/builtin_str_encode.py +++ b/extra_tests/snippets/builtin_str_encode.py @@ -32,3 +32,12 @@ def round_trip(s, encoding="utf-8"): assert not b"\x80\x80".isupper() assert b"\x80cat\x80".islower() assert b"\x80CAT\x80".isupper() + +# A lone surrogate gets an escape of its own wherever it sits, and a high one +# followed by a low one stays two escapes rather than being folded into one. +assert "\ud800".encode("unicode_escape") == b"\\ud800" +assert "a\ud800".encode("unicode_escape") == b"a\\ud800" +assert "\ud800b".encode("unicode_escape") == b"\\ud800b" +assert "\ud800\ud800".encode("unicode_escape") == b"\\ud800\\ud800" +assert "\ud800\udc00".encode("unicode_escape") == b"\\ud800\\udc00" +assert "\U00010000".encode("unicode_escape") == b"\\U00010000" diff --git a/extra_tests/snippets/builtin_type.py b/extra_tests/snippets/builtin_type.py index 15a330aea19..06b40fe41f6 100644 --- a/extra_tests/snippets/builtin_type.py +++ b/extra_tests/snippets/builtin_type.py @@ -1,4 +1,5 @@ import types +import warnings from testutils import assert_raises @@ -717,3 +718,28 @@ class NoSlots: owner.borrowed = 1 with assert_raises(TypeError): del owner.borrowed + + +# A str subclass names an attribute the same way a str does, and interning the +# key is what makes it reachable at all. +class StrKey(str): + pass + + +subclass_key = type("SubclassKey", (), {StrKey("attr"): 7}) +assert subclass_key.attr == 7 + +# A key that is not a string at all cannot become an attribute. CPython keeps it +# in the class dict and warns once; the class is built either way. +with warnings.catch_warnings(record=True) as caught: + warnings.simplefilter("always") + non_string_key = type("NonStringKey", (), {"kept": 1, 2: 3, 4: 5}) + +assert non_string_key.kept == 1 +assert [w.category for w in caught] == [RuntimeWarning], [w.category for w in caught] +assert "NonStringKey" in str(caught[0].message), str(caught[0].message) + +with warnings.catch_warnings(): + warnings.simplefilter("error") + with assert_raises(RuntimeWarning): + type("NonStringKeyRaises", (), {6: 7}) diff --git a/extra_tests/snippets/stdlib_bisect.py b/extra_tests/snippets/stdlib_bisect.py new file mode 100644 index 00000000000..9aa6863491f --- /dev/null +++ b/extra_tests/snippets/stdlib_bisect.py @@ -0,0 +1,73 @@ +from bisect import bisect_left, bisect_right, insort, insort_left, insort_right + +# A key decides where the item goes, but the item is what gets stored. +for insort_fn in (insort, insort_left, insort_right): + words = ["a", "ccc"] + insort_fn(words, "bb", key=len) + assert words == ["a", "bb", "ccc"], (insort_fn.__name__, words) + + numbers = [1, 3] + insort_fn(numbers, -2, key=abs) + assert numbers == [1, -2, 3], (insort_fn.__name__, numbers) + + pairs = [(1, "a"), (3, "b")] + insort_fn(pairs, (2, "x"), key=lambda pair: pair[0]) + assert pairs == [(1, "a"), (2, "x"), (3, "b")], (insort_fn.__name__, pairs) + + +descending = [3, 1] +insort(descending, 2, key=lambda value: -value) +assert descending == [3, 2, 1], descending + + +class Tagged: + def __init__(self, size, tag): + self.size = size + self.tag = tag + + +def sizes_and_tags(items): + return [(item.size, item.tag) for item in items] + + +by_size = [Tagged(1, "old"), Tagged(2, "old")] + +# On a tie, left goes before the equal element and right goes after it. +left = list(by_size) +insort_left(left, Tagged(2, "new"), key=lambda item: item.size) +assert sizes_and_tags(left) == [(1, "old"), (2, "new"), (2, "old")] + +right = list(by_size) +insort_right(right, Tagged(2, "new"), key=lambda item: item.size) +assert sizes_and_tags(right) == [(1, "old"), (2, "old"), (2, "new")] + + +# The key runs once on the new item, whatever the search does afterwards. +seen = [] + + +def counting_key(value): + seen.append(value) + return value + + +data = [1, 3, 5, 7] +insort(data, 4, key=counting_key) +assert data == [1, 3, 4, 5, 7], data +assert seen.count(4) == 1, seen + + +# lo and hi bound the search and leave the inserted item alone. +bounded = [3, 1] +insort(bounded, 2, 0, 1, key=lambda value: -value) +assert bounded == [3, 2, 1], bounded + + +plain = [1, 3] +insort(plain, 2) +assert plain == [1, 2, 3], plain + +# The search takes the key value itself, so these two stay where they were. +sizes = ["a", "bb", "ccc"] +assert bisect_left(sizes, 2, key=len) == 1 +assert bisect_right(sizes, 2, key=len) == 2 diff --git a/extra_tests/snippets/stdlib_collections_deque.py b/extra_tests/snippets/stdlib_collections_deque.py index d4d3f25bc4f..0c280fd9b02 100644 --- a/extra_tests/snippets/stdlib_collections_deque.py +++ b/extra_tests/snippets/stdlib_collections_deque.py @@ -108,3 +108,46 @@ class D(deque): # until the allocator gives up, so it is left out of this check. with assert_raises(MemoryError): deque([0]) * sys.maxsize + + +# maxlen=0 keeps nothing, whichever end the item arrives at. +d = deque(maxlen=0) +d.append(1) +d.appendleft(2) +assert list(d) == [] +assert len(d) == 0 +assert d.maxlen == 0 + +d = deque(maxlen=0) +d.extend("abc") +d.extendleft("abc") +d += "abc" +assert list(d) == [] + +assert list(deque("abc", maxlen=0)) == [] +assert list(deque("ab", maxlen=0) * 3) == [] +assert list(deque("ab", maxlen=0) + deque("cd")) == [] + +d = deque("abc", maxlen=0) +d.rotate(1) +assert list(d) == [] + +assert_raises(IndexError, deque(maxlen=0).insert, 0, 1) + + +# A bounded deque still drops from the far end, and only once it is full. +d = deque(maxlen=1) +d.append(1) +assert list(d) == [1] +d.append(2) +assert list(d) == [2] +d.appendleft(3) +assert list(d) == [3] + +d = deque("ab", maxlen=3) +d.append("c") +assert list(d) == ["a", "b", "c"] +d.append("d") +assert list(d) == ["b", "c", "d"] +d.appendleft("z") +assert list(d) == ["z", "b", "c"] diff --git a/extra_tests/snippets/stdlib_csv.py b/extra_tests/snippets/stdlib_csv.py index 3401cf64ace..bb5a7af1332 100644 --- a/extra_tests/snippets/stdlib_csv.py +++ b/extra_tests/snippets/stdlib_csv.py @@ -1,7 +1,6 @@ import _csv import csv import io -import sys from testutils import assert_raises @@ -264,42 +263,6 @@ def test_multichar_lineterminator(): test_multichar_lineterminator() -def test_reject_non_ascii_lineterminator(): - # CPython accepts non-ASCII line terminators; RustPython rejects them - # because the writer quotes and escapes byte by byte. Supporting them - # requires code-point-wise handling as part of full Unicode dialect support. - with assert_raises(csv.Error): - csv.writer(io.StringIO(), lineterminator="é") - - with assert_raises(csv.Error): - csv.writer(io.StringIO(), lineterminator="\x85") - - with assert_raises(csv.Error): - csv.writer(io.StringIO(), lineterminator="\ud800") - - with assert_raises(csv.Error): - csv.writer( - io.StringIO(), lineterminator="é", quoting=csv.QUOTE_NONE, escapechar="\\" - ) - - with assert_raises(csv.Error): - csv.register_dialect("non_ascii_lt", lineterminator="é") - - class NonAsciiDialect(csv.excel): - lineterminator = "é" - - with assert_raises(csv.Error): - NonAsciiDialect() - - buf = io.StringIO() - csv.writer(buf, lineterminator="!@#").writerow(["a", "b"]) - assert buf.getvalue() == "a,b!@#" - - -if sys.implementation.name == "rustpython": - test_reject_non_ascii_lineterminator() - - def test_empty_lineterminator(): class EmptyLineTerminator(csv.excel): lineterminator = "" diff --git a/extra_tests/snippets/stdlib_ctypes.py b/extra_tests/snippets/stdlib_ctypes.py index 109665b6a03..827fc598826 100644 --- a/extra_tests/snippets/stdlib_ctypes.py +++ b/extra_tests/snippets/stdlib_ctypes.py @@ -444,8 +444,18 @@ def get_win_folder_via_ctypes(csidl_name: str) -> str: except ValueError: pass else: - assert False, "slice assignment accepted an unbounded iterable" + raise AssertionError("slice assignment accepted an unbounded iterable") array3[0:3] = [7, 8, 9] assert list(array3) == [7, 8, 9] + +# An array type carries the size of its buffer, so one too large to allocate +# must raise instead of aborting. +try: + (ctypes.c_char * (2**60))() +except MemoryError: + pass +else: + raise AssertionError("an unallocatable array was created") + print("done") diff --git a/extra_tests/snippets/stdlib_itertools.py b/extra_tests/snippets/stdlib_itertools.py index 029d0d4229a..ef06ce52985 100644 --- a/extra_tests/snippets/stdlib_itertools.py +++ b/extra_tests/snippets/stdlib_itertools.py @@ -540,3 +540,32 @@ def __iter__(self): itertools.combinations(range(5), 2**44) with assert_raises(MemoryError): itertools.combinations_with_replacement(range(5), 2**44) + +# repeat is an arbitrary Python int: a negative one is refused, and one whose +# pool cannot be allocated must raise rather than take the process down. +with assert_raises(ValueError): + itertools.product([1], repeat=-1) +with assert_raises(OverflowError): + itertools.product([1, 2], repeat=2**60) + + +# The pools are filled by their own count, so a repeat with nothing to repeat +# answers at once instead of counting up to it. +assert list(itertools.product(repeat=2**62)) == [()] +assert list(itertools.product(repeat=0)) == [()] + + +# The count is settled before the arguments are read, so a repeat too large to +# serve does not run their code first. +ran = [] + + +class Watched: + def __iter__(self): + ran.append(True) + return iter([1]) + + +with assert_raises(OverflowError): + itertools.product(Watched(), repeat=2**62) +assert ran == [] diff --git a/extra_tests/snippets/stdlib_re.py b/extra_tests/snippets/stdlib_re.py index 8613ddd30fc..80006aaf3e8 100644 --- a/extra_tests/snippets/stdlib_re.py +++ b/extra_tests/snippets/stdlib_re.py @@ -82,3 +82,47 @@ # Combining characters; issue #7518 assert not re.match(r"\w", "\u0345"), r"\w should not match U+0345 (category Mn)" + + +def test_findall_group_that_did_not_participate(): + # findall returns the matched text, not a match object, so a group that + # took no part in the match stands in as an empty value of the type the + # pattern works on. One group used to come back as None, and a bytes + # pattern used to mix str into its results. + assert re.findall(r"(a)?b", "b ab") == ["", "a"] + assert re.findall(r"(x)?", "a") == ["", ""] + assert re.findall(r"(a|b)?c", "c ac bc") == ["", "a", "b"] + assert re.findall(r"(?Pa)?b", "b ab") == ["", "a"] + assert re.compile(r"(a)?b").findall("b ab") == ["", "a"] + + assert re.findall(rb"(a)?b", b"b ab") == [b"", b"a"] + assert re.findall(rb"(x)?", b"a") == [b"", b""] + + # Two or more groups give a tuple per match, with the same stand-in. + assert re.findall(r"(a)|(b)", "ab") == [("a", ""), ("", "b")] + assert re.findall(rb"(a)|(b)", b"ab") == [(b"a", b""), (b"", b"b")] + assert re.findall(rb"(a)(b)?", b"a ab") == [(b"a", b""), (b"a", b"b")] + + # The type is the pattern's, never the other one. + assert [type(x) for x in re.findall(r"(a)?b", "b ab")] == [str, str] + assert [type(x) for x in re.findall(rb"(a)?b", b"b ab")] == [bytes, bytes] + assert [type(y) for x in re.findall(rb"(a)|(b)", b"ab") for y in x] == [ + bytes, + bytes, + bytes, + bytes, + ] + + # A group that does participate, and no group at all, are unchanged. + assert re.findall(r"(a)", "aa") == ["a", "a"] + assert re.findall(r"a", "aa") == ["a", "a"] + assert re.findall(rb"a", b"aa") == [b"a", b"a"] + + # A match object still reports None, which is where the difference lies. + assert re.match(r"(a)?b", "b").groups() == (None,) + assert re.match(r"(a)?b", "b").group(1) is None + assert [m.groups() for m in re.finditer(r"(a)?b", "b ab")] == [(None,), ("a",)] + assert re.split(r"(a)|(b)", "xaybz") == ["x", "a", None, "y", None, "b", "z"] + + +test_findall_group_that_did_not_participate() diff --git a/extra_tests/snippets/stdlib_signal.py b/extra_tests/snippets/stdlib_signal.py index 9d0b13bbd67..50a025a0604 100644 --- a/extra_tests/snippets/stdlib_signal.py +++ b/extra_tests/snippets/stdlib_signal.py @@ -41,3 +41,39 @@ def handler(signum, frame): time.sleep(2.0) assert signals == [signal.SIGALRM, signal.SIGALRM] + + # A handler may call signal.signal(), and the usual reason is to disarm + # itself. Reading the handler table while the handler runs used to be a + # crash rather than a rearm. + rearmed = [] + + def rearm(signum, frame): + rearmed.append(signum) + signal.signal(signal.SIGALRM, signal.SIG_IGN) + + signal.signal(signal.SIGALRM, rearm) + signal.raise_signal(signal.SIGALRM) + assert rearmed == [signal.SIGALRM], rearmed + assert signal.getsignal(signal.SIGALRM) is signal.SIG_IGN + + # The same goes for arming a different signal from inside a handler. + armed = [] + + def target(signum, frame): + armed.append("target") + + def arm_other(signum, frame): + armed.append("arm_other") + signal.signal(signal.SIGUSR2, target) + + signal.signal(signal.SIGUSR1, arm_other) + signal.raise_signal(signal.SIGUSR1) + assert armed == ["arm_other"], armed + assert signal.getsignal(signal.SIGUSR2) is target + + signal.raise_signal(signal.SIGUSR2) + assert armed == ["arm_other", "target"], armed + + signal.signal(signal.SIGALRM, signal.SIG_DFL) + signal.signal(signal.SIGUSR1, signal.SIG_DFL) + signal.signal(signal.SIGUSR2, signal.SIG_DFL) diff --git a/extra_tests/snippets/stdlib_struct.py b/extra_tests/snippets/stdlib_struct.py index b95b6560d68..21305948269 100644 --- a/extra_tests/snippets/stdlib_struct.py +++ b/extra_tests/snippets/stdlib_struct.py @@ -156,3 +156,9 @@ def __init__(self): ): with assert_raises(RuntimeError): call() + + +# The buffer a format asks for is sized by the format: one too large to +# allocate must raise instead of aborting. +with assert_raises(MemoryError): + struct.pack("%dx" % (2**60)) diff --git a/extra_tests/snippets/syntax_try.py b/extra_tests/snippets/syntax_try.py index 5610cb23e6a..06c62c9073e 100644 --- a/extra_tests/snippets/syntax_try.py +++ b/extra_tests/snippets/syntax_try.py @@ -367,3 +367,104 @@ def gen(): assert generator_return_from_try() == [["z"]] + + +# the copy of the finally body is emitted where the try block is left, so its +# nested scopes must be looked up past the ones the rest of the try block opens +def scopes_after_the_early_exit(): + log = [] + + def run(data, leave_early): + try: + if leave_early: + return "early" + return list(s * 2 for s in data) + finally: + log.append(sorted(k for k in data)) + + assert run([1, 2], True) == "early" + assert run([3, 1], False) == [6, 2] + return log + + +assert scopes_after_the_early_exit() == [[1, 2], [1, 3]] + + +# a nested function in the try block is a scope too: taking its symbol table +# for the generator expression below built one without the `.0` argument +def named_scope_after_the_early_exit(): + log = [] + + def run(data, leave_early): + try: + if leave_early: + return "early" + + def inner(): + return [x + 1 for x in data] + + return inner() + finally: + log.append(sorted(k for k in data)) + + assert run([2, 1], True) == "early" + assert run([2, 1], False) == [3, 2] + return log + + +assert named_scope_after_the_early_exit() == [[1, 2], [1, 2]] + + +# scopes that share a name resolve by position, so `inner` must not be found +# where the try block declares it +def same_name_scope_after_the_early_exit(): + log = [] + + def run(value, leave_early): + try: + if leave_early: + return "early" + + def inner(): + return value + + return inner() + finally: + + def inner(): + return log + + assert inner() is log + log.append((lambda x: x + value)(1)) + + assert run(10, True) == "early" + assert run(20, False) == 20 + return log + + +assert same_name_scope_after_the_early_exit() == [11, 21] + + +# breaking and continuing out of a loop copy the finally body the same way +def loop_exit_with_scopes_after_it(): + seen = [] + for i in range(4): + try: + if i == 1: + continue + if i == 3: + break + seen.append(sorted(t for t in [i])) + finally: + seen.append(sorted(k for k in [i, i + 1])) + return seen + + +assert loop_exit_with_scopes_after_it() == [ + [0], + [0, 1], + [1, 2], + [2], + [2, 3], + [3, 4], +], loop_exit_with_scopes_after_it() diff --git a/src/shell.rs b/src/shell.rs index 7fb9336af4b..d99d38765e0 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -7,6 +7,7 @@ use rustpython_compiler::{ use rustpython_vm::{ AsObject, PyResult, VirtualMachine, builtins::PyBaseExceptionRef, + bytecode::CodeFlags, compiler::{self}, readline::{Readline, ReadlineResult}, scope::Scope, @@ -26,6 +27,7 @@ fn shell_exec( scope: Scope, empty_line_given: bool, continuing_block: bool, + future_features: &mut CodeFlags, ) -> ShellExecResult { // compiling expects only UNIX style line endings, and will replace windows line endings // internally. Since we might need to analyze the source to determine if an error could be @@ -33,8 +35,13 @@ fn shell_exec( // was actually compiled. #[cfg(windows)] let source = &source.replace("\r\n", "\n"); - match vm.compile(source, compiler::Mode::Single, "") { + let opts = compiler::CompileOpts { + future_features: *future_features, + ..vm.compile_opts() + }; + match vm.compile_with_opts(source, compiler::Mode::Single, "", opts) { Ok(code) => { + *future_features |= code.code.flags & CodeFlags::FUTURE_MASK; if empty_line_given || !continuing_block { // We want to execute the full code match vm.run_code_obj(code, scope) { @@ -131,6 +138,7 @@ pub fn run_shell(vm: &VirtualMachine, scope: Scope) -> PyResult<()> { // valid. let mut continuing_block = false; let mut continuing_line = false; + let mut future_features = CodeFlags::empty(); loop { let prompt_name = if continuing_block || continuing_line { @@ -170,6 +178,7 @@ pub fn run_shell(vm: &VirtualMachine, scope: Scope) -> PyResult<()> { scope.clone(), empty_line_given, continuing_block, + &mut future_features, ) { ShellExecResult::Ok => { if continuing_block {